From 73aace89c1cd9bc77f420109ce4f94fed687c5d6 Mon Sep 17 00:00:00 2001 From: trav90 Date: Thu, 26 Apr 2018 16:45:18 -0500 Subject: [ffvpx] Revert Mozilla hack in FFmpeg code This hack was added by Mozilla to work around a potential data race, however the root cause was fixed by upstream in release 3.4 so this hack is no longer needed. --- media/ffvpx/libavcodec/pthread_frame.c | 41 +++++++++++++--------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'media/ffvpx/libavcodec') diff --git a/media/ffvpx/libavcodec/pthread_frame.c b/media/ffvpx/libavcodec/pthread_frame.c index a10fcbfe7..7ef5e9f6b 100644 --- a/media/ffvpx/libavcodec/pthread_frame.c +++ b/media/ffvpx/libavcodec/pthread_frame.c @@ -43,29 +43,9 @@ #include "libavutil/opt.h" #include "libavutil/thread.h" -#if defined(MOZ_TSAN) -typedef _Atomic(int) atomic_int; -#else -typedef volatile int atomic_int; -#endif - /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ -typedef enum { - STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. - STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). - STATE_GET_BUFFER, /**< - * Set when the codec calls get_buffer(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_GET_FORMAT, /**< - * Set when the codec calls get_format(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). -} State; - typedef struct PerThreadContext { struct FrameThreadContext *parent; @@ -86,7 +66,19 @@ typedef struct PerThreadContext { int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. int result; ///< The result of the last codec decode/encode() call. - atomic_int state; + enum { + STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. + STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). + STATE_GET_BUFFER, /**< + * Set when the codec calls get_buffer(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_FORMAT, /**< + * Set when the codec calls get_format(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). + } state; /** * Array of frames passed to ff_thread_release_buffer(). @@ -366,8 +358,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) while (p->state == STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - State p_state = (State)p->state; - switch (p_state) { + switch (p->state) { case STATE_GET_BUFFER: p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); break; @@ -480,7 +471,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, void ff_thread_report_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; + volatile int *progress = f->progress ? (int*)f->progress->data : NULL; if (!progress || progress[field] >= n) return; @@ -498,7 +489,7 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) void ff_thread_await_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; + volatile int *progress = f->progress ? (int*)f->progress->data : NULL; if (!progress || progress[field] >= n) return; -- cgit v1.2.3 From 56a2df6b25bc93ea9a59b8e0bf8029f752f68573 Mon Sep 17 00:00:00 2001 From: trav90 Date: Thu, 26 Apr 2018 16:46:31 -0500 Subject: [ffvpx] Restore AVOptions and dictionary features FFmpeg requires specific default values in AVCodecContext to be set. Instead of manually setting these each time we resync with upstream, let's use FFmpeg's own AVOptions which automatically sets all the values to their default. --- media/ffvpx/libavcodec/bsf.c | 219 ++++++++++++ media/ffvpx/libavcodec/ff_options_table.h | 30 -- media/ffvpx/libavcodec/options.c | 2 +- media/ffvpx/libavcodec/options_table.h | 559 ++++++++++++++++++++++++++++++ 4 files changed, 779 insertions(+), 31 deletions(-) create mode 100644 media/ffvpx/libavcodec/bsf.c delete mode 100644 media/ffvpx/libavcodec/ff_options_table.h create mode 100644 media/ffvpx/libavcodec/options_table.h (limited to 'media/ffvpx/libavcodec') diff --git a/media/ffvpx/libavcodec/bsf.c b/media/ffvpx/libavcodec/bsf.c new file mode 100644 index 000000000..88b7f29fe --- /dev/null +++ b/media/ffvpx/libavcodec/bsf.c @@ -0,0 +1,219 @@ +/* + * 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/log.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" + +#include "avcodec.h" +#include "bsf.h" + +struct AVBSFInternal { + AVPacket *buffer_pkt; + int eof; +}; + +void av_bsf_free(AVBSFContext **pctx) +{ + AVBSFContext *ctx; + + if (!pctx || !*pctx) + return; + ctx = *pctx; + + if (ctx->filter->close) + ctx->filter->close(ctx); + if (ctx->filter->priv_class && ctx->priv_data) + av_opt_free(ctx->priv_data); + + av_opt_free(ctx); + + av_packet_free(&ctx->internal->buffer_pkt); + av_freep(&ctx->internal); + av_freep(&ctx->priv_data); + + avcodec_parameters_free(&ctx->par_in); + avcodec_parameters_free(&ctx->par_out); + + av_freep(pctx); +} + +static void *bsf_child_next(void *obj, void *prev) +{ + AVBSFContext *ctx = obj; + if (!prev && ctx->filter->priv_class) + return ctx->priv_data; + return NULL; +} + +static const AVClass bsf_class = { + .class_name = "AVBSFContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .child_next = bsf_child_next, + .child_class_next = ff_bsf_child_class_next, +}; + +const AVClass *av_bsf_get_class(void) +{ + return &bsf_class; +} + +int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) +{ + AVBSFContext *ctx; + int ret; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return AVERROR(ENOMEM); + + ctx->av_class = &bsf_class; + ctx->filter = filter; + + ctx->par_in = avcodec_parameters_alloc(); + ctx->par_out = avcodec_parameters_alloc(); + if (!ctx->par_in || !ctx->par_out) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ctx->internal->buffer_pkt = av_packet_alloc(); + if (!ctx->internal->buffer_pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } + + av_opt_set_defaults(ctx); + + /* allocate priv data and init private options */ + if (filter->priv_data_size) { + ctx->priv_data = av_mallocz(filter->priv_data_size); + if (!ctx->priv_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + if (filter->priv_class) { + *(const AVClass **)ctx->priv_data = filter->priv_class; + av_opt_set_defaults(ctx->priv_data); + } + } + + *pctx = ctx; + return 0; +fail: + av_bsf_free(&ctx); + return ret; +} + +int av_bsf_init(AVBSFContext *ctx) +{ + int ret, i; + + /* check that the codec is supported */ + if (ctx->filter->codec_ids) { + for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) + if (ctx->par_in->codec_id == ctx->filter->codec_ids[i]) + break; + if (ctx->filter->codec_ids[i] == AV_CODEC_ID_NONE) { + const AVCodecDescriptor *desc = avcodec_descriptor_get(ctx->par_in->codec_id); + av_log(ctx, AV_LOG_ERROR, "Codec '%s' (%d) is not supported by the " + "bitstream filter '%s'. Supported codecs are: ", + desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name); + for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) { + desc = avcodec_descriptor_get(ctx->filter->codec_ids[i]); + av_log(ctx, AV_LOG_ERROR, "%s (%d) ", + desc ? desc->name : "unknown", ctx->filter->codec_ids[i]); + } + av_log(ctx, AV_LOG_ERROR, "\n"); + return AVERROR(EINVAL); + } + } + + /* initialize output parameters to be the same as input + * init below might overwrite that */ + ret = avcodec_parameters_copy(ctx->par_out, ctx->par_in); + if (ret < 0) + return ret; + + ctx->time_base_out = ctx->time_base_in; + + if (ctx->filter->init) { + ret = ctx->filter->init(ctx); + if (ret < 0) + return ret; + } + + return 0; +} + +int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) +{ + if (!pkt || !pkt->data) { + ctx->internal->eof = 1; + return 0; + } + + if (ctx->internal->eof) { + av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n"); + return AVERROR(EINVAL); + } + + if (ctx->internal->buffer_pkt->data || + ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(ctx->internal->buffer_pkt, pkt); + + return 0; +} + +int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt) +{ + return ctx->filter->filter(ctx, pkt); +} + +int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) +{ + AVBSFInternal *in = ctx->internal; + AVPacket *tmp_pkt; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + tmp_pkt = av_packet_alloc(); + if (!tmp_pkt) + return AVERROR(ENOMEM); + + *pkt = ctx->internal->buffer_pkt; + ctx->internal->buffer_pkt = tmp_pkt; + + return 0; +} diff --git a/media/ffvpx/libavcodec/ff_options_table.h b/media/ffvpx/libavcodec/ff_options_table.h deleted file mode 100644 index ee01275d3..000000000 --- a/media/ffvpx/libavcodec/ff_options_table.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2001 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 - */ - -#ifndef AVCODEC_OPTIONS_TABLE_H -#define AVCODEC_OPTIONS_TABLE_H - -#include "libavutil/opt.h" -static const AVOption avcodec_options[] = { -{NULL}, -}; - -#endif /* AVCODEC_OPTIONS_TABLE_H */ diff --git a/media/ffvpx/libavcodec/options.c b/media/ffvpx/libavcodec/options.c index f25df2ab3..d8e3dbfa3 100644 --- a/media/ffvpx/libavcodec/options.c +++ b/media/ffvpx/libavcodec/options.c @@ -34,7 +34,7 @@ #include FF_DISABLE_DEPRECATION_WARNINGS -#include "ff_options_table.h" +#include "options_table.h" FF_ENABLE_DEPRECATION_WARNINGS static const char* context_to_name(void* ptr) { diff --git a/media/ffvpx/libavcodec/options_table.h b/media/ffvpx/libavcodec/options_table.h new file mode 100644 index 000000000..adfbe72bf --- /dev/null +++ b/media/ffvpx/libavcodec/options_table.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2001 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 + */ + +#ifndef AVCODEC_OPTIONS_TABLE_H +#define AVCODEC_OPTIONS_TABLE_H + +#include +#include +#include + +#include "libavutil/opt.h" +#include "avcodec.h" +#include "version.h" + +#define OFFSET(x) offsetof(AVCodecContext,x) +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define S AV_OPT_FLAG_SUBTITLE_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +#define AV_CODEC_DEFAULT_BITRATE 200*1000 + +static const AVOption avcodec_options[] = { +{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E}, +{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E}, +{"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far " + "ratecontrol is willing to deviate from the target average bitrate value. This is not related " + "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", + OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, +{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"}, +{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" }, +{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, +{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, +{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, +{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"}, +#if FF_API_GMC +{"gmc", "use gmc", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"}, +#endif +#if FF_API_MV0 +{"mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"}, +#endif +#if FF_API_INPUT_PRESERVED +{"input_preserved", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"}, +#endif +{"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"}, +{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"}, +{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"}, +#if FF_API_EMU_EDGE +{"emu_edge", "do not draw edges", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"}, +#endif +{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"}, +{"truncated", "Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D, "flags"}, +#if FF_API_NORMALIZE_AQP +{"naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"}, +#endif +{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"}, +{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"}, +{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"}, +{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"}, +{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"}, +{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"}, +{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"}, +{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"}, +{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_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 = AV_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 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"}, +{"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, "flags2"}, +#if FF_API_MOTION_EST +{"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" }, +{"epzs", "EPZS motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"esa", "esa motion estimation (alias for full)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"tesa", "tesa motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"dia", "diamond motion estimation (alias for EPZS)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"log", "log motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"phods", "phods motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" }, +#endif +{"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 }, 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}, +{"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. " + "Recommended range for default rc_eq: 0.0-1.0", + OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E}, +{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E}, +{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E}, +{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E}, +{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E}, +{"bf", "set maximum number of B-frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E}, +{"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, +#if FF_API_RC_STRATEGY +{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_PRIVATE_OPT +{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E}, +{"ps", "RTP payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_STAT_BITS +{"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"p_tex_bits", NULL, OFFSET(p_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"i_count", NULL, OFFSET(i_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"p_count", NULL, OFFSET(p_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"skip_count", NULL, OFFSET(skip_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +#if FF_API_OLD_MSMPEG4 +{"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"}, +#endif +{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"}, +{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"}, +{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"}, +#if FF_API_AC_VLC +{"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"}, +#endif +{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, +{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"}, +{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"}, +{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, +{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"}, +{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"}, +{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"}, +{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, +{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_PRIVATE_OPT +{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#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}, +#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_INT64, {.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_INT64, {.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}, +#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}, +#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", 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"}, +{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"}, +{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_SH4 +{"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_ALPHA +{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +#if FF_API_UNUSED_MEMBERS +{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif /* FF_API_UNUSED_MEMBERS */ +{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, +{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"}, +{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"}, +{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"}, +{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"}, +{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_PRIVATE_OPT +{"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"}, +{"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"}, +{"plane", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"}, +{"median", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"}, +#endif +{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, +{"sar", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, +{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"}, +{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"}, +{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"}, +{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"}, +{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV +{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif +{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"}, +{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"}, +{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"}, +{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_UNUSED_MEMBERS +{"pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PTS }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif /* FF_API_UNUSED_MEMBERS */ +{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"}, +{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"}, +{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"}, +{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +{"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, +{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, +{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"}, +#if FF_API_VISMV +{"vismv", "visualize motion vectors (MVs) (deprecated)", OFFSET(debug_mv), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"}, +{"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"}, +#endif +{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#if CONFIG_SNOW_ENCODER +{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#endif +{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, +#if FF_API_AFD +{"dtg_active_format", NULL, OFFSET(dtg_active_format), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#if FF_API_QUANT_BIAS +{"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E}, +{"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E}, +#endif +{"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_CODER_TYPE +{"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"}, +{"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"}, +{"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"}, +{"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"}, +{"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"}, +#if FF_API_UNUSED_MEMBERS +{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"}, +#endif /* FF_API_UNUSED_MEMBERS */ +#endif /* FF_API_CODER_TYPE */ +#if FF_API_PRIVATE_OPT +{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_XVMC +{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif /* FF_API_XVMC */ +{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"}, +{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"}, +{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"}, +{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"}, +#if FF_API_STREAM_CODEC_TAG +{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +#if FF_API_PRIVATE_OPT +{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#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 +#if FF_API_PRIVATE_OPT +{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"}, +#if FF_API_ERROR_RATE +{"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"}, +{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"}, +#if FF_API_MPV_OPT +{"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E}, +{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, +{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D}, +{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D}, +{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"aac_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ssr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ltp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg4_sp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_asp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D}, +#if FF_API_PRIVATE_OPT +{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"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"}, +#endif +#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}, +#if FF_API_PRIVATE_OPT +{"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}, +#endif +{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"skip_idct" , "skip IDCT/dequantization for the selected frames", OFFSET(skip_idct), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"skip_frame" , "skip decoding for the selected frames", OFFSET(skip_frame), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"none" , "discard no frame", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"default" , "discard useless frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"noref" , "discard all non-reference frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"bidir" , "discard all bidirectional frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"nokey" , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"nointra" , "discard all frames except I frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"all" , "discard all frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E}, +#if FF_API_PRIVATE_OPT +{"brd_scale", "downscale frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E}, +#endif +{"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E}, +{"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"chromaoffset", "chroma QP offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_UNUSED_MEMBERS +{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.i64 = 6 }, 0, INT_MAX, V|E}, +#endif /* FF_API_UNUSED_MEMBERS */ +{"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E}, +#endif +{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_PRIVATE_OPT +{"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 = -1 }, -1, INT64_MAX, V|E}, +#endif +{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"}, +{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"}, +{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E}, +{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E}, +{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D}, +{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D, "color_primaries_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"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"}, +{"smpte428_1", "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_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", "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", "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", "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"}, +{"smpte2084", "SMPTE ST 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte428_1", "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_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", "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"}, +{"ycocg", "YCOCG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCOCG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D, "color_range_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"chroma_sample_location", "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", "set the 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"}, +{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, +{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, +{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, +{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"ef", "Effects", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"vi", "Visually Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"hi", "Hearing Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"di", "Dialogue", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"co", "Commentary", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"}, +{"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, +{"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D}, +{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"}, +{"do_nothing", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +#if FF_API_ASS_TIMING +{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, 0, 1, S|D, "sub_text_format"}, +#else +{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS}, 0, 1, S|D, "sub_text_format"}, +#endif +{"ass", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, +#if FF_API_ASS_TIMING +{"ass_with_timings", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, +#endif +{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D }, +#if FF_API_SIDEDATA_ONLY_PKT +{"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E }, +#endif +{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D }, +{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" }, +{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" }, +{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" }, +{"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}, +}; + +#undef A +#undef V +#undef S +#undef E +#undef D +#undef DEFAULT +#undef OFFSET + +#endif /* AVCODEC_OPTIONS_TABLE_H */ -- cgit v1.2.3 From 8b37a1bc306c1d5a3cc92e9dc04fb95d5d9a0298 Mon Sep 17 00:00:00 2001 From: trav90 Date: Thu, 26 Apr 2018 16:49:15 -0500 Subject: [ffvpx] Update ffvp9/ffvp8 to 3.4.2-release Structure of code was slightly modified so that it should be no longer necessary to re-generate the config_*.h files, greatly simplifying the resync process in the future. --- media/ffvpx/libavcodec/allcodecs.c | 81 +- media/ffvpx/libavcodec/avcodec.h | 322 +- media/ffvpx/libavcodec/avdct.h | 84 - media/ffvpx/libavcodec/avpacket.c | 64 +- media/ffvpx/libavcodec/bitstream.c | 20 +- media/ffvpx/libavcodec/bitstream_filter.c | 185 + media/ffvpx/libavcodec/bitstream_filters.c | 91 + media/ffvpx/libavcodec/blockdsp.h | 3 +- media/ffvpx/libavcodec/bsf.c | 325 +- media/ffvpx/libavcodec/bsf_list.c | 3 + media/ffvpx/libavcodec/bytestream.h | 2 +- media/ffvpx/libavcodec/codec_desc.c | 269 +- media/ffvpx/libavcodec/dct.h | 5 +- media/ffvpx/libavcodec/decode.c | 1761 +++++++++ media/ffvpx/libavcodec/decode.h | 39 + media/ffvpx/libavcodec/dummy_funcs.c | 73 +- media/ffvpx/libavcodec/error_resilience.h | 4 +- media/ffvpx/libavcodec/flac.c | 11 +- media/ffvpx/libavcodec/flac.h | 4 +- media/ffvpx/libavcodec/flac_parser.c | 4 +- media/ffvpx/libavcodec/flacdec.c | 34 +- media/ffvpx/libavcodec/flacdsp.c | 12 +- media/ffvpx/libavcodec/flacdsp.h | 1 + media/ffvpx/libavcodec/flacdsp_template.c | 2 +- media/ffvpx/libavcodec/get_bits.h | 20 + media/ffvpx/libavcodec/golomb.h | 55 +- media/ffvpx/libavcodec/h264chroma.h | 3 +- media/ffvpx/libavcodec/hpeldsp.h | 2 + media/ffvpx/libavcodec/hwaccel.h | 24 + media/ffvpx/libavcodec/idctdsp.h | 20 +- media/ffvpx/libavcodec/internal.h | 70 +- media/ffvpx/libavcodec/mathops.h | 19 +- media/ffvpx/libavcodec/me_cmp.h | 2 +- media/ffvpx/libavcodec/moz.build | 11 + media/ffvpx/libavcodec/mpegvideo.h | 3 +- media/ffvpx/libavcodec/null_bsf.c | 43 + media/ffvpx/libavcodec/options.c | 46 +- media/ffvpx/libavcodec/options_table.h | 77 +- media/ffvpx/libavcodec/parser.c | 7 +- media/ffvpx/libavcodec/pixblockdsp.h | 15 +- media/ffvpx/libavcodec/profiles.c | 12 + media/ffvpx/libavcodec/profiles.h | 1 + media/ffvpx/libavcodec/pthread_frame.c | 317 +- media/ffvpx/libavcodec/pthread_slice.c | 146 +- media/ffvpx/libavcodec/put_bits.h | 109 +- media/ffvpx/libavcodec/ratecontrol.h | 4 - media/ffvpx/libavcodec/raw.c | 14 + media/ffvpx/libavcodec/thread.h | 6 +- media/ffvpx/libavcodec/utils.c | 2326 ++--------- media/ffvpx/libavcodec/version.h | 23 +- media/ffvpx/libavcodec/videodsp.c | 2 + media/ffvpx/libavcodec/videodsp.h | 1 + media/ffvpx/libavcodec/vlc.h | 20 +- media/ffvpx/libavcodec/vorbis_parser.h | 3 - media/ffvpx/libavcodec/vp3dsp.h | 10 +- media/ffvpx/libavcodec/vp56.h | 12 +- media/ffvpx/libavcodec/vp56dsp.h | 18 +- media/ffvpx/libavcodec/vp56rac.c | 5 +- media/ffvpx/libavcodec/vp8.c | 158 +- media/ffvpx/libavcodec/vp8.h | 31 +- media/ffvpx/libavcodec/vp8_parser.c | 49 +- media/ffvpx/libavcodec/vp8dsp.c | 38 +- media/ffvpx/libavcodec/vp8dsp.h | 4 +- media/ffvpx/libavcodec/vp9.c | 4122 ++++---------------- media/ffvpx/libavcodec/vp9.h | 142 +- media/ffvpx/libavcodec/vp9_mc_template.c | 210 +- media/ffvpx/libavcodec/vp9block.c | 1449 +++++++ media/ffvpx/libavcodec/vp9data.c | 2247 +++++++++++ media/ffvpx/libavcodec/vp9data.h | 2292 +---------- media/ffvpx/libavcodec/vp9dec.h | 240 ++ media/ffvpx/libavcodec/vp9dsp.c | 58 + media/ffvpx/libavcodec/vp9dsp.h | 10 +- media/ffvpx/libavcodec/vp9dsp_template.c | 63 +- media/ffvpx/libavcodec/vp9lpf.c | 202 + media/ffvpx/libavcodec/vp9mvs.c | 364 ++ media/ffvpx/libavcodec/vp9prob.c | 274 ++ media/ffvpx/libavcodec/vp9recon.c | 644 +++ media/ffvpx/libavcodec/vp9shared.h | 169 + media/ffvpx/libavcodec/x86/constants.h | 1 + media/ffvpx/libavcodec/x86/flacdsp_init.c | 4 +- media/ffvpx/libavcodec/x86/h264_i386.h | 212 - media/ffvpx/libavcodec/x86/h264_intrapred.asm | 102 +- .../ffvpx/libavcodec/x86/h264_intrapred_10bit.asm | 77 +- media/ffvpx/libavcodec/x86/h264_intrapred_init.c | 7 + media/ffvpx/libavcodec/x86/videodsp.asm | 2 +- media/ffvpx/libavcodec/x86/videodsp_init.c | 8 +- media/ffvpx/libavcodec/x86/vp8dsp.asm | 31 +- media/ffvpx/libavcodec/x86/vp8dsp_init.c | 21 +- media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm | 6 +- media/ffvpx/libavcodec/x86/vp9dsp_init.c | 16 +- media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c | 18 +- .../libavcodec/x86/vp9dsp_init_16bpp_template.c | 8 +- media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm | 257 ++ media/ffvpx/libavcodec/x86/vp9itxfm.asm | 188 +- media/ffvpx/libavcodec/x86/vp9mc.asm | 7 +- 95 files changed, 11542 insertions(+), 9034 deletions(-) delete mode 100644 media/ffvpx/libavcodec/avdct.h create mode 100644 media/ffvpx/libavcodec/bitstream_filter.c create mode 100644 media/ffvpx/libavcodec/bitstream_filters.c create mode 100644 media/ffvpx/libavcodec/bsf_list.c create mode 100644 media/ffvpx/libavcodec/decode.c create mode 100644 media/ffvpx/libavcodec/decode.h create mode 100644 media/ffvpx/libavcodec/hwaccel.h create mode 100644 media/ffvpx/libavcodec/null_bsf.c create mode 100644 media/ffvpx/libavcodec/vp9block.c create mode 100644 media/ffvpx/libavcodec/vp9data.c create mode 100644 media/ffvpx/libavcodec/vp9dec.h create mode 100644 media/ffvpx/libavcodec/vp9lpf.c create mode 100644 media/ffvpx/libavcodec/vp9mvs.c create mode 100644 media/ffvpx/libavcodec/vp9prob.c create mode 100644 media/ffvpx/libavcodec/vp9recon.c create mode 100644 media/ffvpx/libavcodec/vp9shared.h delete mode 100644 media/ffvpx/libavcodec/x86/h264_i386.h (limited to 'media/ffvpx/libavcodec') diff --git a/media/ffvpx/libavcodec/allcodecs.c b/media/ffvpx/libavcodec/allcodecs.c index b592aa3b2..4f34312e6 100644 --- a/media/ffvpx/libavcodec/allcodecs.c +++ b/media/ffvpx/libavcodec/allcodecs.c @@ -25,6 +25,7 @@ */ #include "config.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "version.h" @@ -58,20 +59,14 @@ av_register_codec_parser(&ff_##x##_parser); \ } -void avcodec_register_all(void) +static void register_all(void) { - static int initialized; - - if (initialized) - return; - initialized = 1; - /* hardware accelerators */ - REGISTER_HWACCEL(H263_CUVID, h263_cuvid); REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); REGISTER_HWACCEL(H263_VIDEOTOOLBOX, h263_videotoolbox); REGISTER_HWACCEL(H264_CUVID, h264_cuvid); REGISTER_HWACCEL(H264_D3D11VA, h264_d3d11va); + REGISTER_HWACCEL(H264_D3D11VA2, h264_d3d11va2); REGISTER_HWACCEL(H264_DXVA2, h264_dxva2); REGISTER_HWACCEL(H264_MEDIACODEC, h264_mediacodec); REGISTER_HWACCEL(H264_MMAL, h264_mmal); @@ -83,11 +78,13 @@ void avcodec_register_all(void) REGISTER_HWACCEL(H264_VIDEOTOOLBOX, h264_videotoolbox); REGISTER_HWACCEL(HEVC_CUVID, hevc_cuvid); REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va); + REGISTER_HWACCEL(HEVC_D3D11VA2, hevc_d3d11va2); REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2); REGISTER_HWACCEL(HEVC_MEDIACODEC, hevc_mediacodec); REGISTER_HWACCEL(HEVC_QSV, hevc_qsv); REGISTER_HWACCEL(HEVC_VAAPI, hevc_vaapi); REGISTER_HWACCEL(HEVC_VDPAU, hevc_vdpau); + REGISTER_HWACCEL(HEVC_VIDEOTOOLBOX, hevc_videotoolbox); REGISTER_HWACCEL(MJPEG_CUVID, mjpeg_cuvid); REGISTER_HWACCEL(MPEG1_CUVID, mpeg1_cuvid); REGISTER_HWACCEL(MPEG1_XVMC, mpeg1_xvmc); @@ -96,12 +93,14 @@ void avcodec_register_all(void) REGISTER_HWACCEL(MPEG2_CUVID, mpeg2_cuvid); REGISTER_HWACCEL(MPEG2_XVMC, mpeg2_xvmc); REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va); + REGISTER_HWACCEL(MPEG2_D3D11VA2, mpeg2_d3d11va2); REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL(MPEG2_MMAL, mpeg2_mmal); REGISTER_HWACCEL(MPEG2_QSV, mpeg2_qsv); REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); REGISTER_HWACCEL(MPEG2_VIDEOTOOLBOX, mpeg2_videotoolbox); + REGISTER_HWACCEL(MPEG2_MEDIACODEC, mpeg2_mediacodec); REGISTER_HWACCEL(MPEG4_CUVID, mpeg4_cuvid); REGISTER_HWACCEL(MPEG4_MEDIACODEC, mpeg4_mediacodec); REGISTER_HWACCEL(MPEG4_MMAL, mpeg4_mmal); @@ -110,6 +109,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(MPEG4_VIDEOTOOLBOX, mpeg4_videotoolbox); REGISTER_HWACCEL(VC1_CUVID, vc1_cuvid); REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va); + REGISTER_HWACCEL(VC1_D3D11VA2, vc1_d3d11va2); REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); @@ -117,12 +117,15 @@ void avcodec_register_all(void) REGISTER_HWACCEL(VC1_QSV, vc1_qsv); REGISTER_HWACCEL(VP8_CUVID, vp8_cuvid); REGISTER_HWACCEL(VP8_MEDIACODEC, vp8_mediacodec); + REGISTER_HWACCEL(VP8_QSV, vp8_qsv); REGISTER_HWACCEL(VP9_CUVID, vp9_cuvid); REGISTER_HWACCEL(VP9_D3D11VA, vp9_d3d11va); + REGISTER_HWACCEL(VP9_D3D11VA2, vp9_d3d11va2); REGISTER_HWACCEL(VP9_DXVA2, vp9_dxva2); REGISTER_HWACCEL(VP9_MEDIACODEC, vp9_mediacodec); REGISTER_HWACCEL(VP9_VAAPI, vp9_vaapi); REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va); + REGISTER_HWACCEL(WMV3_D3D11VA2, wmv3_d3d11va2); REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); @@ -158,6 +161,7 @@ void avcodec_register_all(void) REGISTER_DECODER(CDXL, cdxl); REGISTER_DECODER(CFHD, cfhd); REGISTER_ENCDEC (CINEPAK, cinepak); + REGISTER_DECODER(CLEARVIDEO, clearvideo); REGISTER_ENCDEC (CLJR, cljr); REGISTER_DECODER(CLLC, cllc); REGISTER_ENCDEC (COMFORTNOISE, comfortnoise); @@ -189,24 +193,30 @@ void avcodec_register_all(void) REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); REGISTER_DECODER(FIC, fic); + REGISTER_ENCDEC (FITS, fits); REGISTER_ENCDEC (FLASHSV, flashsv); REGISTER_ENCDEC (FLASHSV2, flashsv2); REGISTER_DECODER(FLIC, flic); REGISTER_ENCDEC (FLV, flv); + REGISTER_DECODER(FMVC, fmvc); REGISTER_DECODER(FOURXM, fourxm); REGISTER_DECODER(FRAPS, fraps); REGISTER_DECODER(FRWU, frwu); REGISTER_DECODER(G2M, g2m); + REGISTER_DECODER(GDV, gdv); REGISTER_ENCDEC (GIF, gif); REGISTER_ENCDEC (H261, h261); REGISTER_ENCDEC (H263, h263); REGISTER_DECODER(H263I, h263i); REGISTER_ENCDEC (H263P, h263p); + REGISTER_DECODER(H263_V4L2M2M, h263_v4l2m2m); REGISTER_DECODER(H264, h264); REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); + REGISTER_DECODER(H264_V4L2M2M, h264_v4l2m2m); REGISTER_DECODER(H264_MEDIACODEC, h264_mediacodec); REGISTER_DECODER(H264_MMAL, h264_mmal); REGISTER_DECODER(H264_QSV, h264_qsv); + REGISTER_DECODER(H264_RKMPP, h264_rkmpp); REGISTER_DECODER(H264_VDA, h264_vda); #if FF_API_VDPAU REGISTER_DECODER(H264_VDPAU, h264_vdpau); @@ -214,6 +224,8 @@ void avcodec_register_all(void) REGISTER_ENCDEC (HAP, hap); REGISTER_DECODER(HEVC, hevc); REGISTER_DECODER(HEVC_QSV, hevc_qsv); + REGISTER_DECODER(HEVC_RKMPP, hevc_rkmpp); + REGISTER_DECODER(HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_DECODER(HQ_HQA, hq_hqa); REGISTER_DECODER(HQX, hqx); @@ -248,6 +260,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd); + REGISTER_DECODER(MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(MPEG4_MMAL, mpeg4_mmal); #if FF_API_VDPAU REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau); @@ -257,14 +270,18 @@ void avcodec_register_all(void) REGISTER_DECODER(MPEG_VDPAU, mpeg_vdpau); REGISTER_DECODER(MPEG1_VDPAU, mpeg1_vdpau); #endif + REGISTER_DECODER(MPEG1_V4L2M2M, mpeg1_v4l2m2m); REGISTER_DECODER(MPEG2_MMAL, mpeg2_mmal); REGISTER_DECODER(MPEG2_CRYSTALHD, mpeg2_crystalhd); + REGISTER_DECODER(MPEG2_V4L2M2M, mpeg2_v4l2m2m); REGISTER_DECODER(MPEG2_QSV, mpeg2_qsv); + REGISTER_DECODER(MPEG2_MEDIACODEC, mpeg2_mediacodec); REGISTER_DECODER(MSA1, msa1); - REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); + REGISTER_DECODER(MSCC, mscc); REGISTER_DECODER(MSMPEG4V1, msmpeg4v1); REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); + REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); REGISTER_DECODER(MSRLE, msrle); REGISTER_DECODER(MSS1, mss1); REGISTER_DECODER(MSS2, mss2); @@ -282,12 +299,14 @@ void avcodec_register_all(void) REGISTER_ENCDEC (PGM, pgm); REGISTER_ENCDEC (PGMYUV, pgmyuv); REGISTER_DECODER(PICTOR, pictor); + REGISTER_DECODER(PIXLET, pixlet); REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); REGISTER_ENCDEC (PRORES, prores); REGISTER_ENCODER(PRORES_AW, prores_aw); REGISTER_ENCODER(PRORES_KS, prores_ks); REGISTER_DECODER(PRORES_LGPL, prores_lgpl); + REGISTER_DECODER(PSD, psd); REGISTER_DECODER(PTX, ptx); REGISTER_DECODER(QDRAW, qdraw); REGISTER_DECODER(QPEG, qpeg); @@ -305,6 +324,7 @@ void avcodec_register_all(void) REGISTER_DECODER(RV40, rv40); REGISTER_ENCDEC (S302M, s302m); REGISTER_DECODER(SANM, sanm); + REGISTER_DECODER(SCPR, scpr); REGISTER_DECODER(SCREENPRESSO, screenpresso); REGISTER_DECODER(SDX2_DPCM, sdx2_dpcm); REGISTER_ENCDEC (SGI, sgi); @@ -315,6 +335,8 @@ void avcodec_register_all(void) REGISTER_DECODER(SMVJPEG, smvjpeg); REGISTER_ENCDEC (SNOW, snow); REGISTER_DECODER(SP5X, sp5x); + REGISTER_DECODER(SPEEDHQ, speedhq); + REGISTER_DECODER(SRGC, srgc); REGISTER_ENCDEC (SUNRAST, sunrast); REGISTER_ENCDEC (SVQ1, svq1); REGISTER_DECODER(SVQ3, svq3); @@ -349,6 +371,7 @@ void avcodec_register_all(void) REGISTER_DECODER(VC1IMAGE, vc1image); REGISTER_DECODER(VC1_MMAL, vc1_mmal); REGISTER_DECODER(VC1_QSV, vc1_qsv); + REGISTER_DECODER(VC1_V4L2M2M, vc1_v4l2m2m); REGISTER_ENCODER(VC2, vc2); REGISTER_DECODER(VCR1, vcr1); REGISTER_DECODER(VMDVIDEO, vmdvideo); @@ -360,10 +383,15 @@ void avcodec_register_all(void) REGISTER_DECODER(VP6F, vp6f); REGISTER_DECODER(VP7, vp7); REGISTER_DECODER(VP8, vp8); + REGISTER_DECODER(VP8_RKMPP, vp8_rkmpp); + REGISTER_DECODER(VP8_V4L2M2M, vp8_v4l2m2m); REGISTER_DECODER(VP9, vp9); + REGISTER_DECODER(VP9_RKMPP, vp9_rkmpp); + REGISTER_DECODER(VP9_V4L2M2M, vp9_v4l2m2m); REGISTER_DECODER(VQA, vqa); + REGISTER_DECODER(BITPACKED, bitpacked); REGISTER_DECODER(WEBP, webp); - REGISTER_ENCODER(WRAPPED_AVFRAME, wrapped_avframe); + REGISTER_ENCDEC (WRAPPED_AVFRAME, wrapped_avframe); REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER(WMV3, wmv3); @@ -378,6 +406,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (XBM, xbm); REGISTER_ENCDEC (XFACE, xface); REGISTER_DECODER(XL, xl); + REGISTER_DECODER(XPM, xpm); REGISTER_ENCDEC (XWD, xwd); REGISTER_ENCDEC (Y41P, y41p); REGISTER_DECODER(YLC, ylc); @@ -401,12 +430,15 @@ void avcodec_register_all(void) REGISTER_DECODER(APE, ape); REGISTER_DECODER(ATRAC1, atrac1); REGISTER_DECODER(ATRAC3, atrac3); + REGISTER_DECODER(ATRAC3AL, atrac3al); REGISTER_DECODER(ATRAC3P, atrac3p); + REGISTER_DECODER(ATRAC3PAL, atrac3pal); REGISTER_DECODER(BINKAUDIO_DCT, binkaudio_dct); REGISTER_DECODER(BINKAUDIO_RDFT, binkaudio_rdft); REGISTER_DECODER(BMV_AUDIO, bmv_audio); REGISTER_DECODER(COOK, cook); REGISTER_ENCDEC (DCA, dca); + REGISTER_DECODER(DOLBY_E, dolby_e); REGISTER_DECODER(DSD_LSBF, dsd_lsbf); REGISTER_DECODER(DSD_MSBF, dsd_msbf); REGISTER_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar); @@ -444,10 +476,11 @@ void avcodec_register_all(void) REGISTER_DECODER(MPC8, mpc8); REGISTER_ENCDEC (NELLYMOSER, nellymoser); REGISTER_DECODER(ON2AVC, on2avc); - REGISTER_DECODER(OPUS, opus); + REGISTER_ENCDEC (OPUS, opus); REGISTER_DECODER(PAF_AUDIO, paf_audio); REGISTER_DECODER(QCELP, qcelp); REGISTER_DECODER(QDM2, qdm2); + REGISTER_DECODER(QDMC, qdmc); REGISTER_ENCDEC (RA_144, ra_144); REGISTER_DECODER(RA_288, ra_288); REGISTER_DECODER(RALF, ralf); @@ -477,6 +510,8 @@ void avcodec_register_all(void) REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); REGISTER_DECODER(PCM_BLURAY, pcm_bluray); REGISTER_DECODER(PCM_DVD, pcm_dvd); + REGISTER_DECODER(PCM_F16LE, pcm_f16le); + REGISTER_DECODER(PCM_F24LE, pcm_f24le); REGISTER_ENCDEC (PCM_F32BE, pcm_f32be); REGISTER_ENCDEC (PCM_F32LE, pcm_f32le); REGISTER_ENCDEC (PCM_F64BE, pcm_f64be); @@ -508,6 +543,7 @@ void avcodec_register_all(void) REGISTER_DECODER(PCM_ZORK, pcm_zork); /* DPCM codecs */ + REGISTER_DECODER(GREMLIN_DPCM, gremlin_dpcm); REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm); REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm); REGISTER_DECODER(SOL_DPCM, sol_dpcm); @@ -528,7 +564,7 @@ void avcodec_register_all(void) REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); - REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le); + REGISTER_ENCDEC (ADPCM_G726LE, adpcm_g726le); REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc); REGISTER_DECODER(ADPCM_IMA_DAT4, adpcm_ima_dat4); @@ -606,7 +642,7 @@ void avcodec_register_all(void) REGISTER_DECODER(LIBOPENCORE_AMRWB, libopencore_amrwb); REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); REGISTER_ENCDEC (LIBOPUS, libopus); - REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); + REGISTER_DECODER(LIBRSVG, librsvg); REGISTER_ENCODER(LIBSHINE, libshine); REGISTER_ENCDEC (LIBSPEEX, libspeex); REGISTER_ENCODER(LIBTHEORA, libtheora); @@ -633,12 +669,13 @@ void avcodec_register_all(void) /* external libraries, that shouldn't be used by default if one of the * above is available */ + REGISTER_ENCODER(H263_V4L2M2M, h263_v4l2m2m); REGISTER_ENCDEC (LIBOPENH264, libopenh264); - REGISTER_DECODER(H263_CUVID, h263_cuvid); REGISTER_DECODER(H264_CUVID, h264_cuvid); REGISTER_ENCODER(H264_NVENC, h264_nvenc); REGISTER_ENCODER(H264_OMX, h264_omx); REGISTER_ENCODER(H264_QSV, h264_qsv); + REGISTER_ENCODER(H264_V4L2M2M, h264_v4l2m2m); REGISTER_ENCODER(H264_VAAPI, h264_vaapi); REGISTER_ENCODER(H264_VIDEOTOOLBOX, h264_videotoolbox); #if FF_API_NVENC_OLD_NAME @@ -650,6 +687,7 @@ void avcodec_register_all(void) REGISTER_DECODER(HEVC_MEDIACODEC, hevc_mediacodec); REGISTER_ENCODER(HEVC_NVENC, hevc_nvenc); REGISTER_ENCODER(HEVC_QSV, hevc_qsv); + REGISTER_ENCODER(HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_ENCODER(HEVC_VAAPI, hevc_vaapi); REGISTER_ENCODER(LIBKVAZAAR, libkvazaar); REGISTER_DECODER(MJPEG_CUVID, mjpeg_cuvid); @@ -657,13 +695,19 @@ void avcodec_register_all(void) REGISTER_DECODER(MPEG1_CUVID, mpeg1_cuvid); REGISTER_DECODER(MPEG2_CUVID, mpeg2_cuvid); REGISTER_ENCODER(MPEG2_QSV, mpeg2_qsv); + REGISTER_ENCODER(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_DECODER(MPEG4_CUVID, mpeg4_cuvid); REGISTER_DECODER(MPEG4_MEDIACODEC, mpeg4_mediacodec); + REGISTER_ENCODER(MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(VC1_CUVID, vc1_cuvid); REGISTER_DECODER(VP8_CUVID, vp8_cuvid); REGISTER_DECODER(VP8_MEDIACODEC, vp8_mediacodec); + REGISTER_DECODER(VP8_QSV, vp8_qsv); + REGISTER_ENCODER(VP8_V4L2M2M, vp8_v4l2m2m); + REGISTER_ENCODER(VP8_VAAPI, vp8_vaapi); REGISTER_DECODER(VP9_CUVID, vp9_cuvid); REGISTER_DECODER(VP9_MEDIACODEC, vp9_mediacodec); + REGISTER_ENCODER(VP9_VAAPI, vp9_vaapi); /* parsers */ REGISTER_PARSER(AAC, aac); @@ -698,10 +742,19 @@ void avcodec_register_all(void) REGISTER_PARSER(PNM, pnm); REGISTER_PARSER(RV30, rv30); REGISTER_PARSER(RV40, rv40); + REGISTER_PARSER(SIPR, sipr); REGISTER_PARSER(TAK, tak); REGISTER_PARSER(VC1, vc1); REGISTER_PARSER(VORBIS, vorbis); REGISTER_PARSER(VP3, vp3); REGISTER_PARSER(VP8, vp8); REGISTER_PARSER(VP9, vp9); + REGISTER_PARSER(XMA, xma); +} + +void avcodec_register_all(void) +{ + static AVOnce control = AV_ONCE_INIT; + + ff_thread_once(&control, register_all); } diff --git a/media/ffvpx/libavcodec/avcodec.h b/media/ffvpx/libavcodec/avcodec.h index e5e7f4225..18c3e3ea1 100644 --- a/media/ffvpx/libavcodec/avcodec.h +++ b/media/ffvpx/libavcodec/avcodec.h @@ -89,7 +89,7 @@ * - Send valid input: * - For decoding, call avcodec_send_packet() to give the decoder raw * compressed data in an AVPacket. - * - For encoding, call avcodec_send_frame() to give the decoder an AVFrame + * - For encoding, call avcodec_send_frame() to give the encoder an AVFrame * containing uncompressed audio or video. * In both cases, it is recommended that AVPackets and AVFrames are * refcounted, or libavcodec might have to copy the input data. (libavformat @@ -112,6 +112,12 @@ * are filled. This situation is handled transparently if you follow the steps * outlined above. * + * In theory, sending input can result in EAGAIN - this should happen only if + * not all output was received. You can use this to structure alternative decode + * or encode loops other than the one suggested above. For example, you could + * try sending new input on each iteration, and try to receive output if that + * returns EAGAIN. + * * End of stream situations. These require "flushing" (aka draining) the codec, * as the codec might buffer multiple frames or packets internally for * performance or out of necessity (consider B-frames). @@ -136,8 +142,9 @@ * * Not all codecs will follow a rigid and predictable dataflow; the only * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on - * one end implies that a receive/send call on the other end will succeed. In - * general, no codec will permit unlimited buffering of input or output. + * one end implies that a receive/send call on the other end will succeed, or + * at least will not fail with AVERROR(EAGAIN). In general, no codec will + * permit unlimited buffering of input or output. * * This API replaces the following legacy functions: * - avcodec_decode_video2() and avcodec_decode_audio4(): @@ -146,7 +153,8 @@ * Unlike with the old video decoding API, multiple frames might result from * a packet. For audio, splitting the input packet into frames by partially * decoding packets becomes transparent to the API user. You never need to - * feed an AVPacket to the API twice. + * feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then + * no data was read from the packet). * Additionally, sending a flush/draining packet is required only once. * - avcodec_encode_video2()/avcodec_encode_audio2(): * Use avcodec_send_frame() to feed input to the encoder, then use @@ -159,7 +167,22 @@ * and will result in undefined behavior. * * Some codecs might require using the new API; using the old API will return - * an error when calling it. + * an error when calling it. All codecs support the new API. + * + * A codec is not allowed to return AVERROR(EAGAIN) for both sending and receiving. This + * would be an invalid state, which could put the codec user into an endless + * loop. The API has no concept of time either: it cannot happen that trying to + * do avcodec_send_packet() results in AVERROR(EAGAIN), but a repeated call 1 second + * later accepts the packet (with no other receive/flush API calls involved). + * The API is a strict state machine, and the passage of time is not supposed + * to influence it. Some timing-dependent behavior might still be deemed + * acceptable in certain cases. But it must never result in both send/receive + * returning EAGAIN at the same time at any point. It must also absolutely be + * avoided that the current state is "unstable" and can "flip-flop" between + * the send/receive APIs allowing progress. For example, it's not allowed that + * the codec randomly decides that it actually wants to consume a packet now + * instead of returning a frame, after it just returned AVERROR(EAGAIN) on an + * avcodec_send_packet() call. * @} */ @@ -411,6 +434,20 @@ enum AVCodecID { AV_CODEC_ID_MAGICYUV, AV_CODEC_ID_SHEERVIDEO, AV_CODEC_ID_YLC, + AV_CODEC_ID_PSD, + AV_CODEC_ID_PIXLET, + AV_CODEC_ID_SPEEDHQ, + AV_CODEC_ID_FMVC, + AV_CODEC_ID_SCPR, + AV_CODEC_ID_CLEARVIDEO, + AV_CODEC_ID_XPM, + AV_CODEC_ID_AV1, + AV_CODEC_ID_BITPACKED, + AV_CODEC_ID_MSCC, + AV_CODEC_ID_SRGC, + AV_CODEC_ID_SVG, + AV_CODEC_ID_GDV, + AV_CODEC_ID_FITS, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -448,6 +485,8 @@ enum AVCodecID { AV_CODEC_ID_PCM_S64LE = 0x10800, AV_CODEC_ID_PCM_S64BE, + AV_CODEC_ID_PCM_F16LE, + AV_CODEC_ID_PCM_F24LE, /* various ADPCM codecs */ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, @@ -511,6 +550,7 @@ enum AVCodecID { AV_CODEC_ID_SOL_DPCM, AV_CODEC_ID_SDX2_DPCM = 0x14800, + AV_CODEC_ID_GREMLIN_DPCM, /* audio codecs */ AV_CODEC_ID_MP2 = 0x15000, @@ -598,6 +638,9 @@ enum AVCodecID { AV_CODEC_ID_XMA1, AV_CODEC_ID_XMA2, AV_CODEC_ID_DST, + AV_CODEC_ID_ATRAC3AL, + AV_CODEC_ID_ATRAC3PAL, + AV_CODEC_ID_DOLBY_E, /* subtitle codecs */ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. @@ -689,7 +732,7 @@ typedef struct AVCodecDescriptor { /** * Codec uses only intra compression. - * Video codecs only. + * Video and audio codecs only. */ #define AV_CODEC_PROP_INTRA_ONLY (1 << 0) /** @@ -1360,6 +1403,11 @@ typedef struct AVCPBProperties { * @{ */ enum AVPacketSideDataType { + /** + * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE + * bytes worth of palette. This side data signals that a new palette is + * present. + */ AV_PKT_DATA_PALETTE, /** @@ -1533,10 +1581,40 @@ enum AVPacketSideDataType { /** * Mastering display metadata (based on SMPTE-2086:2014). This metadata - * should be associated with a video stream and containts data in the form + * should be associated with a video stream and contains data in the form * of the AVMasteringDisplayMetadata struct. */ - AV_PKT_DATA_MASTERING_DISPLAY_METADATA + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + + /** + * This side data should be associated with a video stream and corresponds + * to the AVSphericalMapping structure. + */ + AV_PKT_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This metadata should be + * associated with a video stream and contains data in the form of the + * AVContentLightMetadata struct. + */ + AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + + /** + * ATSC A53 Part 4 Closed Captions. This metadata should be associated with + * a video stream. A53 CC bitstream is stored as uint8_t in AVPacketSideData.data. + * The number of bytes of CC data is AVPacketSideData.size. + */ + AV_PKT_DATA_A53_CC, + + /** + * The number of side data elements (in fact a bit more than it). + * This is not part of the public API/ABI in the sense that it may + * change when new side data types are added. + * This must stay the last enum value. + * If its value becomes huge, some code using it + * needs to be updated as it assumes it to be smaller than other limits. + */ + AV_PKT_DATA_NB }; #define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED @@ -1638,6 +1716,13 @@ typedef struct AVPacket { * after decoding. **/ #define AV_PKT_FLAG_DISCARD 0x0004 +/** + * The packet comes from a trusted source. + * + * Otherwise-unsafe constructs such as arbitrary pointers to data + * outside the packet may be followed. + */ +#define AV_PKT_FLAG_TRUSTED 0x0008 enum AVSideDataParamChangeFlags { AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, @@ -1665,7 +1750,7 @@ enum AVFieldOrder { * New fields can be added to the end with minor version bumps. * Removal, reordering and changes to existing fields require a major * version bump. - * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user + * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user * applications. * The name string for AVOptions options matches the associated command line * parameter name and can be found in libavcodec/options_table.h @@ -2605,6 +2690,7 @@ typedef struct AVCodecContext { * - encoding: unused * - decoding: set by the caller before avcodec_open2(). */ + attribute_deprecated int refcounted_frames; /* - encoding parameters */ @@ -2936,8 +3022,8 @@ typedef struct AVCodecContext { #define FF_DEBUG_MMCO 0x00000800 #define FF_DEBUG_BUGS 0x00001000 #if FF_API_DEBUG_MV -#define FF_DEBUG_VIS_QP 0x00002000 ///< only access through AVOptions from outside libavcodec -#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 #endif #define FF_DEBUG_BUFFERS 0x00008000 #define FF_DEBUG_THREADS 0x00010000 @@ -2947,7 +3033,6 @@ typedef struct AVCodecContext { #if FF_API_DEBUG_MV /** * debug - * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -3061,6 +3146,7 @@ typedef struct AVCodecContext { #if FF_API_ARCH_ALPHA #define FF_IDCT_SIMPLEALPHA 23 #endif +#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ #define FF_IDCT_SIMPLEAUTO 128 /** @@ -3082,8 +3168,6 @@ typedef struct AVCodecContext { * low resolution decoding, 1-> 1/2 size, 2->1/4 size * - encoding: unused * - decoding: Set by user. - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_lowres(avctx) */ int lowres; #endif @@ -3384,8 +3468,6 @@ typedef struct AVCodecContext { /** * Timebase in which pkt_dts/pts and AVPacket.dts/pts are. - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_pkt_timebase(avctx) * - encoding unused. * - decoding set by user. */ @@ -3393,8 +3475,6 @@ typedef struct AVCodecContext { /** * AVCodecDescriptor - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_codec_descriptor(avctx) * - encoding: unused. * - decoding: set by libavcodec. */ @@ -3405,8 +3485,6 @@ typedef struct AVCodecContext { * low resolution decoding, 1-> 1/2 size, 2->1/4 size * - encoding: unused * - decoding: Set by user. - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_lowres(avctx) */ int lowres; #endif @@ -3447,7 +3525,6 @@ typedef struct AVCodecContext { * However for formats that do not use pre-multiplied alpha * there might be serious artefacts (though e.g. libswscale currently * assumes pre-multiplied alpha anyway). - * Code outside libavcodec should access this field using AVOptions * * - decoding: set by user * - encoding: unused @@ -3464,7 +3541,6 @@ typedef struct AVCodecContext { #if !FF_API_DEBUG_MV /** * debug motion vectors - * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -3476,7 +3552,6 @@ typedef struct AVCodecContext { /** * custom intra quantization matrix - * Code outside libavcodec should access this field using av_codec_g/set_chroma_intra_matrix() * - encoding: Set by user, can be NULL. * - decoding: unused. */ @@ -3485,8 +3560,6 @@ typedef struct AVCodecContext { /** * 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. */ @@ -3496,13 +3569,12 @@ typedef struct AVCodecContext { * ',' separated list of allowed decoders. * If NULL then all are allowed * - encoding: unused - * - decoding: set by user through AVOPtions (NO direct access) + * - decoding: set by user */ char *codec_whitelist; - /* + /** * Properties of the stream that gets decoded - * To be accessed through av_codec_get_properties() (NO direct access) * - encoding: unused * - decoding: set by libavcodec */ @@ -3522,7 +3594,8 @@ typedef struct AVCodecContext { /** * A reference to the AVHWFramesContext describing the input (for encoding) * or output (decoding) frames. The reference is set by the caller and - * afterwards owned (and freed) by libavcodec. + * afterwards owned (and freed) by libavcodec - it should never be read by + * the caller after being set. * * - decoding: This field should be set by the caller from the get_format() * callback. The previous reference (if any) will always be @@ -3564,6 +3637,71 @@ typedef struct AVCodecContext { */ int trailing_padding; + /** + * The number of pixels per image to maximally accept. + * + * - decoding: set by user + * - encoding: set by user + */ + int64_t max_pixels; + + /** + * A reference to the AVHWDeviceContext describing the device which will + * be used by a hardware encoder/decoder. The reference is set by the + * caller and afterwards owned (and freed) by libavcodec. + * + * This should be used if either the codec device does not require + * hardware frames or any that are used are to be allocated internally by + * libavcodec. If the user wishes to supply any of the frames used as + * encoder input or decoder output then hw_frames_ctx should be used + * instead. When hw_frames_ctx is set in get_format() for a decoder, this + * field will be ignored while decoding the associated stream segment, but + * may again be used on a following one after another get_format() call. + * + * For both encoders and decoders this field should be set before + * avcodec_open2() is called and must not be written to thereafter. + * + * Note that some decoders may require this field to be set initially in + * order to support hw_frames_ctx at all - in that case, all frames + * contexts used must be created on the same device. + */ + AVBufferRef *hw_device_ctx; + + /** + * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated + * decoding (if active). + * - encoding: unused + * - decoding: Set by user (either before avcodec_open2(), or in the + * AVCodecContext.get_format callback) + */ + int hwaccel_flags; + + /** + * Video decoding only. Certain video codecs support cropping, meaning that + * only a sub-rectangle of the decoded frame is intended for display. This + * option controls how cropping is handled by libavcodec. + * + * When set to 1 (the default), libavcodec will apply cropping internally. + * I.e. it will modify the output frame width/height fields and offset the + * data pointers (only by as much as possible while preserving alignment, or + * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that + * the frames output by the decoder refer only to the cropped area. The + * crop_* fields of the output frames will be zero. + * + * When set to 0, the width/height fields of the output frames will be set + * to the coded dimensions and the crop_* fields will describe the cropping + * rectangle. Applying the cropping is left to the caller. + * + * @warning When hardware acceleration with opaque output frames is used, + * libavcodec is unable to apply cropping from the top/left border. + * + * @note when this option is set to zero, the width/height fields of the + * AVCodecContext and output AVFrames have different meanings. The codec + * context fields store display dimensions (with the coded dimensions in + * coded_width/height), while the frame fields store the coded dimensions + * (with the display dimensions being determined by the crop_* fields). + */ + int apply_cropping; } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); @@ -3623,7 +3761,7 @@ typedef struct AVCodec { const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 - uint8_t max_lowres; ///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres() + uint8_t max_lowres; ///< maximum value for lowres supported by the decoder const AVClass *priv_class; ///< AVClass for the private context const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} @@ -3684,20 +3822,22 @@ typedef struct AVCodec { int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); int (*close)(AVCodecContext *); /** - * Decode/encode API with decoupled packet/frame dataflow. The API is the + * Encode API with decoupled packet/frame dataflow. The API is the * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except * that: * - never called if the codec is closed or the wrong type, - * - AVPacket parameter change side data is applied right before calling - * AVCodec->send_packet, - * - if AV_CODEC_CAP_DELAY is not set, drain packets or frames are never sent, - * - only one drain packet is ever passed down (until the next flush()), - * - a drain AVPacket is always NULL (no need to check for avpkt->size). + * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, + * - only one drain frame is ever passed down, */ int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame); - int (*send_packet)(AVCodecContext *avctx, const AVPacket *avpkt); - int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt); + + /** + * Decode API with decoupled packet/frame dataflow. This function is called + * to get one output frame. It should call ff_decode_get_packet() to obtain + * input data. + */ + int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); /** * Flush buffers. * Will be called when seeking @@ -3708,6 +3848,12 @@ typedef struct AVCodec { * See FF_CODEC_CAP_* in internal.h */ int caps_internal; + + /** + * Decoding only, a comma-separated list of bitstream filters to apply to + * packets before decoding. + */ + const char *bsfs; } AVCodec; int av_codec_get_max_lowres(const AVCodec *codec); @@ -3749,7 +3895,7 @@ typedef struct AVHWAccel { /** * Hardware accelerated codec capabilities. - * see HWACCEL_CODEC_CAP_* + * see AV_HWACCEL_CODEC_CAP_* */ int capabilities; @@ -3820,7 +3966,7 @@ typedef struct AVHWAccel { /** * Called for every Macroblock in a slice. * - * XvMC uses it to replace the ff_mpv_decode_mb(). + * XvMC uses it to replace the ff_mpv_reconstruct_mb(). * Instead of decoding to raw picture, MB parameters are * stored in an array provided by the video driver. * @@ -3850,8 +3996,19 @@ typedef struct AVHWAccel { * AVCodecInternal.hwaccel_priv_data. */ int priv_data_size; + + /** + * Internal hwaccel capabilities. + */ + int caps_internal; } AVHWAccel; +/** + * HWAccel is experimental and is thus avoided in favor of non experimental + * codecs + */ +#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 + /** * 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 @@ -3868,6 +4025,20 @@ typedef struct AVHWAccel { */ #define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1) +/** + * Hardware acceleration should still be attempted for decoding when the + * codec profile does not match the reported capabilities of the hardware. + * + * For example, this can be used to try to decode baseline profile H.264 + * streams in hardware - it will often succeed, because many streams marked + * as baseline profile actually conform to constrained baseline profile. + * + * @warning If the stream is actually not supported then the behaviour is + * undefined, and may include returning entirely incorrect output + * while indicating success. + */ +#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) + /** * @} */ @@ -4377,13 +4548,13 @@ AVPacket *av_packet_alloc(void); * @see av_packet_alloc * @see av_packet_ref */ -AVPacket *av_packet_clone(AVPacket *src); +AVPacket *av_packet_clone(const AVPacket *src); /** * Free the packet, if the packet is reference counted, it will be * unreferenced first. * - * @param packet packet to be freed. The pointer will be set to NULL. + * @param pkt packet to be freed. The pointer will be set to NULL. * @note passing NULL is a no-op. */ void av_packet_free(AVPacket **pkt); @@ -4452,14 +4623,20 @@ int av_dup_packet(AVPacket *pkt); * Copy packet, including contents * * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_ref */ +attribute_deprecated int av_copy_packet(AVPacket *dst, const AVPacket *src); /** * Copy packet side data * * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_copy_props */ +attribute_deprecated int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src); /** @@ -4518,12 +4695,16 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, * @param size pointer for side information size to store (optional) * @return pointer to data if present or NULL otherwise */ -uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size); +#if FF_API_MERGE_SD_API +attribute_deprecated int av_packet_merge_side_data(AVPacket *pkt); +attribute_deprecated int av_packet_split_side_data(AVPacket *pkt); +#endif const char *av_packet_side_data_name(enum AVPacketSideDataType type); @@ -4823,13 +5004,13 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, * and reusing a get_buffer written for video codecs would probably perform badly * due to a potentially very different allocation pattern. * - * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input * and output. This means that for some packets they will not immediately * produce decoded output and need to be flushed at the end of decoding to get * all the decoded data. Flushing is done by calling this function with packets * with avpkt->data set to NULL and avpkt->size set to 0 until it stops * returning subtitles. It is safe to flush even those decoders that are not - * marked with CODEC_CAP_DELAY, then no subtitles will be returned. + * marked with AV_CODEC_CAP_DELAY, then no subtitles will be returned. * * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() * before packets may be fed to the decoder. @@ -4883,8 +5064,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, * a flush packet. * * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted right now - the packet must be - * resent after trying to read output + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_frame() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). * AVERROR_EOF: the decoder has been flushed, and no new packets can * be sent to it (also returned if more than 1 flush * packet is sent) @@ -4905,7 +5088,7 @@ int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); * * @return * 0: success, a frame was returned - * AVERROR(EAGAIN): output is not available right now - user must try + * AVERROR(EAGAIN): output is not available in this state - user must try * to send new input * AVERROR_EOF: the decoder has been fully flushed, and there will be * no more output frames @@ -4938,8 +5121,10 @@ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); * avctx->frame_size for all frames except the last. * The final frame may be smaller than avctx->frame_size. * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted right now - the frame must be - * resent after trying to read output packets + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_packet() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). * AVERROR_EOF: the encoder has been flushed, and no new frames can * be sent to it * AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a @@ -4957,8 +5142,8 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); * encoder. Note that the function will always call * av_frame_unref(frame) before doing anything else. * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): output is not available right now - user must try - * to send input + * AVERROR(EAGAIN): output is not available in the current state - user + * must try to send input * AVERROR_EOF: the encoder has been fully flushed, and there will be * no more output packets * AVERROR(EINVAL): codec not opened, or it is an encoder @@ -5509,22 +5694,14 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, * @{ */ +#if FF_API_GETCHROMA /** - * Utility function to access log2_chroma_w log2_chroma_h from - * the pixel format AVPixFmtDescriptor. - * - * This function asserts that pix_fmt is valid. See av_pix_fmt_get_chroma_sub_sample - * for one that returns a failure code and continues in case of invalid - * pix_fmts. - * - * @param[in] pix_fmt the pixel format - * @param[out] h_shift store log2_chroma_w - * @param[out] v_shift store log2_chroma_h - * - * @see av_pix_fmt_get_chroma_sub_sample + * @deprecated Use av_pix_fmt_get_chroma_sub_sample */ +attribute_deprecated void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift); +#endif /** * Return a value representing the fourCC code associated to the @@ -5584,6 +5761,7 @@ attribute_deprecated void avcodec_set_dimensions(AVCodecContext *s, int width, int height); #endif +#if FF_API_TAG_STRING /** * Put a string representing the codec tag codec_tag in buf. * @@ -5592,8 +5770,12 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height); * @param codec_tag codec tag to assign * @return the length of the string that would have been generated if * enough space had been available, excluding the trailing null + * + * @deprecated see av_fourcc_make_string() and av_fourcc2str(). */ +attribute_deprecated size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag); +#endif void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); @@ -5706,7 +5888,7 @@ int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes); #if FF_API_OLD_BSF typedef struct AVBitStreamFilterContext { void *priv_data; - struct AVBitStreamFilter *filter; + const struct AVBitStreamFilter *filter; AVCodecParserContext *parser; struct AVBitStreamFilterContext *next; /** @@ -5753,12 +5935,15 @@ typedef struct AVBSFContext { void *priv_data; /** - * Parameters of the input stream. Set by the caller before av_bsf_init(). + * Parameters of the input stream. This field is allocated in + * av_bsf_alloc(), it needs to be filled by the caller before + * av_bsf_init(). */ AVCodecParameters *par_in; /** - * Parameters of the output stream. Set by the filter in av_bsf_init(). + * Parameters of the output stream. This field is allocated in + * av_bsf_alloc(), it is set by the filter in av_bsf_init(). */ AVCodecParameters *par_out; @@ -5936,8 +6121,7 @@ int av_bsf_init(AVBSFContext *ctx); * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or * AVERROR_EOF. * - * @param pkt the packet to filter. pkt must contain some payload (i.e data or - * side data must be present in pkt). The bitstream filter will take ownership of + * @param pkt the packet to filter. The bitstream filter will take ownership of * the packet and reset the contents of pkt. pkt is not touched if an error occurs. * This parameter may be NULL, which signals the end of the stream (i.e. no more * packets will be sent). That will cause the filter to output any packets it diff --git a/media/ffvpx/libavcodec/avdct.h b/media/ffvpx/libavcodec/avdct.h deleted file mode 100644 index 272422e44..000000000 --- a/media/ffvpx/libavcodec/avdct.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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_AVDCT_H -#define AVCODEC_AVDCT_H - -#include "libavutil/opt.h" - -/** - * AVDCT context. - * @note function pointers can be NULL if the specific features have been - * disabled at build time. - */ -typedef struct AVDCT { - const AVClass *av_class; - - void (*idct)(int16_t *block /* align 16 */); - - /** - * IDCT input permutation. - * Several optimized IDCTs need a permutated input (relative to the - * normal order of the reference IDCT). - * This permutation must be performed before the idct_put/add. - * Note, normally this can be merged with the zigzag/alternate scan
- * An example to avoid confusion: - * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) - * - (x -> reference DCT -> reference IDCT -> x) - * - (x -> reference DCT -> simple_mmx_perm = idct_permutation - * -> simple_idct_mmx -> x) - * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant - * -> simple_idct_mmx -> ...) - */ - uint8_t idct_permutation[64]; - - void (*fdct)(int16_t *block /* align 16 */); - - - /** - * DCT algorithm. - * must use AVOptions to set this field. - */ - int dct_algo; - - /** - * IDCT algorithm. - * must use AVOptions to set this field. - */ - int idct_algo; - - void (*get_pixels)(int16_t *block /* align 16 */, - const uint8_t *pixels /* align 8 */, - ptrdiff_t line_size); - - int bits_per_sample; -} AVDCT; - -/** - * Allocates a AVDCT context. - * This needs to be initialized with avcodec_dct_init() after optionally - * configuring it with AVOptions. - * - * To free it use av_free() - */ -AVDCT *avcodec_dct_alloc(void); -int avcodec_dct_init(AVDCT *); - -const AVClass *avcodec_dct_get_class(void); - -#endif /* AVCODEC_AVDCT_H */ diff --git a/media/ffvpx/libavcodec/avpacket.c b/media/ffvpx/libavcodec/avpacket.c index e5a8bdbe4..d1f4ea9eb 100644 --- a/media/ffvpx/libavcodec/avpacket.c +++ b/media/ffvpx/libavcodec/avpacket.c @@ -247,8 +247,6 @@ failed_alloc: av_packet_unref(pkt); return AVERROR(ENOMEM); } -FF_ENABLE_DEPRECATION_WARNINGS -#endif int av_dup_packet(AVPacket *pkt) { @@ -266,6 +264,8 @@ int av_copy_packet(AVPacket *dst, const AVPacket *src) *dst = *src; return copy_packet_data(dst, src, 0); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif void av_packet_free_side_data(AVPacket *pkt) { @@ -296,9 +296,20 @@ int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size) { AVPacketSideData *tmp; - int elems = pkt->side_data_elems; + int i, elems = pkt->side_data_elems; + + for (i = 0; i < elems; i++) { + AVPacketSideData *sd = &pkt->side_data[i]; + + if (sd->type == type) { + av_free(sd->data); + sd->data = data; + sd->size = size; + return 0; + } + } - if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data)) + if ((unsigned)elems + 1 > AV_PKT_DATA_NB) return AVERROR(ERANGE); tmp = av_realloc(pkt->side_data, (elems + 1) * sizeof(*tmp)); @@ -336,7 +347,7 @@ uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, return data; } -uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +uint8_t *av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size) { int i; @@ -348,6 +359,8 @@ uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, return pkt->side_data[i].data; } } + if (size) + *size = 0; return NULL; } @@ -372,10 +385,15 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update"; case AV_PKT_DATA_MPEGTS_STREAM_ID: return "MPEGTS Stream ID"; case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; + case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; + case AV_PKT_DATA_SPHERICAL: return "Spherical Mapping"; + case AV_PKT_DATA_A53_CC: return "A53 Closed Captions"; } return NULL; } +#if FF_API_MERGE_SD_API + #define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL int av_packet_merge_side_data(AVPacket *pkt){ @@ -431,6 +449,9 @@ int av_packet_split_side_data(AVPacket *pkt){ p-= size+5; } + if (i > AV_PKT_DATA_NB) + return AVERROR(ERANGE); + pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data)); if (!pkt->side_data) return AVERROR(ENOMEM); @@ -456,6 +477,35 @@ int av_packet_split_side_data(AVPacket *pkt){ } return 0; } +#endif + +#if FF_API_MERGE_SD +int ff_packet_split_and_drop_side_data(AVPacket *pkt){ + if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){ + int i; + unsigned int size; + uint8_t *p; + + p = pkt->data + pkt->size - 8 - 5; + for (i=1; ; i++){ + size = AV_RB32(p); + if (size>INT_MAX - 5 || p - pkt->data < size) + return 0; + if (p[4]&128) + break; + if (p - pkt->data < size + 5) + return 0; + p-= size+5; + if (i > AV_PKT_DATA_NB) + return 0; + } + pkt->size = p - pkt->data - size; + av_assert0(pkt->size >= 0); + return 1; + } + return 0; +} +#endif uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) { @@ -505,7 +555,7 @@ int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **di const uint8_t *key = data; const uint8_t *val = data + strlen(key) + 1; - if (val >= end) + if (val >= end || !*key) return AVERROR_INVALIDDATA; ret = av_dict_set(dict, key, val, 0); @@ -607,7 +657,7 @@ fail: return ret; } -AVPacket *av_packet_clone(AVPacket *src) +AVPacket *av_packet_clone(const AVPacket *src) { AVPacket *ret = av_packet_alloc(); diff --git a/media/ffvpx/libavcodec/bitstream.c b/media/ffvpx/libavcodec/bitstream.c index 562ca1cb8..ed528fe4a 100644 --- a/media/ffvpx/libavcodec/bitstream.c +++ b/media/ffvpx/libavcodec/bitstream.c @@ -28,7 +28,6 @@ * bitstream api. */ -#include "libavutil/atomic.h" #include "libavutil/avassert.h" #include "libavutil/qsort.h" #include "avcodec.h" @@ -99,9 +98,11 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) case 2: \ v = *(const uint16_t *)ptr; \ break; \ - default: \ + case 4: \ v = *(const uint32_t *)ptr; \ break; \ + default: \ + av_assert1(0); \ } \ } @@ -126,14 +127,6 @@ static int alloc_table(VLC *vlc, int size, int use_static) return index; } -static av_always_inline uint32_t bitswap_32(uint32_t x) -{ - return (uint32_t)ff_reverse[ x & 0xFF] << 24 | - (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | - (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | - (uint32_t)ff_reverse[ x >> 24]; -} - typedef struct VLCcode { uint8_t bits; uint16_t symbol; @@ -183,7 +176,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, n = codes[i].bits; code = codes[i].code; symbol = codes[i].symbol; - ff_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code); + ff_dlog(NULL, "i=%d n=%d code=0x%"PRIx32"\n", i, n, code); if (n <= table_nb_bits) { /* no need to add another table */ j = code >> (32 - table_nb_bits); @@ -264,7 +257,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, 'bits' or 'codes' tables. 'xxx_size' : gives the number of bytes of each entry of the 'bits' - or 'codes' tables. + or 'codes' tables. Currently 1,2 and 4 are supported. 'wrap' and 'size' make it possible to use any memory configuration and types (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. @@ -317,7 +310,8 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, } \ GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ if (buf[j].code >= (1LL< + * + * 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 "avcodec.h" +#include "libavutil/internal.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" + +#if FF_API_OLD_BSF +FF_DISABLE_DEPRECATION_WARNINGS + +AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f) +{ + const AVBitStreamFilter *filter = NULL; + void *opaque = NULL; + + while (filter != f) + filter = av_bsf_next(&opaque); + + return av_bsf_next(&opaque); +} + +void av_register_bitstream_filter(AVBitStreamFilter *bsf) +{ +} + +typedef struct BSFCompatContext { + AVBSFContext *ctx; + int extradata_updated; +} BSFCompatContext; + +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) +{ + AVBitStreamFilterContext *ctx = NULL; + BSFCompatContext *priv = NULL; + const AVBitStreamFilter *bsf; + + bsf = av_bsf_get_by_name(name); + if (!bsf) + return NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + goto fail; + + + ctx->filter = bsf; + ctx->priv_data = priv; + + return ctx; + +fail: + if (priv) + av_bsf_free(&priv->ctx); + av_freep(&priv); + av_freep(&ctx); + return NULL; +} + +void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) +{ + BSFCompatContext *priv; + + if (!bsfc) + return; + + priv = bsfc->priv_data; + + av_bsf_free(&priv->ctx); + av_freep(&bsfc->priv_data); + av_free(bsfc); +} + +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + BSFCompatContext *priv = bsfc->priv_data; + AVPacket pkt = { 0 }; + int ret; + + if (!priv->ctx) { + ret = av_bsf_alloc(bsfc->filter, &priv->ctx); + if (ret < 0) + return ret; + + ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx); + if (ret < 0) + return ret; + + priv->ctx->time_base_in = avctx->time_base; + + if (bsfc->args && bsfc->filter->priv_class) { + const AVOption *opt = av_opt_next(priv->ctx->priv_data, NULL); + const char * shorthand[2] = {NULL}; + + if (opt) + shorthand[0] = opt->name; + + ret = av_opt_set_from_string(priv->ctx->priv_data, bsfc->args, shorthand, "=", ":"); + if (ret < 0) + return ret; + } + + ret = av_bsf_init(priv->ctx); + if (ret < 0) + return ret; + } + + pkt.data = buf; + pkt.size = buf_size; + + ret = av_bsf_send_packet(priv->ctx, &pkt); + if (ret < 0) + return ret; + + *poutbuf = NULL; + *poutbuf_size = 0; + + ret = av_bsf_receive_packet(priv->ctx, &pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return 0; + else if (ret < 0) + return ret; + + *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*poutbuf) { + av_packet_unref(&pkt); + return AVERROR(ENOMEM); + } + + *poutbuf_size = pkt.size; + memcpy(*poutbuf, pkt.data, pkt.size); + + av_packet_unref(&pkt); + + /* drain all the remaining packets we cannot return */ + while (ret >= 0) { + ret = av_bsf_receive_packet(priv->ctx, &pkt); + av_packet_unref(&pkt); + } + + if (!priv->extradata_updated) { + /* update extradata in avctx from the output codec parameters */ + if (priv->ctx->par_out->extradata_size && (!args || !strstr(args, "private_spspps_buf"))) { + av_freep(&avctx->extradata); + avctx->extradata_size = 0; + avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + memcpy(avctx->extradata, priv->ctx->par_out->extradata, priv->ctx->par_out->extradata_size); + avctx->extradata_size = priv->ctx->par_out->extradata_size; + } + + priv->extradata_updated = 1; + } + + return 1; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif diff --git a/media/ffvpx/libavcodec/bitstream_filters.c b/media/ffvpx/libavcodec/bitstream_filters.c new file mode 100644 index 000000000..ce34de640 --- /dev/null +++ b/media/ffvpx/libavcodec/bitstream_filters.c @@ -0,0 +1,91 @@ +/* + * 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/common.h" +#include "libavutil/log.h" + +#include "avcodec.h" +#include "bsf.h" + +extern const AVBitStreamFilter ff_aac_adtstoasc_bsf; +extern const AVBitStreamFilter ff_chomp_bsf; +extern const AVBitStreamFilter ff_dump_extradata_bsf; +extern const AVBitStreamFilter ff_dca_core_bsf; +extern const AVBitStreamFilter ff_extract_extradata_bsf; +extern const AVBitStreamFilter ff_h264_mp4toannexb_bsf; +extern const AVBitStreamFilter ff_hevc_mp4toannexb_bsf; +extern const AVBitStreamFilter ff_imx_dump_header_bsf; +extern const AVBitStreamFilter ff_mjpeg2jpeg_bsf; +extern const AVBitStreamFilter ff_mjpega_dump_header_bsf; +extern const AVBitStreamFilter ff_mp3_header_decompress_bsf; +extern const AVBitStreamFilter ff_mpeg4_unpack_bframes_bsf; +extern const AVBitStreamFilter ff_mov2textsub_bsf; +extern const AVBitStreamFilter ff_noise_bsf; +extern const AVBitStreamFilter ff_null_bsf; +extern const AVBitStreamFilter ff_remove_extradata_bsf; +extern const AVBitStreamFilter ff_text2movsub_bsf; +extern const AVBitStreamFilter ff_vp9_raw_reorder_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_split_bsf; + +#include "libavcodec/bsf_list.c" + +const AVBitStreamFilter *av_bsf_next(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVBitStreamFilter *f = bitstream_filters[i]; + + if (f) + *opaque = (void*)(i + 1); + + return f; +} + +const AVBitStreamFilter *av_bsf_get_by_name(const char *name) +{ + int i; + + for (i = 0; bitstream_filters[i]; i++) { + const AVBitStreamFilter *f = bitstream_filters[i]; + if (!strcmp(f->name, name)) + return f; + } + + return NULL; +} + +const AVClass *ff_bsf_child_class_next(const AVClass *prev) +{ + int i; + + /* find the filter that corresponds to prev */ + for (i = 0; prev && bitstream_filters[i]; i++) { + if (bitstream_filters[i]->priv_class == prev) { + i++; + break; + } + } + + /* find next filter with priv options */ + for (; bitstream_filters[i]; i++) + if (bitstream_filters[i]->priv_class) + return bitstream_filters[i]->priv_class; + return NULL; +} diff --git a/media/ffvpx/libavcodec/blockdsp.h b/media/ffvpx/libavcodec/blockdsp.h index 95e1d0f32..6e27a02ba 100644 --- a/media/ffvpx/libavcodec/blockdsp.h +++ b/media/ffvpx/libavcodec/blockdsp.h @@ -19,6 +19,7 @@ #ifndef AVCODEC_BLOCKDSP_H #define AVCODEC_BLOCKDSP_H +#include #include #include "avcodec.h" @@ -29,7 +30,7 @@ * h for op_pixels_func is limited to { width / 2, width }, * but never larger than 16 and never smaller than 4. */ typedef void (*op_fill_func)(uint8_t *block /* align width (8 or 16) */, - uint8_t value, int line_size, int h); + uint8_t value, ptrdiff_t line_size, int h); typedef struct BlockDSPContext { void (*clear_block)(int16_t *block /* align 16 */); diff --git a/media/ffvpx/libavcodec/bsf.c b/media/ffvpx/libavcodec/bsf.c index 88b7f29fe..38b423101 100644 --- a/media/ffvpx/libavcodec/bsf.c +++ b/media/ffvpx/libavcodec/bsf.c @@ -21,6 +21,8 @@ #include "libavutil/log.h" #include "libavutil/mem.h" #include "libavutil/opt.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "avcodec.h" #include "bsf.h" @@ -172,7 +174,7 @@ int av_bsf_init(AVBSFContext *ctx) int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) { - if (!pkt || !pkt->data) { + if (!pkt || (!pkt->data && !pkt->side_data_elems)) { ctx->internal->eof = 1; return 0; } @@ -217,3 +219,324 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) return 0; } + +int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt) +{ + AVBSFInternal *in = ctx->internal; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(pkt, ctx->internal->buffer_pkt); + + return 0; +} + +typedef struct BSFListContext { + const AVClass *class; + + AVBSFContext **bsfs; + int nb_bsfs; + + unsigned idx; // index of currently processed BSF + unsigned flushed_idx; // index of BSF being flushed + + char * item_name; +} BSFListContext; + + +static int bsf_list_init(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + int ret, i; + const AVCodecParameters *cod_par = bsf->par_in; + AVRational tb = bsf->time_base_in; + + for (i = 0; i < lst->nb_bsfs; ++i) { + ret = avcodec_parameters_copy(lst->bsfs[i]->par_in, cod_par); + if (ret < 0) + goto fail; + + lst->bsfs[i]->time_base_in = tb; + + ret = av_bsf_init(lst->bsfs[i]); + if (ret < 0) + goto fail; + + cod_par = lst->bsfs[i]->par_out; + tb = lst->bsfs[i]->time_base_out; + } + + bsf->time_base_out = tb; + ret = avcodec_parameters_copy(bsf->par_out, cod_par); + +fail: + return ret; +} + +static int bsf_list_filter(AVBSFContext *bsf, AVPacket *out) +{ + BSFListContext *lst = bsf->priv_data; + int ret; + + if (!lst->nb_bsfs) + return ff_bsf_get_packet_ref(bsf, out); + + while (1) { + if (lst->idx > lst->flushed_idx) { + ret = av_bsf_receive_packet(lst->bsfs[lst->idx-1], out); + if (ret == AVERROR(EAGAIN)) { + /* no more packets from idx-1, try with previous */ + ret = 0; + lst->idx--; + continue; + } else if (ret == AVERROR_EOF) { + /* filter idx-1 is done, continue with idx...nb_bsfs */ + lst->flushed_idx = lst->idx; + continue; + }else if (ret < 0) { + /* filtering error */ + break; + } + } else { + ret = ff_bsf_get_packet_ref(bsf, out); + if (ret == AVERROR_EOF) { + lst->idx = lst->flushed_idx; + } else if (ret < 0) + break; + } + + if (lst->idx < lst->nb_bsfs) { + AVPacket *pkt; + if (ret == AVERROR_EOF && lst->idx == lst->flushed_idx) { + /* ff_bsf_get_packet_ref returned EOF and idx is first + * filter of yet not flushed filter chain */ + pkt = NULL; + } else { + pkt = out; + } + ret = av_bsf_send_packet(lst->bsfs[lst->idx], pkt); + if (ret < 0) + break; + lst->idx++; + } else { + /* The end of filter chain, break to return result */ + break; + } + } + + if (ret < 0) + av_packet_unref(out); + + return ret; +} + +static void bsf_list_close(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + int i; + + for (i = 0; i < lst->nb_bsfs; ++i) + av_bsf_free(&lst->bsfs[i]); + av_freep(&lst->bsfs); + av_freep(&lst->item_name); +} + +static const char *bsf_list_item_name(void *ctx) +{ + static const char *null_filter_name = "null"; + AVBSFContext *bsf_ctx = ctx; + BSFListContext *lst = bsf_ctx->priv_data; + + if (!lst->nb_bsfs) + return null_filter_name; + + if (!lst->item_name) { + int i; + AVBPrint bp; + av_bprint_init(&bp, 16, 128); + + av_bprintf(&bp, "bsf_list("); + for (i = 0; i < lst->nb_bsfs; i++) + av_bprintf(&bp, i ? ",%s" : "%s", lst->bsfs[i]->filter->name); + av_bprintf(&bp, ")"); + + av_bprint_finalize(&bp, &lst->item_name); + } + + return lst->item_name; +} + +static const AVClass bsf_list_class = { + .class_name = "bsf_list", + .item_name = bsf_list_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVBitStreamFilter ff_list_bsf = { + .name = "bsf_list", + .priv_data_size = sizeof(BSFListContext), + .priv_class = &bsf_list_class, + .init = bsf_list_init, + .filter = bsf_list_filter, + .close = bsf_list_close, +}; + +struct AVBSFList { + AVBSFContext **bsfs; + int nb_bsfs; +}; + +AVBSFList *av_bsf_list_alloc(void) +{ + return av_mallocz(sizeof(AVBSFList)); +} + +void av_bsf_list_free(AVBSFList **lst) +{ + int i; + + if (!*lst) + return; + + for (i = 0; i < (*lst)->nb_bsfs; ++i) + av_bsf_free(&(*lst)->bsfs[i]); + av_free((*lst)->bsfs); + av_freep(lst); +} + +int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf) +{ + return av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf); +} + +int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options) +{ + int ret; + const AVBitStreamFilter *filter; + AVBSFContext *bsf; + + filter = av_bsf_get_by_name(bsf_name); + if (!filter) + return AVERROR_BSF_NOT_FOUND; + + ret = av_bsf_alloc(filter, &bsf); + if (ret < 0) + return ret; + + if (options) { + ret = av_opt_set_dict2(bsf, options, AV_OPT_SEARCH_CHILDREN); + if (ret < 0) + goto end; + } + + ret = av_bsf_list_append(lst, bsf); + +end: + if (ret < 0) + av_bsf_free(&bsf); + + return ret; +} + +int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf) +{ + int ret = 0; + BSFListContext *ctx; + + if ((*lst)->nb_bsfs == 1) { + *bsf = (*lst)->bsfs[0]; + av_freep(&(*lst)->bsfs); + (*lst)->nb_bsfs = 0; + goto end; + } + + ret = av_bsf_alloc(&ff_list_bsf, bsf); + if (ret < 0) + return ret; + + ctx = (*bsf)->priv_data; + + ctx->bsfs = (*lst)->bsfs; + ctx->nb_bsfs = (*lst)->nb_bsfs; + +end: + av_freep(lst); + return ret; +} + +static int bsf_parse_single(const char *str, AVBSFList *bsf_lst) +{ + char *bsf_name, *bsf_options_str, *buf; + AVDictionary *bsf_options = NULL; + int ret = 0; + + if (!(buf = av_strdup(str))) + return AVERROR(ENOMEM); + + bsf_name = av_strtok(buf, "=", &bsf_options_str); + if (!bsf_name) { + ret = AVERROR(EINVAL); + goto end; + } + + if (bsf_options_str) { + ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0); + if (ret < 0) + goto end; + } + + ret = av_bsf_list_append2(bsf_lst, bsf_name, &bsf_options); + + av_dict_free(&bsf_options); +end: + av_free(buf); + return ret; +} + +int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst) +{ + AVBSFList *lst; + char *bsf_str, *buf, *dup, *saveptr; + int ret; + + if (!str) + return av_bsf_get_null_filter(bsf_lst); + + lst = av_bsf_list_alloc(); + if (!lst) + return AVERROR(ENOMEM); + + if (!(dup = buf = av_strdup(str))) { + ret = AVERROR(ENOMEM); + goto end; + } + + while (1) { + bsf_str = av_strtok(buf, ",", &saveptr); + if (!bsf_str) + break; + + ret = bsf_parse_single(bsf_str, lst); + if (ret < 0) + goto end; + + buf = NULL; + } + + ret = av_bsf_list_finalize(&lst, bsf_lst); +end: + if (ret < 0) + av_bsf_list_free(&lst); + av_free(dup); + return ret; +} + +int av_bsf_get_null_filter(AVBSFContext **bsf) +{ + return av_bsf_alloc(&ff_list_bsf, bsf); +} diff --git a/media/ffvpx/libavcodec/bsf_list.c b/media/ffvpx/libavcodec/bsf_list.c new file mode 100644 index 000000000..d31ece942 --- /dev/null +++ b/media/ffvpx/libavcodec/bsf_list.c @@ -0,0 +1,3 @@ +static const AVBitStreamFilter * const bitstream_filters[] = { + &ff_null_bsf, + NULL }; diff --git a/media/ffvpx/libavcodec/bytestream.h b/media/ffvpx/libavcodec/bytestream.h index 7c05ea6cf..7be7fc22f 100644 --- a/media/ffvpx/libavcodec/bytestream.h +++ b/media/ffvpx/libavcodec/bytestream.h @@ -94,7 +94,7 @@ DEF(unsigned int, be24, 3, AV_RB24, AV_WB24) DEF(unsigned int, be16, 2, AV_RB16, AV_WB16) DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8) -#if HAVE_BIGENDIAN +#if AV_HAVE_BIGENDIAN # define bytestream2_get_ne16 bytestream2_get_be16 # define bytestream2_get_ne24 bytestream2_get_be24 # define bytestream2_get_ne32 bytestream2_get_be32 diff --git a/media/ffvpx/libavcodec/codec_desc.c b/media/ffvpx/libavcodec/codec_desc.c index d862cc8f6..6a13bbbf0 100644 --- a/media/ffvpx/libavcodec/codec_desc.c +++ b/media/ffvpx/libavcodec/codec_desc.c @@ -169,6 +169,14 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_SVG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "svg", + .long_name = NULL_IF_CONFIG_SMALL("Scalable Vector Graphics"), + .props = AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/svg+xml"), + }, { .id = AV_CODEC_ID_SVQ1, .type = AVMEDIA_TYPE_VIDEO, @@ -520,7 +528,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "fraps", .long_name = NULL_IF_CONFIG_SMALL("Fraps"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_TRUEMOTION2, @@ -665,6 +673,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "dnxhd", .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles), }, { .id = AV_CODEC_ID_THP, @@ -1106,7 +1115,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "y41p", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_ESCAPE130, @@ -1120,56 +1129,56 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "avrp", .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_012V, .type = AVMEDIA_TYPE_VIDEO, .name = "012v", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_AVUI, .type = AVMEDIA_TYPE_VIDEO, .name = "avui", .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_AYUV, .type = AVMEDIA_TYPE_VIDEO, .name = "ayuv", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_TARGA_Y216, .type = AVMEDIA_TYPE_VIDEO, .name = "targa_y216", .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_V308, .type = AVMEDIA_TYPE_VIDEO, .name = "v308", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_V408, .type = AVMEDIA_TYPE_VIDEO, .name = "v408", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_YUV4, .type = AVMEDIA_TYPE_VIDEO, .name = "yuv4", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_AVRN, @@ -1272,7 +1281,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_HAP, .type = AVMEDIA_TYPE_VIDEO, .name = "hap", - .long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap decoder"), + .long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, { @@ -1289,6 +1298,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("Screenpresso"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_SPEEDHQ, + .type = AVMEDIA_TYPE_VIDEO, + .name = "speedhq", + .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, { .id = AV_CODEC_ID_WRAPPED_AVFRAME, .type = AVMEDIA_TYPE_VIDEO, @@ -1303,6 +1319,104 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("innoHeim/Rsupport Screen Capture Codec"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_MAGICYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "magicyuv", + .long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TRUEMOTION2RT, + .type = AVMEDIA_TYPE_VIDEO, + .name = "truemotion2rt", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CFHD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cfhd", + .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SHEERVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sheervideo", + .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_YLC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ylc", + .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PIXLET, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pixlet", + .long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FMVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fmvc", + .long_name = NULL_IF_CONFIG_SMALL("FM Screen Capture Codec"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SCPR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "scpr", + .long_name = NULL_IF_CONFIG_SMALL("ScreenPressor"), + .props = AV_CODEC_PROP_LOSSLESS | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CLEARVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "clearvideo", + .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "av1", + .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BITPACKED, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bitpacked", + .long_name = NULL_IF_CONFIG_SMALL("Bitpacked"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSCC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mscc", + .long_name = NULL_IF_CONFIG_SMALL("Mandsoft Screen Capture Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SRGC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "srgc", + .long_name = NULL_IF_CONFIG_SMALL("Screen Recorder Gold Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_GDV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "gdv", + .long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"), + .props = AV_CODEC_PROP_LOSSY, + }, /* image codecs */ { @@ -1349,6 +1463,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_FITS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("FITS (Flexible Image Transport System)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_GIF, .type = AVMEDIA_TYPE_VIDEO, @@ -1424,6 +1545,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_PSD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "psd", + .long_name = NULL_IF_CONFIG_SMALL("Photoshop PSD file"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_PTX, .type = AVMEDIA_TYPE_VIDEO, @@ -1511,6 +1639,15 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "xbm", .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xbitmap"), + }, + { + .id = AV_CODEC_ID_XPM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xpm", + .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xpixmap"), }, { .id = AV_CODEC_ID_XWD, @@ -1528,41 +1665,6 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSLESS, .mime_types= MT("image/png"), }, - { - .id = AV_CODEC_ID_CFHD, - .type = AVMEDIA_TYPE_VIDEO, - .name = "cfhd", - .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), - .props = AV_CODEC_PROP_LOSSY, - }, - { - .id = AV_CODEC_ID_TRUEMOTION2RT, - .type = AVMEDIA_TYPE_VIDEO, - .name = "truemotion2rt", - .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), - .props = AV_CODEC_PROP_LOSSY, - }, - { - .id = AV_CODEC_ID_MAGICYUV, - .type = AVMEDIA_TYPE_VIDEO, - .name = "magicyuv", - .long_name = NULL_IF_CONFIG_SMALL("MagicYUV Lossless Video"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, - }, - { - .id = AV_CODEC_ID_SHEERVIDEO, - .type = AVMEDIA_TYPE_VIDEO, - .name = "sheervideo", - .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, - }, - { - .id = AV_CODEC_ID_YLC, - .type = AVMEDIA_TYPE_VIDEO, - .name = "ylc", - .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, - }, /* various PCM "codecs" */ { @@ -1635,6 +1737,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("PCM signed 32-bit big-endian"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_PCM_S64LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s64le", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 64-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S64BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s64be", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 64-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_PCM_U32LE, .type = AVMEDIA_TYPE_AUDIO, @@ -1726,6 +1842,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("PCM signed 20|24-bit big-endian"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_PCM_F16LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f16le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 16.8 floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F24LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f24le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_PCM_F32BE, .type = AVMEDIA_TYPE_AUDIO, @@ -2133,6 +2263,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("DPCM Squareroot-Delta-Exact"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_GREMLIN_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "gremlin_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Gremlin"), + .props = AV_CODEC_PROP_LOSSY, + }, /* audio codecs */ { @@ -2226,7 +2363,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "flac", .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_MP3ADU, @@ -2254,7 +2391,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "alac", .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_WESTWOOD_SND1, @@ -2281,7 +2418,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_COOK, .type = AVMEDIA_TYPE_AUDIO, .name = "cook", - .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Goanna (RealAudio G2)"), + .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"), .props = AV_CODEC_PROP_LOSSY, }, { @@ -2296,7 +2433,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tta", .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_SMACKAUDIO, @@ -2317,7 +2454,8 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "wavpack", .long_name = NULL_IF_CONFIG_SMALL("WavPack"), - .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | + AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_DSICINAUDIO, @@ -2426,6 +2564,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_ATRAC3PAL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3pal", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ AL (Adaptive TRansform Acoustic Coding 3+ Advanced Lossless)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ATRAC3AL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3al", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 AL (Adaptive TRansform Acoustic Coding 3 Advanced Lossless)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_EAC3, .type = AVMEDIA_TYPE_AUDIO, @@ -2525,6 +2677,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("Digital Speech Standard - Standard Play mode (DSS SP)"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_DOLBY_E, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dolby_e", + .long_name = NULL_IF_CONFIG_SMALL("Dolby E"), + .props = AV_CODEC_PROP_LOSSY, + }, { .id = AV_CODEC_ID_G729, .type = AVMEDIA_TYPE_AUDIO, @@ -2611,7 +2770,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tak", .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_METASOUND, @@ -2949,6 +3108,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, + { + .id = AV_CODEC_ID_SCTE_35, + .type = AVMEDIA_TYPE_DATA, + .name = "scte_35", + .long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), + }, /* deprecated codec ids */ }; diff --git a/media/ffvpx/libavcodec/dct.h b/media/ffvpx/libavcodec/dct.h index 05297ba9d..0a03e256d 100644 --- a/media/ffvpx/libavcodec/dct.h +++ b/media/ffvpx/libavcodec/dct.h @@ -24,6 +24,7 @@ #if !defined(AVCODEC_DCT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT) #define AVCODEC_DCT_H +#include #include #include "rdft.h" @@ -62,7 +63,7 @@ void ff_j_rev_dct(int16_t *data); void ff_j_rev_dct4(int16_t *data); void ff_j_rev_dct2(int16_t *data); void ff_j_rev_dct1(int16_t *data); -void ff_jref_idct_put(uint8_t *dest, int line_size, int16_t *block); -void ff_jref_idct_add(uint8_t *dest, int line_size, int16_t *block); +void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); #endif /* AVCODEC_DCT_H */ diff --git a/media/ffvpx/libavcodec/decode.c b/media/ffvpx/libavcodec/decode.c new file mode 100644 index 000000000..fb1824be1 --- /dev/null +++ b/media/ffvpx/libavcodec/decode.c @@ -0,0 +1,1761 @@ +/* + * generic decoding-related code + * + * 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 "config.h" + +#if CONFIG_ICONV +# include +#endif + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intmath.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "decode.h" +#include "internal.h" +#include "thread.h" + +static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) +{ + int size = 0, ret; + const uint8_t *data; + uint32_t flags; + int64_t val; + + data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); + if (!data) + return 0; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + ret = AVERROR(EINVAL); + goto fail2; + } + + if (size < 4) + goto fail; + + flags = bytestream_get_le32(&data); + size -= 4; + + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; + val = bytestream_get_le32(&data); + if (val <= 0 || val > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid channel count"); + ret = AVERROR_INVALIDDATA; + goto fail2; + } + avctx->channels = val; + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { + if (size < 8) + goto fail; + avctx->channel_layout = bytestream_get_le64(&data); + size -= 8; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; + val = bytestream_get_le32(&data); + if (val <= 0 || val > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); + ret = AVERROR_INVALIDDATA; + goto fail2; + } + avctx->sample_rate = val; + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { + if (size < 8) + goto fail; + avctx->width = bytestream_get_le32(&data); + avctx->height = bytestream_get_le32(&data); + size -= 8; + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto fail2; + } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + ret = AVERROR_INVALIDDATA; +fail2: + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } + return 0; +} + +static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +{ + int ret = 0; + + av_packet_unref(avci->last_pkt_props); + if (pkt) { + ret = av_packet_copy_props(avci->last_pkt_props, pkt); + if (!ret) + avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_init_buffer_info(). + } + return ret; +} + +static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) +{ + int ret; + + /* move the original frame to our backup */ + av_frame_unref(avci->to_free); + av_frame_move_ref(avci->to_free, frame); + + /* now copy everything except the AVBufferRefs back + * note that we make a COPY of the side data, so calling av_frame_free() on + * the caller's frame will work properly */ + ret = av_frame_copy_props(frame, avci->to_free); + if (ret < 0) + return ret; + + memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); + memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); + if (avci->to_free->extended_data != avci->to_free->data) { + int planes = avci->to_free->channels; + int size = planes * sizeof(*frame->extended_data); + + if (!size) { + av_frame_unref(frame); + return AVERROR_BUG; + } + + frame->extended_data = av_malloc(size); + if (!frame->extended_data) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + memcpy(frame->extended_data, avci->to_free->extended_data, + size); + } else + frame->extended_data = frame->data; + + frame->format = avci->to_free->format; + frame->width = avci->to_free->width; + frame->height = avci->to_free->height; + frame->channel_layout = avci->to_free->channel_layout; + frame->nb_samples = avci->to_free->nb_samples; + frame->channels = avci->to_free->channels; + + return 0; +} + +static int bsfs_init(AVCodecContext *avctx) +{ + AVCodecInternal *avci = avctx->internal; + DecodeFilterContext *s = &avci->filter; + const char *bsfs_str; + int ret; + + if (s->nb_bsfs) + return 0; + + bsfs_str = avctx->codec->bsfs ? avctx->codec->bsfs : "null"; + while (bsfs_str && *bsfs_str) { + AVBSFContext **tmp; + const AVBitStreamFilter *filter; + char *bsf; + + bsf = av_get_token(&bsfs_str, ","); + if (!bsf) { + ret = AVERROR(ENOMEM); + goto fail; + } + + filter = av_bsf_get_by_name(bsf); + if (!filter) { + av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s " + "requested by a decoder. This is a bug, please report it.\n", + bsf); + ret = AVERROR_BUG; + av_freep(&bsf); + goto fail; + } + av_freep(&bsf); + + tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto fail; + } + s->bsfs = tmp; + s->nb_bsfs++; + + ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + + if (s->nb_bsfs == 1) { + /* We do not currently have an API for passing the input timebase into decoders, + * but no filters used here should actually need it. + * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ + s->bsfs[s->nb_bsfs - 1]->time_base_in = (AVRational){ 1, 90000 }; + ret = avcodec_parameters_from_context(s->bsfs[s->nb_bsfs - 1]->par_in, + avctx); + } else { + s->bsfs[s->nb_bsfs - 1]->time_base_in = s->bsfs[s->nb_bsfs - 2]->time_base_out; + ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, + s->bsfs[s->nb_bsfs - 2]->par_out); + } + if (ret < 0) + goto fail; + + ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + } + + return 0; +fail: + ff_decode_bsfs_uninit(avctx); + return ret; +} + +/* try to get one output packet from the filter chain */ +static int bsfs_poll(AVCodecContext *avctx, AVPacket *pkt) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int idx, ret; + + /* start with the last filter in the chain */ + idx = s->nb_bsfs - 1; + while (idx >= 0) { + /* request a packet from the currently selected filter */ + ret = av_bsf_receive_packet(s->bsfs[idx], pkt); + if (ret == AVERROR(EAGAIN)) { + /* no packets available, try the next filter up the chain */ + ret = 0; + idx--; + continue; + } else if (ret < 0 && ret != AVERROR_EOF) { + return ret; + } + + /* got a packet or EOF -- pass it to the caller or to the next filter + * down the chain */ + if (idx == s->nb_bsfs - 1) { + return ret; + } else { + idx++; + ret = av_bsf_send_packet(s->bsfs[idx], ret < 0 ? NULL : pkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error pre-processing a packet before decoding\n"); + av_packet_unref(pkt); + return ret; + } + } + } + + return AVERROR(EAGAIN); +} + +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (avci->draining) + return AVERROR_EOF; + + ret = bsfs_poll(avctx, pkt); + if (ret == AVERROR_EOF) + avci->draining = 1; + if (ret < 0) + return ret; + + ret = extract_packet_props(avctx->internal, pkt); + if (ret < 0) + goto finish; + + ret = apply_param_change(avctx, pkt); + if (ret < 0) + goto finish; + + if (avctx->codec->receive_frame) + avci->compat_decode_consumed += pkt->size; + + return 0; +finish: + av_packet_unref(pkt); + return ret; +} + +/** + * Attempt to guess proper monotonic timestamps for decoded video frames + * which might have incorrect times. Input timestamps may wrap around, in + * which case the output will as well. + * + * @param pts the pts field of the decoded AVPacket, as passed through + * AVFrame.pts + * @param dts the dts field of the decoded AVPacket + * @return one of the input values, may be AV_NOPTS_VALUE + */ +static int64_t guess_correct_pts(AVCodecContext *ctx, + int64_t reordered_pts, int64_t dts) +{ + int64_t pts = AV_NOPTS_VALUE; + + if (dts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; + ctx->pts_correction_last_dts = dts; + } else if (reordered_pts != AV_NOPTS_VALUE) + ctx->pts_correction_last_dts = reordered_pts; + + if (reordered_pts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; + ctx->pts_correction_last_pts = reordered_pts; + } else if(dts != AV_NOPTS_VALUE) + ctx->pts_correction_last_pts = dts; + + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) + && reordered_pts != AV_NOPTS_VALUE) + pts = reordered_pts; + else + pts = dts; + + return pts; +} + +/* + * The core of the receive_frame_wrapper for the decoders implementing + * the simple API. Certain decoders might consume partial packets without + * returning any output, so this function needs to be called in a loop until it + * returns EAGAIN. + **/ +static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + DecodeSimpleContext *ds = &avci->ds; + AVPacket *pkt = ds->in_pkt; + // copy to ensure we do not change pkt + AVPacket tmp; + int got_frame, actual_got_frame, did_split; + int ret; + + if (!pkt->data && !avci->draining) { + av_packet_unref(pkt); + ret = ff_decode_get_packet(avctx, pkt); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + // Some codecs (at least wma lossless) will crash when feeding drain packets + // after EOF was signaled. + if (avci->draining_done) + return AVERROR_EOF; + + if (!pkt->data && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + avctx->active_thread_type & FF_THREAD_FRAME)) + return AVERROR_EOF; + + tmp = *pkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS + did_split = avci->compat_decode_partial_size ? + ff_packet_split_and_drop_side_data(&tmp) : + av_packet_split_side_data(&tmp); + + if (did_split) { + ret = extract_packet_props(avctx->internal, &tmp); + if (ret < 0) + return ret; + + ret = apply_param_change(avctx, &tmp); + if (ret < 0) + return ret; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + got_frame = 0; + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { + ret = ff_thread_decode_frame(avctx, frame, &got_frame, &tmp); + } else { + ret = avctx->codec->decode(avctx, frame, &got_frame, &tmp); + + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + frame->pkt_dts = pkt->dts; + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if(!avctx->has_b_frames) + frame->pkt_pos = pkt->pos; + //FIXME these should be under if(!avctx->has_b_frames) + /* get_buffer is supposed to set frame parameters */ + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (!frame->width) frame->width = avctx->width; + if (!frame->height) frame->height = avctx->height; + if (frame->format == AV_PIX_FMT_NONE) frame->format = avctx->pix_fmt; + } + } + } + emms_c(); + actual_got_frame = got_frame; + + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if (frame->flags & AV_FRAME_FLAG_DISCARD) + got_frame = 0; + if (got_frame) + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + uint8_t *side; + int side_size; + uint32_t discard_padding = 0; + uint8_t skip_reason = 0; + uint8_t discard_reason = 0; + + if (ret >= 0 && got_frame) { + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + if (frame->format == AV_SAMPLE_FMT_NONE) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) + frame->channel_layout = avctx->channel_layout; + if (!frame->channels) + frame->channels = avctx->channels; + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + } + + side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + if(side && side_size>=10) { + avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier; + discard_padding = AV_RL32(side + 4); + av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", + avctx->internal->skip_samples, (int)discard_padding); + skip_reason = AV_RL8(side + 8); + discard_reason = AV_RL8(side + 9); + } + + if ((frame->flags & AV_FRAME_FLAG_DISCARD) && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + avctx->internal->skip_samples = FFMAX(0, avctx->internal->skip_samples - frame->nb_samples); + got_frame = 0; + } + + if (avctx->internal->skip_samples > 0 && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + if(frame->nb_samples <= avctx->internal->skip_samples){ + got_frame = 0; + avctx->internal->skip_samples -= frame->nb_samples; + av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", + avctx->internal->skip_samples); + } else { + av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples, + frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format); + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + if(frame->pts!=AV_NOPTS_VALUE) + frame->pts += diff_ts; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + if(frame->pkt_pts!=AV_NOPTS_VALUE) + frame->pkt_pts += diff_ts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if(frame->pkt_dts!=AV_NOPTS_VALUE) + frame->pkt_dts += diff_ts; + if (frame->pkt_duration >= diff_ts) + frame->pkt_duration -= diff_ts; + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", + avctx->internal->skip_samples, frame->nb_samples); + frame->nb_samples -= avctx->internal->skip_samples; + avctx->internal->skip_samples = 0; + } + } + + if (discard_padding > 0 && discard_padding <= frame->nb_samples && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + if (discard_padding == frame->nb_samples) { + got_frame = 0; + } else { + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + frame->pkt_duration = diff_ts; + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", + (int)discard_padding, frame->nb_samples); + frame->nb_samples -= discard_padding; + } + } + + if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && got_frame) { + 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; + } + } + } +#if FF_API_MERGE_SD + if (did_split) { + av_packet_free_side_data(&tmp); + if(ret == tmp.size) + ret = pkt->size; + } +#endif + + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO && + !avci->showed_multi_packet_warning && + ret >= 0 && ret != pkt->size && !(avctx->codec->capabilities & AV_CODEC_CAP_SUBFRAMES)) { + av_log(avctx, AV_LOG_WARNING, "Multiple frames in a packet.\n"); + avci->showed_multi_packet_warning = 1; + } + + if (!got_frame) + av_frame_unref(frame); + + if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED)) + ret = pkt->size; + +#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 + + /* do not stop draining when actual_got_frame != 0 or ret < 0 */ + /* got_frame == 0 but actual_got_frame != 0 when frame is discarded */ + if (avctx->internal->draining && !actual_got_frame) { + if (ret < 0) { + /* prevent infinite loop if a decoder wrongly always return error on draining */ + /* reasonable nb_errors_max = maximum b frames + thread count */ + int nb_errors_max = 20 + (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME ? + avctx->thread_count : 1); + + if (avci->nb_draining_errors++ >= nb_errors_max) { + av_log(avctx, AV_LOG_ERROR, "Too many errors when draining, this is a bug. " + "Stop draining and force EOF.\n"); + avci->draining_done = 1; + ret = AVERROR_BUG; + } + } else { + avci->draining_done = 1; + } + } + + avci->compat_decode_consumed += ret; + + if (ret >= pkt->size || ret < 0) { + av_packet_unref(pkt); + } else { + int consumed = ret; + + pkt->data += consumed; + pkt->size -= consumed; + avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + avci->last_pkt_props->pts = AV_NOPTS_VALUE; + avci->last_pkt_props->dts = AV_NOPTS_VALUE; + } + + if (got_frame) + av_assert0(frame->buf[0]); + + return ret < 0 ? ret : 0; +} + +static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + int ret; + + while (!frame->buf[0]) { + ret = decode_simple_internal(avctx, frame); + if (ret < 0) + return ret; + } + + return 0; +} + +static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + av_assert0(!frame->buf[0]); + + if (avctx->codec->receive_frame) + ret = avctx->codec->receive_frame(avctx, frame); + else + ret = decode_simple_receive_frame(avctx, frame); + + if (ret == AVERROR_EOF) + avci->draining_done = 1; + + return ret; +} + +int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->internal->draining) + return AVERROR_EOF; + + if (avpkt && !avpkt->size && avpkt->data) + return AVERROR(EINVAL); + + ret = bsfs_init(avctx); + if (ret < 0) + return ret; + + av_packet_unref(avci->buffer_pkt); + if (avpkt && (avpkt->data || avpkt->side_data_elems)) { + ret = av_packet_ref(avci->buffer_pkt, avpkt); + if (ret < 0) + return ret; + } + + ret = av_bsf_send_packet(avci->filter.bsfs[0], avci->buffer_pkt); + if (ret < 0) { + av_packet_unref(avci->buffer_pkt); + return ret; + } + + if (!avci->buffer_frame->buf[0]) { + ret = decode_receive_frame_internal(avctx, avci->buffer_frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } + + return 0; +} + +static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) +{ + /* make sure we are noisy about decoders returning invalid cropping data */ + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) { + av_log(avctx, AV_LOG_WARNING, + "Invalid cropping information set by a decoder: " + "%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER" " + "(frame size %dx%d). This is a bug, please report it\n", + frame->crop_left, frame->crop_right, frame->crop_top, frame->crop_bottom, + frame->width, frame->height); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + return 0; + } + + if (!avctx->apply_cropping) + return 0; + + return av_frame_apply_cropping(frame, avctx->flags & AV_CODEC_FLAG_UNALIGNED ? + AV_FRAME_CROP_UNALIGNED : 0); +} + +int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + av_frame_unref(frame); + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + ret = bsfs_init(avctx); + if (ret < 0) + return ret; + + if (avci->buffer_frame->buf[0]) { + av_frame_move_ref(frame, avci->buffer_frame); + } else { + ret = decode_receive_frame_internal(avctx, frame); + if (ret < 0) + return ret; + } + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = apply_cropping(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + + avctx->frame_number++; + + return 0; +} + +static int compat_decode(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, const AVPacket *pkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret = 0; + + av_assert0(avci->compat_decode_consumed == 0); + + if (avci->draining_done && pkt && pkt->size != 0) { + av_log(avctx, AV_LOG_WARNING, "Got unexpected packet after EOF\n"); + avcodec_flush_buffers(avctx); + } + + *got_frame = 0; + avci->compat_decode = 1; + + if (avci->compat_decode_partial_size > 0 && + avci->compat_decode_partial_size != pkt->size) { + av_log(avctx, AV_LOG_ERROR, + "Got unexpected packet size after a partial decode\n"); + ret = AVERROR(EINVAL); + goto finish; + } + + if (!avci->compat_decode_partial_size) { + ret = avcodec_send_packet(avctx, pkt); + if (ret == AVERROR_EOF) + ret = 0; + else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not + * ever happen */ + ret = AVERROR_BUG; + goto finish; + } else if (ret < 0) + goto finish; + } + + while (ret >= 0) { + ret = avcodec_receive_frame(avctx, frame); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + goto finish; + } + + if (frame != avci->compat_decode_frame) { + if (!avctx->refcounted_frames) { + ret = unrefcount_frame(avci, frame); + if (ret < 0) + goto finish; + } + + *got_frame = 1; + frame = avci->compat_decode_frame; + } else { + if (!avci->compat_decode_warned) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_decode_* " + "API cannot return all the frames for this decoder. " + "Some frames will be dropped. Update your code to the " + "new decoding API to fix this.\n"); + avci->compat_decode_warned = 1; + } + } + + if (avci->draining || (!avctx->codec->bsfs && avci->compat_decode_consumed < pkt->size)) + break; + } + +finish: + if (ret == 0) { + /* if there are any bsfs then assume full packet is always consumed */ + if (avctx->codec->bsfs) + ret = pkt->size; + else + ret = FFMIN(avci->compat_decode_consumed, pkt->size); + } + avci->compat_decode_consumed = 0; + avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0; + + return ret; +} + +int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const AVPacket *avpkt) +{ + return compat_decode(avctx, picture, got_picture_ptr, avpkt); +} + +int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, + AVFrame *frame, + int *got_frame_ptr, + const AVPacket *avpkt) +{ + return compat_decode(avctx, frame, got_frame_ptr, avpkt); +} + +static void get_subtitle_defaults(AVSubtitle *sub) +{ + memset(sub, 0, sizeof(*sub)); + sub->pts = AV_NOPTS_VALUE; +} + +#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ +static int recode_subtitle(AVCodecContext *avctx, + AVPacket *outpkt, const AVPacket *inpkt) +{ +#if CONFIG_ICONV + iconv_t cd = (iconv_t)-1; + int ret = 0; + char *inb, *outb; + size_t inl, outl; + AVPacket tmp; +#endif + + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) + return 0; + +#if CONFIG_ICONV + cd = iconv_open("UTF-8", avctx->sub_charenc); + av_assert0(cd != (iconv_t)-1); + + inb = inpkt->data; + inl = inpkt->size; + + if (inl >= INT_MAX / UTF8_MAX_BYTES - AV_INPUT_BUFFER_PADDING_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES); + if (ret < 0) + goto end; + outpkt->buf = tmp.buf; + outpkt->data = tmp.data; + outpkt->size = tmp.size; + outb = outpkt->data; + outl = outpkt->size; + + 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_packet_unref(&tmp); + goto end; + } + outpkt->size -= outl; + memset(outpkt->data + outpkt->size, 0, outl); + +end: + if (cd != (iconv_t)-1) + iconv_close(cd); + return ret; +#else + av_log(avctx, AV_LOG_ERROR, "requesting subtitles recoding without iconv"); + return AVERROR(EINVAL); +#endif +} + +static int utf8_check(const uint8_t *str) +{ + const uint8_t *byte; + uint32_t codepoint, min; + + while (*str) { + byte = str; + GET_UTF8(codepoint, *(byte++), return 0;); + min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : + 1 << (5 * (byte - str) - 4); + if (codepoint < min || codepoint >= 0x110000 || + codepoint == 0xFFFE /* BOM */ || + codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) + return 0; + str = byte; + } + return 1; +} + +#if FF_API_ASS_TIMING +static void insert_ts(AVBPrint *buf, int ts) +{ + if (ts == -1) { + av_bprintf(buf, "9:59:59.99,"); + } else { + int h, m, s; + + h = ts/360000; ts -= 360000*h; + m = ts/ 6000; ts -= 6000*m; + s = ts/ 100; ts -= 100*s; + av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts); + } +} + +static int convert_sub_to_old_ass_form(AVSubtitle *sub, const AVPacket *pkt, AVRational tb) +{ + int i; + AVBPrint buf; + + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + + for (i = 0; i < sub->num_rects; i++) { + char *final_dialog; + const char *dialog; + AVSubtitleRect *rect = sub->rects[i]; + int ts_start, ts_duration = -1; + long int layer; + + if (rect->type != SUBTITLE_ASS || !strncmp(rect->ass, "Dialogue: ", 10)) + continue; + + av_bprint_clear(&buf); + + /* skip ReadOrder */ + dialog = strchr(rect->ass, ','); + if (!dialog) + continue; + dialog++; + + /* extract Layer or Marked */ + layer = strtol(dialog, (char**)&dialog, 10); + if (*dialog != ',') + continue; + dialog++; + + /* rescale timing to ASS time base (ms) */ + ts_start = av_rescale_q(pkt->pts, tb, av_make_q(1, 100)); + if (pkt->duration != -1) + ts_duration = av_rescale_q(pkt->duration, tb, av_make_q(1, 100)); + sub->end_display_time = FFMAX(sub->end_display_time, 10 * ts_duration); + + /* construct ASS (standalone file form with timestamps) string */ + av_bprintf(&buf, "Dialogue: %ld,", layer); + insert_ts(&buf, ts_start); + insert_ts(&buf, ts_duration == -1 ? -1 : ts_start + ts_duration); + av_bprintf(&buf, "%s\r\n", dialog); + + final_dialog = av_strdup(buf.str); + if (!av_bprint_is_complete(&buf) || !final_dialog) { + av_freep(&final_dialog); + av_bprint_finalize(&buf, NULL); + return AVERROR(ENOMEM); + } + av_freep(&rect->ass); + rect->ass = final_dialog; + } + + av_bprint_finalize(&buf, NULL); + return 0; +} +#endif + +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt) +{ + int i, ret = 0; + AVCodecInternal *avci = avctx->internal; + + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if (!avctx->codec) + return AVERROR(EINVAL); + if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { + av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); + return AVERROR(EINVAL); + } + + *got_sub_ptr = 0; + get_subtitle_defaults(sub); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { + AVPacket pkt_recoded; + AVPacket tmp = *avpkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS + int did_split = avci->compat_decode_partial_size ? + ff_packet_split_and_drop_side_data(&tmp) : + av_packet_split_side_data(&tmp); + //apply_param_change(avctx, &tmp); + + if (did_split) { + /* FFMIN() prevents overflow in case the packet wasn't allocated with + * proper padding. + * If the side data is smaller than the buffer padding size, the + * remaining bytes should have already been filled with zeros by the + * original packet allocation anyway. */ + memset(tmp.data + tmp.size, 0, + FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE)); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + pkt_recoded = tmp; + ret = recode_subtitle(avctx, &pkt_recoded, &tmp); + if (ret < 0) { + *got_sub_ptr = 0; + } else { + ret = extract_packet_props(avctx->internal, &pkt_recoded); + if (ret < 0) + return ret; + + if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) + sub->pts = av_rescale_q(avpkt->pts, + avctx->pkt_timebase, AV_TIME_BASE_Q); + ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); + av_assert1((ret >= 0) >= !!*got_sub_ptr && + !!*got_sub_ptr >= !!sub->num_rects); + +#if FF_API_ASS_TIMING + if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS + && *got_sub_ptr && sub->num_rects) { + const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase + : avctx->time_base; + int err = convert_sub_to_old_ass_form(sub, avpkt, tb); + if (err < 0) + ret = err; + } +#endif + + if (sub->num_rects && !sub->end_display_time && avpkt->duration && + avctx->pkt_timebase.num) { + AVRational ms = { 1, 1000 }; + sub->end_display_time = av_rescale_q(avpkt->duration, + avctx->pkt_timebase, ms); + } + + if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) + sub->format = 0; + else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) + sub->format = 1; + + for (i = 0; i < sub->num_rects; i++) { + if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid UTF-8 in decoded subtitles text; " + "maybe missing -sub_charenc option\n"); + avsubtitle_free(sub); + ret = AVERROR_INVALIDDATA; + break; + } + } + + if (tmp.data != pkt_recoded.data) { // did we recode? + /* prevent from destroying side data from original packet */ + pkt_recoded.side_data = NULL; + pkt_recoded.side_data_elems = 0; + + av_packet_unref(&pkt_recoded); + } + } + +#if FF_API_MERGE_SD + if (did_split) { + av_packet_free_side_data(&tmp); + if(ret == tmp.size) + ret = avpkt->size; + } +#endif + + if (*got_sub_ptr) + avctx->frame_number++; + } + + return ret; +} + +static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; +} + +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) +{ + while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) + ++fmt; + return fmt[0]; +} + +static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, + enum AVPixelFormat pix_fmt) +{ + AVHWAccel *hwaccel = NULL; + + while ((hwaccel = av_hwaccel_next(hwaccel))) + if (hwaccel->id == codec_id + && hwaccel->pix_fmt == pix_fmt) + return hwaccel; + 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->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL && + avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", + hwa->name); + return AVERROR_PATCHWELCOME; + } + + 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); + } + + avctx->hwaccel = hwa; + if (hwa->init) { + ret = hwa->init(avctx); + if (ret < 0) { + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + return ret; + } + } + + return 0; +} + +int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + const AVPixFmtDescriptor *desc; + enum AVPixelFormat *choices; + enum AVPixelFormat ret; + unsigned n = 0; + + while (fmt[n] != AV_PIX_FMT_NONE) + ++n; + + av_assert0(n >= 1); + avctx->sw_pix_fmt = fmt[n - 1]; + av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); + + choices = av_malloc_array(n + 1, sizeof(*choices)); + if (!choices) + return AV_PIX_FMT_NONE; + + memcpy(choices, fmt, (n + 1) * sizeof(*choices)); + + for (;;) { + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + + av_buffer_unref(&avctx->hw_frames_ctx); + + ret = avctx->get_format(avctx, choices); + + desc = av_pix_fmt_desc_get(ret); + if (!desc) { + ret = AV_PIX_FMT_NONE; + break; + } + + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + break; +#if FF_API_CAP_VDPAU + if (avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU) + break; +#endif + + if (avctx->hw_frames_ctx) { + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (hw_frames_ctx->format != ret) { + av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " + "does not match the format of provided AVHWFramesContext\n"); + ret = AV_PIX_FMT_NONE; + 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; +} + +static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int i, ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: { + uint8_t *data[4]; + int linesize[4]; + int size[4] = { 0 }; + int w = frame->width; + int h = frame->height; + int tmpsize, unaligned; + + if (pool->format == frame->format && + pool->width == frame->width && pool->height == frame->height) + return 0; + + avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); + + do { + // NOTE: do not align linesizes individually, this breaks e.g. assumptions + // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 + ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); + if (ret < 0) + return ret; + // increase alignment of w for next try (rhs gives the lowest bit set in w) + w += w & ~(w - 1); + + unaligned = 0; + for (i = 0; i < 4; i++) + unaligned |= linesize[i] % pool->stride_align[i]; + } while (unaligned); + + tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, + NULL, linesize); + if (tmpsize < 0) + return -1; + + for (i = 0; i < 3 && data[i + 1]; i++) + size[i] = data[i + 1] - data[i]; + size[i] = tmpsize - (data[i] - data[0]); + + for (i = 0; i < 4; i++) { + av_buffer_pool_uninit(&pool->pools[i]); + pool->linesize[i] = linesize[i]; + if (size[i]) { + pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, + CONFIG_MEMORY_POISONING ? + NULL : + av_buffer_allocz); + if (!pool->pools[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + pool->format = frame->format; + pool->width = frame->width; + pool->height = frame->height; + + break; + } + case AVMEDIA_TYPE_AUDIO: { + int ch = frame->channels; //av_get_channel_layout_nb_channels(frame->channel_layout); + int planar = av_sample_fmt_is_planar(frame->format); + int planes = planar ? ch : 1; + + if (pool->format == frame->format && pool->planes == planes && + pool->channels == ch && frame->nb_samples == pool->samples) + return 0; + + av_buffer_pool_uninit(&pool->pools[0]); + ret = av_samples_get_buffer_size(&pool->linesize[0], ch, + frame->nb_samples, frame->format, 0); + if (ret < 0) + goto fail; + + pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); + if (!pool->pools[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + pool->format = frame->format; + pool->planes = planes; + pool->channels = ch; + pool->samples = frame->nb_samples; + break; + } + default: av_assert0(0); + } + return 0; +fail: + for (i = 0; i < 4; i++) + av_buffer_pool_uninit(&pool->pools[i]); + pool->format = -1; + pool->planes = pool->channels = pool->samples = 0; + pool->width = pool->height = 0; + return ret; +} + +static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int planes = pool->planes; + int i; + + frame->linesize[0] = pool->linesize[0]; + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_mallocz_array(planes, sizeof(*frame->extended_data)); + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + } else { + frame->extended_data = frame->data; + av_assert0(frame->nb_extended_buf == 0); + } + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->buf[i]) + goto fail; + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->extended_buf[i]) + goto fail; + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + + if (avctx->debug & FF_DEBUG_BUFFERS) + av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); + + return 0; +fail: + av_frame_unref(frame); + return AVERROR(ENOMEM); +} + +static int video_get_buffer(AVCodecContext *s, AVFrame *pic) +{ + FramePool *pool = s->internal->pool; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); + int i; + + if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { + av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); + return -1; + } + + if (!desc) { + av_log(s, AV_LOG_ERROR, + "Unable to get pixel format descriptor for format %s\n", + av_get_pix_fmt_name(pic->format)); + return AVERROR(EINVAL); + } + + memset(pic->data, 0, sizeof(pic->data)); + pic->extended_data = pic->data; + + for (i = 0; i < 4 && pool->pools[i]; i++) { + pic->linesize[i] = pool->linesize[i]; + + pic->buf[i] = av_buffer_pool_get(pool->pools[i]); + if (!pic->buf[i]) + goto fail; + + pic->data[i] = pic->buf[i]->data; + } + for (; i < AV_NUM_DATA_POINTERS; i++) { + pic->data[i] = NULL; + pic->linesize[i] = 0; + } + if (desc->flags & AV_PIX_FMT_FLAG_PAL || + desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); + + if (s->debug & FF_DEBUG_BUFFERS) + av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); + + return 0; +fail: + av_frame_unref(pic); + return AVERROR(ENOMEM); +} + +int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret; + + if (avctx->hw_frames_ctx) { + ret = av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); + frame->width = avctx->coded_width; + frame->height = avctx->coded_height; + return ret; + } + + if ((ret = update_frame_pool(avctx, frame)) < 0) + return ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return video_get_buffer(avctx, frame); + case AVMEDIA_TYPE_AUDIO: + return audio_get_buffer(avctx, frame); + default: + return -1; + } +} + +static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) +{ + int size; + const uint8_t *side_metadata; + + AVDictionary **frame_md = &frame->metadata; + + side_metadata = av_packet_get_side_data(avpkt, + AV_PKT_DATA_STRINGS_METADATA, &size); + return av_packet_unpack_dictionary(side_metadata, size, frame_md); +} + +int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) +{ + const AVPacket *pkt = avctx->internal->last_pkt_props; + 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_SPHERICAL, AV_FRAME_DATA_SPHERICAL }, + { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, + { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, + { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, + { AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, + { AV_PKT_DATA_A53_CC, AV_FRAME_DATA_A53_CC }, + }; + + if (pkt) { + frame->pts = pkt->pts; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pts = pkt->pts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->pkt_pos = pkt->pos; + frame->pkt_duration = pkt->duration; + frame->pkt_size = pkt->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); + } + } + add_metadata_from_side_data(pkt, frame); + + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + frame->flags |= AV_FRAME_FLAG_DISCARD; + } else { + frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); + } + } + frame->reordered_opaque = avctx->reordered_opaque; + + if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED) + frame->color_primaries = avctx->color_primaries; + if (frame->color_trc == AVCOL_TRC_UNSPECIFIED) + frame->color_trc = avctx->color_trc; + if (frame->colorspace == AVCOL_SPC_UNSPECIFIED) + frame->colorspace = avctx->colorspace; + if (frame->color_range == AVCOL_RANGE_UNSPECIFIED) + frame->color_range = avctx->color_range; + if (frame->chroma_location == AVCHROMA_LOC_UNSPECIFIED) + frame->chroma_location = avctx->chroma_sample_location; + + switch (avctx->codec->type) { + case AVMEDIA_TYPE_VIDEO: + frame->format = avctx->pix_fmt; + if (!frame->sample_aspect_ratio.num) + frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + + if (frame->width && frame->height && + av_image_check_sar(frame->width, frame->height, + frame->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + frame->sample_aspect_ratio.num, + frame->sample_aspect_ratio.den); + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + + break; + case AVMEDIA_TYPE_AUDIO: + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + if (frame->format < 0) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) { + if (avctx->channel_layout) { + if (av_get_channel_layout_nb_channels(avctx->channel_layout) != + avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " + "configuration.\n"); + return AVERROR(EINVAL); + } + + frame->channel_layout = avctx->channel_layout; + } else { + if (avctx->channels > FF_SANE_NB_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", + avctx->channels); + return AVERROR(ENOSYS); + } + } + } + frame->channels = avctx->channels; + break; + } + return 0; +} + +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) +{ + return ff_init_buffer_info(avctx, frame); +} + +static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) +{ + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + int i; + int num_planes = av_pix_fmt_count_planes(frame->format); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int flags = desc ? desc->flags : 0; + if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) + num_planes = 2; + for (i = 0; i < num_planes; i++) { + av_assert0(frame->data[i]); + } + // For now do not enforce anything for palette of pseudopal formats + if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) + num_planes = 2; + // For formats without data like hwaccel allow unused pointers to be non-NULL. + for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) { + if (frame->data[i]) + av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n"); + frame->data[i] = NULL; + } + } +} + +static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + const AVHWAccel *hwaccel = avctx->hwaccel; + int override_dimensions = 1; + int ret; + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + if ((ret = av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { + av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); + return AVERROR(EINVAL); + } + + if (frame->width <= 0 || frame->height <= 0) { + frame->width = FFMAX(avctx->width, AV_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); + frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); + override_dimensions = 0; + } + + if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) { + av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n"); + return AVERROR(EINVAL); + } + } + ret = ff_decode_frame_props(avctx, frame); + if (ret < 0) + return ret; + + if (hwaccel) { + if (hwaccel->alloc_frame) { + ret = hwaccel->alloc_frame(avctx, frame); + goto end; + } + } else + avctx->sw_pix_fmt = avctx->pix_fmt; + + ret = avctx->get_buffer2(avctx, frame, flags); + if (ret >= 0) + validate_avframe_allocation(avctx, frame); + +end: + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && + !(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { + frame->width = avctx->width; + frame->height = avctx->height; + } + + return ret; +} + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret = get_buffer_internal(avctx, frame, flags); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + frame->width = frame->height = 0; + } + return ret; +} + +static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVFrame *tmp; + int ret; + + av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); + + if (frame->data[0] && (frame->width != avctx->width || frame->height != avctx->height || frame->format != avctx->pix_fmt)) { + av_log(avctx, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n", + frame->width, frame->height, av_get_pix_fmt_name(frame->format), avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); + av_frame_unref(frame); + } + + ff_init_buffer_info(avctx, frame); + + if (!frame->data[0]) + return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + + if (av_frame_is_writable(frame)) + return ff_decode_frame_props(avctx, frame); + + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + av_frame_move_ref(tmp, frame); + + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) { + av_frame_free(&tmp); + return ret; + } + + av_frame_copy(frame, tmp); + av_frame_free(&tmp); + + return 0; +} + +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + int ret = reget_buffer_internal(avctx, frame); + if (ret < 0) + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return ret; +} + +void avcodec_flush_buffers(AVCodecContext *avctx) +{ + avctx->internal->draining = 0; + avctx->internal->draining_done = 0; + avctx->internal->nb_draining_errors = 0; + av_frame_unref(avctx->internal->buffer_frame); + av_frame_unref(avctx->internal->compat_decode_frame); + av_packet_unref(avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + + av_packet_unref(avctx->internal->ds.in_pkt); + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ff_thread_flush(avctx); + else if (avctx->codec->flush) + avctx->codec->flush(avctx); + + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + + ff_decode_bsfs_uninit(avctx); + + if (!avctx->refcounted_frames) + av_frame_unref(avctx->internal->to_free); +} + +void ff_decode_bsfs_uninit(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int i; + + for (i = 0; i < s->nb_bsfs; i++) + av_bsf_free(&s->bsfs[i]); + av_freep(&s->bsfs); + s->nb_bsfs = 0; +} diff --git a/media/ffvpx/libavcodec/decode.h b/media/ffvpx/libavcodec/decode.h new file mode 100644 index 000000000..c9630228d --- /dev/null +++ b/media/ffvpx/libavcodec/decode.h @@ -0,0 +1,39 @@ +/* + * generic decoding-related code + * + * 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_DECODE_H +#define AVCODEC_DECODE_H + +#include "avcodec.h" + +/** + * Called by decoders to get the next packet for decoding. + * + * @param pkt An empty packet to be filled with data. + * @return 0 if a new reference has been successfully written to pkt + * AVERROR(EAGAIN) if no data is currently available + * AVERROR_EOF if and end of stream has been reached, so no more data + * will be available + */ +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); + +void ff_decode_bsfs_uninit(AVCodecContext *avctx); + +#endif /* AVCODEC_DECODE_H */ diff --git a/media/ffvpx/libavcodec/dummy_funcs.c b/media/ffvpx/libavcodec/dummy_funcs.c index 200e1d266..21b469f7e 100644 --- a/media/ffvpx/libavcodec/dummy_funcs.c +++ b/media/ffvpx/libavcodec/dummy_funcs.c @@ -73,6 +73,16 @@ AVHWAccel ff_hevc_mediacodec_hwaccel; AVHWAccel ff_mpeg4_mediacodec_hwaccel; AVHWAccel ff_vp8_mediacodec_hwaccel; AVHWAccel ff_vp9_mediacodec_hwaccel; +/* Added by FFmpeg 3.4 */ +AVHWAccel ff_h264_d3d11va2_hwaccel; +AVHWAccel ff_hevc_d3d11va2_hwaccel; +AVHWAccel ff_hevc_videotoolbox_hwaccel; +AVHWAccel ff_mpeg2_d3d11va2_hwaccel; +AVHWAccel ff_mpeg2_mediacodec_hwaccel; +AVHWAccel ff_vc1_d3d11va2_hwaccel; +AVHWAccel ff_vp8_qsv_hwaccel; +AVHWAccel ff_vp9_d3d11va2_hwaccel; +AVHWAccel ff_wmv3_d3d11va2_hwaccel; AVCodec ff_a64multi_encoder; AVCodec ff_a64multi5_encoder; @@ -741,6 +751,54 @@ AVCodec ff_pcm_s64be_decoder; AVCodec ff_pcm_s64be_encoder; AVCodec ff_truehd_encoder; AVCodec ff_mlp_encoder; +/* Added by FFmpeg 3.4 */ +AVCodec ff_clearvideo_decoder; +AVCodec ff_fits_encoder; +AVCodec ff_fits_decoder; +AVCodec ff_fmvc_decoder; +AVCodec ff_gdv_decoder; +AVCodec ff_h263_v4l2m2m_decoder; +AVCodec ff_h264_v4l2m2m_decoder; +AVCodec ff_h264_rkmpp_decoder; +AVCodec ff_hevc_rkmpp_decoder; +AVCodec ff_hevc_v4l2m2m_decoder; +AVCodec ff_mpeg4_v4l2m2m_decoder; +AVCodec ff_mpeg1_v4l2m2m_decoder; +AVCodec ff_mpeg2_v4l2m2m_decoder; +AVCodec ff_mpeg2_mediacodec_decoder; +AVCodec ff_mscc_decoder; +AVCodec ff_pixlet_decoder; +AVCodec ff_psd_decoder; +AVCodec ff_scpr_decoder; +AVCodec ff_speedhq_decoder; +AVCodec ff_srgc_decoder; +AVCodec ff_vc1_v4l2m2m_decoder; +AVCodec ff_vp8_rkmpp_decoder; +AVCodec ff_vp8_v4l2m2m_decoder; +AVCodec ff_vp9_rkmpp_decoder; +AVCodec ff_vp9_v4l2m2m_decoder; +AVCodec ff_bitpacked_decoder; +AVCodec ff_wrapped_avframe_decoder; +AVCodec ff_xpm_decoder; +AVCodec ff_atrac3al_decoder; +AVCodec ff_atrac3pal_decoder; +AVCodec ff_dolby_e_decoder; +AVCodec ff_opus_encoder; +AVCodec ff_qdmc_decoder; +AVCodec ff_pcm_f16le_decoder; +AVCodec ff_pcm_f24le_decoder; +AVCodec ff_gremlin_dpcm_decoder; +AVCodec ff_adpcm_g726le_encoder; +AVCodec ff_librsvg_decoder; +AVCodec ff_h263_v4l2m2m_encoder; +AVCodec ff_h264_v4l2m2m_encoder; +AVCodec ff_hevc_v4l2m2m_encoder; +AVCodec ff_mpeg2_vaapi_encoder; +AVCodec ff_mpeg4_v4l2m2m_encoder; +AVCodec ff_vp8_qsv_decoder; +AVCodec ff_vp8_v4l2m2m_encoder; +AVCodec ff_vp8_vaapi_encoder; +AVCodec ff_vp9_vaapi_encoder; AVCodecParser ff_aac_parser; AVCodecParser ff_aac_latm_parser; @@ -777,6 +835,10 @@ AVCodecParser ff_tak_parser; AVCodecParser ff_vc1_parser; AVCodecParser ff_vorbis_parser; AVCodecParser ff_vp3_parser; +/* Added by FFmpeg 3.4 */ +AVCodecParser ff_sipr_parser; +AVCodecParser ff_xma_parser; + AVBitStreamFilter ff_aac_adtstoasc_bsf; AVBitStreamFilter ff_chomp_bsf; AVBitStreamFilter ff_dump_extradata_bsf; @@ -806,12 +868,15 @@ int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVF void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc) {} void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc) {} void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc) {} +void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc) {} void ff_vp7dsp_init(VP8DSPContext *c) {} void ff_vp78dsp_init_arm(VP8DSPContext *c) {} void ff_vp78dsp_init_ppc(VP8DSPContext *c) {} void ff_vp8dsp_init_arm(VP8DSPContext *c) {} void ff_vp8dsp_init_mips(VP8DSPContext *c) {} void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp) {} +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp) {} +void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp) {} void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps) {} #if !defined(HAVE_64BIT_BUILD) void ff_flac_decorrelate_indep8_16_sse2(uint8_t **out, int32_t **in, int channels, int len, int shift) {} @@ -819,11 +884,3 @@ void ff_flac_decorrelate_indep8_32_avx(uint8_t **out, int32_t **in, int channels void ff_flac_decorrelate_indep8_16_avx(uint8_t **out, int32_t **in, int channels, int len, int shift) {} void ff_flac_decorrelate_indep8_32_sse2(uint8_t **out, int32_t **in, int channels, int len, int shift) {} #endif -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf) {} -int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe) { return 0; } -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) { return NULL;} -AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f) { return NULL; } -void av_register_bitstream_filter(AVBitStreamFilter *bsf) {} diff --git a/media/ffvpx/libavcodec/error_resilience.h b/media/ffvpx/libavcodec/error_resilience.h index d444ec3a3..27c200869 100644 --- a/media/ffvpx/libavcodec/error_resilience.h +++ b/media/ffvpx/libavcodec/error_resilience.h @@ -57,8 +57,8 @@ typedef struct ERContext { int *mb_index2xy; int mb_num; int mb_width, mb_height; - int mb_stride; - int b8_stride; + ptrdiff_t mb_stride; + ptrdiff_t b8_stride; volatile int error_count; int error_occurred; diff --git a/media/ffvpx/libavcodec/flac.c b/media/ffvpx/libavcodec/flac.c index f5154b914..5ffbf9319 100644 --- a/media/ffvpx/libavcodec/flac.c +++ b/media/ffvpx/libavcodec/flac.c @@ -201,7 +201,7 @@ void ff_flac_set_channel_layout(AVCodecContext *avctx) avctx->channel_layout = 0; } -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, +int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer) { GetBitContext gb; @@ -213,6 +213,7 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n", s->max_blocksize); s->max_blocksize = 16; + return AVERROR_INVALIDDATA; } skip_bits(&gb, 24); /* skip min frame size */ @@ -222,6 +223,12 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, s->channels = get_bits(&gb, 3) + 1; s->bps = get_bits(&gb, 5) + 1; + if (s->bps < 4) { + av_log(avctx, AV_LOG_ERROR, "invalid bps: %d\n", s->bps); + s->bps = 16; + return AVERROR_INVALIDDATA; + } + avctx->channels = s->channels; avctx->sample_rate = s->samplerate; avctx->bits_per_raw_sample = s->bps; @@ -234,4 +241,6 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, skip_bits_long(&gb, 64); /* md5 sum */ skip_bits_long(&gb, 64); /* md5 sum */ + + return 0; } diff --git a/media/ffvpx/libavcodec/flac.h b/media/ffvpx/libavcodec/flac.h index 96d971c9d..991ab43f3 100644 --- a/media/ffvpx/libavcodec/flac.h +++ b/media/ffvpx/libavcodec/flac.h @@ -95,8 +95,10 @@ typedef struct FLACFrameInfo { * @param[out] avctx codec context to set basic stream parameters * @param[out] s where parsed information is stored * @param[in] buffer pointer to start of 34-byte streaminfo data + * + * @return negative error code on faiure or >= 0 on success */ -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, +int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer); /** diff --git a/media/ffvpx/libavcodec/flac_parser.c b/media/ffvpx/libavcodec/flac_parser.c index f5cc35a4f..84da23f32 100644 --- a/media/ffvpx/libavcodec/flac_parser.c +++ b/media/ffvpx/libavcodec/flac_parser.c @@ -586,10 +586,12 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, temp = curr->next; av_freep(&curr->link_penalty); av_free(curr); + fpc->nb_headers_buffered--; } fpc->headers = fpc->best_header->next; av_freep(&fpc->best_header->link_penalty); av_freep(&fpc->best_header); + fpc->nb_headers_buffered--; } /* Find and score new headers. */ @@ -638,7 +640,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, read_end - read_start, NULL); } else { int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 }; - av_fifo_generic_write(fpc->fifo_buf, (void*) pad, sizeof(pad), NULL); + av_fifo_generic_write(fpc->fifo_buf, pad, sizeof(pad), NULL); } /* Tag headers and update sequences. */ diff --git a/media/ffvpx/libavcodec/flacdec.c b/media/ffvpx/libavcodec/flacdec.c index b7237e18f..3d41a1af7 100644 --- a/media/ffvpx/libavcodec/flacdec.c +++ b/media/ffvpx/libavcodec/flacdec.c @@ -109,7 +109,9 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; /* initialize based on the demuxer-supplied streamdata header */ - ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo); + ret = ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo); + if (ret < 0) + return ret; ret = allocate_buffers(s); if (ret < 0) return ret; @@ -175,7 +177,9 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) metadata_size != FLAC_STREAMINFO_SIZE) { return AVERROR_INVALIDDATA; } - ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]); + ret = ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]); + if (ret < 0) + return ret; ret = allocate_buffers(s); if (ret < 0) return ret; @@ -201,12 +205,12 @@ static int get_metadata_size(const uint8_t *buf, int buf_size) buf += 4; do { if (buf_end - buf < 4) - return 0; + return AVERROR_INVALIDDATA; flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size); buf += 4; if (buf_end - buf < metadata_size) { /* need more data in order to read the complete header */ - return 0; + return AVERROR_INVALIDDATA; } buf += metadata_size; } while (!metadata_last); @@ -254,8 +258,15 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) for (; i < samples; i++) *decoded++ = get_sbits_long(&s->gb, tmp); } else { + int real_limit = tmp ? (INT_MAX >> tmp) + 2 : INT_MAX; for (; i < samples; i++) { - *decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); + int v = get_sr_golomb_flac(&s->gb, tmp, real_limit, 0); + if (v == 0x80000000){ + av_log(s->avctx, AV_LOG_ERROR, "invalid residual\n"); + return AVERROR_INVALIDDATA; + } + + *decoded++ = v; } } i= 0; @@ -268,7 +279,8 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, int pred_order, int bps) { const int blocksize = s->blocksize; - int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; + unsigned av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d); + int i; int ret; /* warm up samples */ @@ -286,7 +298,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, if (pred_order > 2) c = b - decoded[pred_order-2] + decoded[pred_order-3]; if (pred_order > 3) - d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4]; + d = c - decoded[pred_order-2] + 2U*decoded[pred_order-3] - decoded[pred_order-4]; switch (pred_order) { case 0: @@ -315,7 +327,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, return 0; } -static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32], +static void lpc_analyze_remodulate(SUINT32 *decoded, const int coeffs[32], int order, int qlevel, int len, int bps) { int i, j; @@ -331,7 +343,7 @@ static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32], for (i = len - 1; i >= order; i--) { int64_t p = 0; for (j = 0; j < order; j++) - p += coeffs[j] * (int64_t)decoded[i-order+j]; + p += coeffs[j] * (int64_t)(int32_t)decoded[i-order+j]; decoded[i] -= p >> qlevel; } for (i = order; i < len; i++, decoded++) { @@ -444,10 +456,10 @@ static inline int decode_subframe(FLACContext *s, int channel) return AVERROR_INVALIDDATA; } - if (wasted) { + if (wasted && wasted < 32) { int i; for (i = 0; i < s->blocksize; i++) - decoded[i] <<= wasted; + decoded[i] = (unsigned)decoded[i] << wasted; } return 0; diff --git a/media/ffvpx/libavcodec/flacdsp.c b/media/ffvpx/libavcodec/flacdsp.c index 30b66484e..bc9a5dbed 100644 --- a/media/ffvpx/libavcodec/flacdsp.c +++ b/media/ffvpx/libavcodec/flacdsp.c @@ -49,8 +49,8 @@ static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32], int i, j; for (i = pred_order; i < len - 1; i += 2, decoded += 2) { - int c = coeffs[0]; - int d = decoded[0]; + SUINT c = coeffs[0]; + SUINT d = decoded[0]; int s0 = 0, s1 = 0; for (j = 1; j < pred_order; j++) { s0 += c*d; @@ -59,15 +59,15 @@ static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32], c = coeffs[j]; } s0 += c*d; - d = decoded[j] += s0 >> qlevel; + d = decoded[j] += (SUINT)(s0 >> qlevel); s1 += c*d; - decoded[j + 1] += s1 >> qlevel; + decoded[j + 1] += (SUINT)(s1 >> qlevel); } if (i < len) { int sum = 0; for (j = 0; j < pred_order; j++) - sum += coeffs[j] * decoded[j]; - decoded[j] += sum >> qlevel; + sum += coeffs[j] * (SUINT)decoded[j]; + decoded[j] = decoded[j] + (unsigned)(sum >> qlevel); } } diff --git a/media/ffvpx/libavcodec/flacdsp.h b/media/ffvpx/libavcodec/flacdsp.h index f5cbd9472..7bb0dd0e9 100644 --- a/media/ffvpx/libavcodec/flacdsp.h +++ b/media/ffvpx/libavcodec/flacdsp.h @@ -20,6 +20,7 @@ #define AVCODEC_FLACDSP_H #include +#include "libavutil/internal.h" #include "libavutil/samplefmt.h" typedef struct FLACDSPContext { diff --git a/media/ffvpx/libavcodec/flacdsp_template.c b/media/ffvpx/libavcodec/flacdsp_template.c index 62c0a15ff..776c78da7 100644 --- a/media/ffvpx/libavcodec/flacdsp_template.c +++ b/media/ffvpx/libavcodec/flacdsp_template.c @@ -56,7 +56,7 @@ static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in, for (j = 0; j < len; j++) for (i = 0; i < channels; i++) - S(samples, i, j) = in[i][j] << shift; + S(samples, i, j) = (int)((unsigned)in[i][j] << shift); } static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in, diff --git a/media/ffvpx/libavcodec/get_bits.h b/media/ffvpx/libavcodec/get_bits.h index 0f183e035..0c7f5ff0c 100644 --- a/media/ffvpx/libavcodec/get_bits.h +++ b/media/ffvpx/libavcodec/get_bits.h @@ -229,6 +229,20 @@ static inline int get_xbits(GetBitContext *s, int n) return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; } +static inline int get_xbits_le(GetBitContext *s, int n) +{ + register int sign; + register int32_t cache; + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE_LE(re, s); + cache = GET_CACHE(re, s); + sign = sign_extend(~cache, n) >> 31; + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); + return (zero_extend(sign ^ cache, n) ^ sign) - sign; +} + static inline int get_sbits(GetBitContext *s, int n) { register int tmp; @@ -331,6 +345,7 @@ static inline void skip_bits1(GetBitContext *s) */ static inline unsigned int get_bits_long(GetBitContext *s, int n) { + av_assert2(n>=0 && n<=32); if (!n) { return 0; } else if (n <= MIN_CACHE_BITS) { @@ -369,6 +384,10 @@ static inline uint64_t get_bits64(GetBitContext *s, int n) */ static inline int get_sbits_long(GetBitContext *s, int n) { + // sign_extend(x, 0) is undefined + if (!n) + return 0; + return sign_extend(get_bits_long(s, n), n); } @@ -531,6 +550,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) * @param max_depth is the number of times bits bits must be read to completely * read the longest vlc code * = (max_vlc_length + bits - 1) / bits + * @returns the code parsed or -1 if no vlc matches */ static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth) diff --git a/media/ffvpx/libavcodec/golomb.h b/media/ffvpx/libavcodec/golomb.h index 917ea54e1..efb1eff8a 100644 --- a/media/ffvpx/libavcodec/golomb.h +++ b/media/ffvpx/libavcodec/golomb.h @@ -314,6 +314,8 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, log = av_log2(buf); + av_assert2(k <= 31); + if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) && 32 - log < limit) { buf >>= log - k; @@ -325,8 +327,10 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, } else { int i; for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) { - if (gb->size_in_bits <= re_index) + if (gb->size_in_bits <= re_index) { + CLOSE_READER(re, gb); return -1; + } LAST_SKIP_BITS(re, gb, 1); UPDATE_CACHE(re, gb); } @@ -348,16 +352,17 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, buf = 0; } - CLOSE_READER(re, gb); - return buf + (i << k); + buf += ((SUINT)i << k); } else if (i == limit - 1) { buf = SHOW_UBITS(re, gb, esc_len); LAST_SKIP_BITS(re, gb, esc_len); - CLOSE_READER(re, gb); - return buf + 1; - } else - return -1; + buf ++; + } else { + buf = -1; + } + CLOSE_READER(re, gb); + return buf; } } @@ -445,19 +450,20 @@ static inline int get_te(GetBitContext *s, int r, char *file, const char *func, return i; } -#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_ue_golomb(a) get_ue(a, __FILE__, __func__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __func__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) #endif /* TRACE */ /** - * write unsigned exp golomb code. + * write unsigned exp golomb code. 2^16 - 2 at most */ static inline void set_ue_golomb(PutBitContext *pb, int i) { av_assert2(i >= 0); + av_assert2(i <= 0xFFFE); if (i < 256) put_bits(pb, ff_ue_golomb_len[i], i + 1); @@ -467,6 +473,21 @@ static inline void set_ue_golomb(PutBitContext *pb, int i) } } +/** + * write unsigned exp golomb code. 2^32-2 at most. + */ +static inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i) +{ + av_assert2(i <= (UINT32_MAX - 1)); + + if (i < 256) + put_bits(pb, ff_ue_golomb_len[i], i + 1); + else { + int e = av_log2(i + 1); + put_bits64(pb, 2 * e + 1, i + 1); + } +} + /** * write truncated unsigned exp golomb code. */ @@ -486,19 +507,9 @@ static inline void set_te_golomb(PutBitContext *pb, int i, int range) */ static inline void set_se_golomb(PutBitContext *pb, int i) { -#if 0 - if (i <= 0) - i = -2 * i; - else - i = 2 * i - 1; -#elif 1 i = 2 * i - 1; if (i < 0) i ^= -1; //FIXME check if gcc does the right thing -#else - i = 2 * i - 1; - i ^= (i >> 31); -#endif set_ue_golomb(pb, i); } diff --git a/media/ffvpx/libavcodec/h264chroma.h b/media/ffvpx/libavcodec/h264chroma.h index e0f45ad13..5c89fd12d 100644 --- a/media/ffvpx/libavcodec/h264chroma.h +++ b/media/ffvpx/libavcodec/h264chroma.h @@ -19,9 +19,10 @@ #ifndef AVCODEC_H264CHROMA_H #define AVCODEC_H264CHROMA_H +#include #include -typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y); typedef struct H264ChromaContext { h264_chroma_mc_func put_h264_chroma_pixels_tab[4]; diff --git a/media/ffvpx/libavcodec/hpeldsp.h b/media/ffvpx/libavcodec/hpeldsp.h index 1a3cea54b..768139bfc 100644 --- a/media/ffvpx/libavcodec/hpeldsp.h +++ b/media/ffvpx/libavcodec/hpeldsp.h @@ -76,6 +76,8 @@ typedef struct HpelDSPContext { * @param pixels source * @param line_size number of bytes in a horizontal line of block * @param h height + * @note The size is kept at [4][4] to match the above pixel_tabs and avoid + * out of bounds reads in the motion estimation code. */ op_pixels_func put_no_rnd_pixels_tab[4][4]; diff --git a/media/ffvpx/libavcodec/hwaccel.h b/media/ffvpx/libavcodec/hwaccel.h new file mode 100644 index 000000000..124fbbf1f --- /dev/null +++ b/media/ffvpx/libavcodec/hwaccel.h @@ -0,0 +1,24 @@ +/* + * 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_HWACCEL_H +#define AVCODEC_HWACCEL_H + +#define HWACCEL_CAP_ASYNC_SAFE (1 << 0) + +#endif /* AVCODEC_HWACCEL_H */ diff --git a/media/ffvpx/libavcodec/idctdsp.h b/media/ffvpx/libavcodec/idctdsp.h index b180a6762..26221f6a9 100644 --- a/media/ffvpx/libavcodec/idctdsp.h +++ b/media/ffvpx/libavcodec/idctdsp.h @@ -21,6 +21,8 @@ #include +#include "config.h" + #include "avcodec.h" /** @@ -51,13 +53,13 @@ int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, typedef struct IDCTDSPContext { /* pixel ops : interface with DCT */ void (*put_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*add_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*idct)(int16_t *block /* align 16 */); @@ -68,14 +70,14 @@ typedef struct IDCTDSPContext { * @param line_size size in bytes of a horizontal line of dest */ void (*idct_put)(uint8_t *dest /* align 8 */, - int line_size, int16_t *block /* align 16 */); + ptrdiff_t line_size, int16_t *block /* align 16 */); /** * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. * @param line_size size in bytes of a horizontal line of dest */ void (*idct_add)(uint8_t *dest /* align 8 */, - int line_size, int16_t *block /* align 16 */); + ptrdiff_t line_size, int16_t *block /* align 16 */); /** * IDCT input permutation. @@ -95,11 +97,15 @@ typedef struct IDCTDSPContext { enum idct_permutation_type perm_type; } IDCTDSPContext; -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_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, + ptrdiff_t line_size); +void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, + ptrdiff_t line_size); void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx); +void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth); void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx, diff --git a/media/ffvpx/libavcodec/internal.h b/media/ffvpx/libavcodec/internal.h index 35b9630b5..faa923c11 100644 --- a/media/ffvpx/libavcodec/internal.h +++ b/media/ffvpx/libavcodec/internal.h @@ -48,8 +48,8 @@ #define FF_CODEC_CAP_INIT_CLEANUP (1 << 1) /** * Decoders marked with FF_CODEC_CAP_SETS_PKT_DTS want to set - * AVFrame.pkt_dts manually. If the flag is set, utils.c won't overwrite - * this field. If it's unset, utils.c tries to guess the pkt_dts field + * AVFrame.pkt_dts manually. If the flag is set, decode.c won't overwrite + * this field. If it's unset, decode.c tries to guess the pkt_dts field * from the input AVPacket. */ #define FF_CODEC_CAP_SETS_PKT_DTS (1 << 2) @@ -58,6 +58,16 @@ * skipped due to the skip_frame setting. */ #define FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM (1 << 3) +/** + * The decoder sets the cropping fields in the output frames manually. + * If this cap is set, the generic code will initialize output frame + * dimensions to coded rather than display values. + */ +#define FF_CODEC_CAP_EXPORTS_CROPPING (1 << 4) +/** + * Codec initializes slice-based threading with a main function + */ +#define FF_CODEC_CAP_SLICE_THREAD_HAS_MF (1 << 5) #ifdef TRACE # define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__) @@ -70,11 +80,18 @@ #define FF_DEFAULT_QUANT_BIAS 999999 #endif +#if !FF_API_QSCALE_TYPE +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 +#define FF_QSCALE_TYPE_VP56 3 +#endif + #define FF_SANE_NB_CHANNELS 64U #define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1) -#if HAVE_AVX +#if HAVE_SIMD_ALIGN_32 # define STRIDE_ALIGN 32 #elif HAVE_SIMD_ALIGN_16 # define STRIDE_ALIGN 16 @@ -101,6 +118,16 @@ typedef struct FramePool { int samples; } FramePool; +typedef struct DecodeSimpleContext { + AVPacket *in_pkt; + AVFrame *out_frame; +} DecodeSimpleContext; + +typedef struct DecodeFilterContext { + AVBSFContext **bsfs; + int nb_bsfs; +} DecodeFilterContext; + typedef struct AVCodecInternal { /** * Whether the parent AVCodecContext is a copy of the context which had @@ -137,11 +164,14 @@ typedef struct AVCodecInternal { void *thread_ctx; + DecodeSimpleContext ds; + DecodeFilterContext filter; + /** - * Current packet as passed into the decoder, to avoid having to pass the - * packet into every function. + * Properties (timestamps+side data) extracted from the last packet passed + * for decoding. */ - AVPacket *pkt; + AVPacket *last_pkt_props; /** * temporary buffer used for encoders to store their bitstream @@ -173,7 +203,23 @@ typedef struct AVCodecInternal { int buffer_pkt_valid; // encoding: packet without data can be valid AVFrame *buffer_frame; int draining_done; + /* set to 1 when the caller is using the old decoding API */ + int compat_decode; + int compat_decode_warned; + /* this variable is set by the decoder internals to signal to the old + * API compat wrappers the amount of data consumed from the last packet */ + size_t compat_decode_consumed; + /* when a partial packet has been consumed, this stores the remaining size + * of the packet (that should be submitted in the next decode call */ + size_t compat_decode_partial_size; + AVFrame *compat_decode_frame; + int showed_multi_packet_warning; + + int skip_samples_multiplier; + + /* to prevent infinite loop on errors when draining */ + int nb_draining_errors; } AVCodecInternal; struct AVCodecDefault { @@ -262,7 +308,7 @@ static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx, static av_always_inline float ff_exp2fi(int x) { /* Normal range */ if (-126 <= x && x <= 128) - return av_int2float(x+127 << 23); + return av_int2float((x+127) << 23); /* Too large */ else if (x > 128) return INFINITY; @@ -327,6 +373,10 @@ int ff_set_sar(AVCodecContext *avctx, AVRational sar); int ff_side_data_update_matrix_encoding(AVFrame *frame, enum AVMatrixEncoding matrix_encoding); +#if FF_API_MERGE_SD +int ff_packet_split_and_drop_side_data(AVPacket *pkt); +#endif + /** * Select the (possibly hardware accelerated) pixel format. * This is a wrapper around AVCodecContext.get_format() and should be used @@ -361,4 +411,10 @@ int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, i int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size); +/** + * Get an estimated video bitrate based on frame size, frame rate and coded + * bits per pixel. + */ +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/media/ffvpx/libavcodec/mathops.h b/media/ffvpx/libavcodec/mathops.h index 5168dc2ce..1c3566431 100644 --- a/media/ffvpx/libavcodec/mathops.h +++ b/media/ffvpx/libavcodec/mathops.h @@ -25,6 +25,7 @@ #include #include "libavutil/common.h" +#include "libavutil/reverse.h" #include "config.h" #define MAX_NEG_CROP 1024 @@ -96,15 +97,6 @@ static av_always_inline unsigned UMULH(unsigned a, unsigned b){ #define mid_pred mid_pred static inline av_const int mid_pred(int a, int b, int c) { -#if 0 - int t= (a-b)&((a-b)>>31); - a-=t; - b+=t; - b-= (b-c)&((b-c)>>31); - b+= (a-b)&((a-b)>>31); - - return b; -#else if(a>b){ if(c>b){ if(c>a) b=a; @@ -117,7 +109,6 @@ static inline av_const int mid_pred(int a, int b, int c) } } return b; -#endif } #endif @@ -249,4 +240,12 @@ static inline int8_t ff_u8_to_s8(uint8_t a) return b.s8; } +static av_always_inline uint32_t bitswap_32(uint32_t x) +{ + return (uint32_t)ff_reverse[ x & 0xFF] << 24 | + (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | + (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | + (uint32_t)ff_reverse[ x >> 24]; +} + #endif /* AVCODEC_MATHOPS_H */ diff --git a/media/ffvpx/libavcodec/me_cmp.h b/media/ffvpx/libavcodec/me_cmp.h index 5666f59ad..0dbbcbb1d 100644 --- a/media/ffvpx/libavcodec/me_cmp.h +++ b/media/ffvpx/libavcodec/me_cmp.h @@ -76,7 +76,7 @@ typedef struct MECmpContext { me_cmp_func frame_skip_cmp[6]; // only width 8 used me_cmp_func pix_abs[2][4]; - me_cmp_func median_sad[2]; + me_cmp_func median_sad[6]; } MECmpContext; void ff_me_cmp_init_static(void); diff --git a/media/ffvpx/libavcodec/moz.build b/media/ffvpx/libavcodec/moz.build index 443bbe978..9980e1556 100644 --- a/media/ffvpx/libavcodec/moz.build +++ b/media/ffvpx/libavcodec/moz.build @@ -16,7 +16,11 @@ SOURCES += [ 'avpacket.c', 'avpicture.c', 'bitstream.c', + 'bitstream_filter.c', + 'bitstream_filters.c', + 'bsf.c', 'codec_desc.c', + 'decode.c', 'dummy_funcs.c', 'flac.c', 'flac_parser.c', @@ -28,6 +32,7 @@ SOURCES += [ 'imgconvert.c', 'log2_tab.c', 'mathtables.c', + 'null_bsf.c', 'options.c', 'parser.c', 'profiles.c', @@ -48,10 +53,16 @@ SOURCES += [ 'vp8dsp.c', 'vp9.c', 'vp9_parser.c', + 'vp9block.c', + 'vp9data.c', 'vp9dsp.c', 'vp9dsp_10bpp.c', 'vp9dsp_12bpp.c', 'vp9dsp_8bpp.c', + 'vp9lpf.c', + 'vp9mvs.c', + 'vp9prob.c', + 'vp9recon.c', 'xiph.c' ] diff --git a/media/ffvpx/libavcodec/mpegvideo.h b/media/ffvpx/libavcodec/mpegvideo.h index c82fa3e1a..e9eb633d1 100644 --- a/media/ffvpx/libavcodec/mpegvideo.h +++ b/media/ffvpx/libavcodec/mpegvideo.h @@ -422,6 +422,7 @@ typedef struct MpegEncContext { struct MJpegContext *mjpeg_ctx; int esc_pos; int pred; + int huffman; /* MSMPEG4 specific */ int mv_table_index; @@ -679,7 +680,7 @@ void ff_mpv_common_end(MpegEncContext *s); void ff_mpv_decode_defaults(MpegEncContext *s); void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); -void ff_mpv_decode_mb(MpegEncContext *s, int16_t block[12][64]); +void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]); void ff_mpv_report_decode_progress(MpegEncContext *s); int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx); diff --git a/media/ffvpx/libavcodec/null_bsf.c b/media/ffvpx/libavcodec/null_bsf.c new file mode 100644 index 000000000..feb71248a --- /dev/null +++ b/media/ffvpx/libavcodec/null_bsf.c @@ -0,0 +1,43 @@ +/* + * 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 + * Null bitstream filter -- pass the input through unchanged. + */ + +#include "avcodec.h" +#include "bsf.h" + +static int null_filter(AVBSFContext *ctx, AVPacket *out) +{ + AVPacket *in; + int ret; + + ret = ff_bsf_get_packet(ctx, &in); + if (ret < 0) + return ret; + av_packet_move_ref(out, in); + av_packet_free(&in); + return 0; +} + +const AVBitStreamFilter ff_null_bsf = { + .name = "null", + .filter = null_filter, +}; diff --git a/media/ffvpx/libavcodec/options.c b/media/ffvpx/libavcodec/options.c index d8e3dbfa3..82e12179a 100644 --- a/media/ffvpx/libavcodec/options.c +++ b/media/ffvpx/libavcodec/options.c @@ -119,6 +119,7 @@ static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) s->execute2 = avcodec_default_execute2; s->sample_aspect_ratio = (AVRational){0,1}; s->pix_fmt = AV_PIX_FMT_NONE; + s->sw_pix_fmt = AV_PIX_FMT_NONE; s->sample_fmt = AV_SAMPLE_FMT_NONE; s->reordered_opaque = AV_NOPTS_VALUE; @@ -187,6 +188,31 @@ void avcodec_free_context(AVCodecContext **pavctx) } #if FF_API_COPY_CONTEXT +static void copy_context_reset(AVCodecContext *avctx) +{ + int i; + + av_opt_free(avctx); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_freep(&avctx->rc_override); + av_freep(&avctx->intra_matrix); + av_freep(&avctx->inter_matrix); + av_freep(&avctx->extradata); + av_freep(&avctx->subtitle_header); + av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); + for (i = 0; i < avctx->nb_coded_side_data; i++) + av_freep(&avctx->coded_side_data[i].data); + av_freep(&avctx->coded_side_data); + avctx->subtitle_header_size = 0; + avctx->nb_coded_side_data = 0; + avctx->extradata_size = 0; +} + int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { const AVCodec *orig_codec = dest->codec; @@ -199,12 +225,7 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) return AVERROR(EINVAL); } - av_opt_free(dest); - av_freep(&dest->rc_override); - av_freep(&dest->intra_matrix); - av_freep(&dest->inter_matrix); - av_freep(&dest->extradata); - av_freep(&dest->subtitle_header); + copy_context_reset(dest); memcpy(dest, src, sizeof(*dest)); av_opt_copy(dest, src); @@ -229,11 +250,14 @@ FF_ENABLE_DEPRECATION_WARNINGS /* reallocate values that should be allocated separately */ dest->extradata = NULL; + dest->coded_side_data = NULL; dest->intra_matrix = NULL; dest->inter_matrix = NULL; dest->rc_override = NULL; dest->subtitle_header = NULL; dest->hw_frames_ctx = NULL; + dest->hw_device_ctx = NULL; + dest->nb_coded_side_data = 0; #define alloc_and_copy_or_fail(obj, size, pad) \ if (src->obj && size > 0) { \ @@ -263,15 +287,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; fail: - av_freep(&dest->subtitle_header); - av_freep(&dest->rc_override); - av_freep(&dest->intra_matrix); - av_freep(&dest->inter_matrix); - av_freep(&dest->extradata); - av_buffer_unref(&dest->hw_frames_ctx); - dest->subtitle_header_size = 0; - dest->extradata_size = 0; - av_opt_free(dest); + copy_context_reset(dest); return AVERROR(ENOMEM); } #endif diff --git a/media/ffvpx/libavcodec/options_table.h b/media/ffvpx/libavcodec/options_table.h index adfbe72bf..2ac37c3ff 100644 --- a/media/ffvpx/libavcodec/options_table.h +++ b/media/ffvpx/libavcodec/options_table.h @@ -106,12 +106,12 @@ static const AVOption avcodec_options[] = { {"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" }, {"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" }, #endif -{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX}, +{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 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 }, 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_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|E}, {"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, {"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, {"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. " @@ -163,6 +163,7 @@ static const AVOption avcodec_options[] = { {"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"}, {"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"}, {"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"}, +{"iedge", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, "bug"}, {"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, {"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, {"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, @@ -179,8 +180,8 @@ static const AVOption avcodec_options[] = { {"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, -{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, -{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, #if FF_API_PRIVATE_OPT {"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, #endif @@ -246,7 +247,7 @@ static const AVOption avcodec_options[] = { {"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"}, {"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"}, {"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"}, -{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, #if FF_API_PRIVATE_OPT {"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"}, {"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"}, @@ -274,8 +275,10 @@ static const AVOption avcodec_options[] = { {"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"}, {"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"}, {"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, {"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, {"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, {"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"}, @@ -312,6 +315,7 @@ static const AVOption avcodec_options[] = { #endif {"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, {"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"msad", "sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, {"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, #if FF_API_AFD @@ -393,6 +397,7 @@ static const AVOption avcodec_options[] = { {"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"}, {"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"}, {"mpeg4_asp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"main10", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, "profile"}, {"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, {"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D}, @@ -443,30 +448,46 @@ static const AVOption avcodec_options[] = { {"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 = -1 }, -1, INT64_MAX, V|E}, #endif -{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, -{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"}, -{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"}, +{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_UINT64, {.i64 = DEFAULT }, 0, UINT64_MAX, A|E|D, "channel_layout"}, +{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_UINT64, {.i64 = DEFAULT }, 0, UINT64_MAX, A|D, "request_channel_layout"}, {"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E}, {"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E}, {"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D}, -{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D, "color_primaries_type"}, +{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_primaries_type"}, {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, -{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, {"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"}, -{"smpte428_1", "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_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"}, +{"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte431", "SMPTE 431-2", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte432", "SMPTE 422-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"jedec-p22", "JEDEC P22", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, 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"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, 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"}, +{"log100", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log316", "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"}, +{"bt1361e", "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", "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-10", "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-12", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte2084", "SMPTE 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"arib-std-b67", "ARIB STD-B67", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_ARIB_STD_B67 }, 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"}, {"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"}, @@ -474,31 +495,39 @@ static const AVOption avcodec_options[] = { {"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"}, -{"smpte2084", "SMPTE ST 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, -{"smpte428_1", "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, -{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, AVCOL_SPC_NB-1, V|E|D, "colorspace_type"}, +{"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, 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"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, 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"}, -{"ycocg", "YCOCG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCOCG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, 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"}, +{"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, {"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, -{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D, "color_range_type"}, +{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"tv", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"pc", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, {"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, -{"chroma_sample_location", "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"}, +{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"unknown", "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"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 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", "set the 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"}, @@ -534,6 +563,7 @@ static const AVOption avcodec_options[] = { #if FF_API_SIDEDATA_ONLY_PKT {"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E }, #endif +{"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, V | D }, {"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D }, {"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" }, {"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" }, @@ -545,6 +575,11 @@ static const AVOption avcodec_options[] = { {"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 }, +{"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E }, +{"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, "hwaccel_flags"}, +{"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, "hwaccel_flags" }, +{"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, {NULL}, }; diff --git a/media/ffvpx/libavcodec/parser.c b/media/ffvpx/libavcodec/parser.c index 30cfc55cb..670680ea7 100644 --- a/media/ffvpx/libavcodec/parser.c +++ b/media/ffvpx/libavcodec/parser.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include @@ -251,7 +252,7 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); @@ -284,6 +285,8 @@ int ff_combine_frame(ParseContext *pc, int next, return -1; } + av_assert0(next >= 0 || pc->buffer); + *buf_size = pc->overread_index = pc->index + next; @@ -314,7 +317,7 @@ int ff_combine_frame(ParseContext *pc, int next, } if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); diff --git a/media/ffvpx/libavcodec/pixblockdsp.h b/media/ffvpx/libavcodec/pixblockdsp.h index 79ed86c3a..e036700ff 100644 --- a/media/ffvpx/libavcodec/pixblockdsp.h +++ b/media/ffvpx/libavcodec/pixblockdsp.h @@ -21,16 +21,23 @@ #include +#include "config.h" + #include "avcodec.h" typedef struct PixblockDSPContext { - void (*get_pixels)(int16_t *block /* align 16 */, + void (*get_pixels)(int16_t *av_restrict block /* align 16 */, const uint8_t *pixels /* align 8 */, - ptrdiff_t line_size); - void (*diff_pixels)(int16_t *block /* align 16 */, + ptrdiff_t stride); + void (*diff_pixels)(int16_t *av_restrict block /* align 16 */, const uint8_t *s1 /* align 8 */, const uint8_t *s2 /* align 8 */, - int stride); + ptrdiff_t stride); + void (*diff_pixels_unaligned)(int16_t *av_restrict block /* align 16 */, + const uint8_t *s1, + const uint8_t *s2, + ptrdiff_t stride); + } PixblockDSPContext; void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx); diff --git a/media/ffvpx/libavcodec/profiles.c b/media/ffvpx/libavcodec/profiles.c index da745e139..30498efed 100644 --- a/media/ffvpx/libavcodec/profiles.c +++ b/media/ffvpx/libavcodec/profiles.c @@ -46,6 +46,16 @@ const AVProfile ff_dca_profiles[] = { { FF_PROFILE_UNKNOWN }, }; +const AVProfile ff_dnxhd_profiles[] = { + { FF_PROFILE_DNXHD, "DNXHD"}, + { FF_PROFILE_DNXHR_LB, "DNXHR LB"}, + { FF_PROFILE_DNXHR_SQ, "DNXHR SQ"}, + { FF_PROFILE_DNXHR_HQ, "DNXHR HQ" }, + { FF_PROFILE_DNXHR_HQX, "DNXHR HQX"}, + { FF_PROFILE_DNXHR_444, "DNXHR 444"}, + { FF_PROFILE_UNKNOWN }, +}; + const AVProfile ff_h264_profiles[] = { { FF_PROFILE_H264_BASELINE, "Baseline" }, { FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" }, @@ -60,6 +70,8 @@ const AVProfile ff_h264_profiles[] = { { FF_PROFILE_H264_HIGH_444_PREDICTIVE, "High 4:4:4 Predictive" }, { FF_PROFILE_H264_HIGH_444_INTRA, "High 4:4:4 Intra" }, { FF_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" }, + { FF_PROFILE_H264_MULTIVIEW_HIGH, "Multiview High" }, + { FF_PROFILE_H264_STEREO_HIGH, "Stereo High" }, { FF_PROFILE_UNKNOWN }, }; diff --git a/media/ffvpx/libavcodec/profiles.h b/media/ffvpx/libavcodec/profiles.h index c86c683ab..eb18b406a 100644 --- a/media/ffvpx/libavcodec/profiles.h +++ b/media/ffvpx/libavcodec/profiles.h @@ -23,6 +23,7 @@ extern const AVProfile ff_aac_profiles[]; extern const AVProfile ff_dca_profiles[]; +extern const AVProfile ff_dnxhd_profiles[]; extern const AVProfile ff_h264_profiles[]; extern const AVProfile ff_hevc_profiles[]; extern const AVProfile ff_jpeg2000_profiles[]; diff --git a/media/ffvpx/libavcodec/pthread_frame.c b/media/ffvpx/libavcodec/pthread_frame.c index 7ef5e9f6b..2c702c737 100644 --- a/media/ffvpx/libavcodec/pthread_frame.c +++ b/media/ffvpx/libavcodec/pthread_frame.c @@ -24,9 +24,11 @@ #include "config.h" +#include #include #include "avcodec.h" +#include "hwaccel.h" #include "internal.h" #include "pthread_internal.h" #include "thread.h" @@ -43,6 +45,25 @@ #include "libavutil/opt.h" #include "libavutil/thread.h" +enum { + ///< Set when the thread is awaiting a packet. + STATE_INPUT_READY, + ///< Set before the codec has called ff_thread_finish_setup(). + STATE_SETTING_UP, + /** + * Set when the codec calls get_buffer(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_BUFFER, + /** + * Set when the codec calls get_format(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_FORMAT, + ///< Set after the codec has called ff_thread_finish_setup(). + STATE_SETUP_FINISHED, +}; + /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ @@ -66,19 +87,7 @@ typedef struct PerThreadContext { int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. int result; ///< The result of the last codec decode/encode() call. - enum { - STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. - STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). - STATE_GET_BUFFER, /**< - * Set when the codec calls get_buffer(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_GET_FORMAT, /**< - * Set when the codec calls get_format(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). - } state; + atomic_int state; /** * Array of frames passed to ff_thread_release_buffer(). @@ -95,6 +104,11 @@ typedef struct PerThreadContext { enum AVPixelFormat result_format; ///< get_format() result int die; ///< Set when the thread should exit. + + int hwaccel_serializing; + int async_serializing; + + atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set. } PerThreadContext; /** @@ -105,6 +119,14 @@ typedef struct FrameThreadContext { PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). + /** + * This lock is used for ensuring threads run in serial when hwaccel + * is used. + */ + pthread_mutex_t hwaccel_mutex; + pthread_mutex_t async_mutex; + pthread_cond_t async_cond; + int async_lock; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -118,6 +140,24 @@ typedef struct FrameThreadContext { #define THREAD_SAFE_CALLBACKS(avctx) \ ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) +static void async_lock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + while (fctx->async_lock) + pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex); + fctx->async_lock = 1; + pthread_mutex_unlock(&fctx->async_mutex); +} + +static void async_unlock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + av_assert0(fctx->async_lock); + fctx->async_lock = 0; + pthread_cond_broadcast(&fctx->async_cond); + pthread_mutex_unlock(&fctx->async_mutex); +} + /** * Codec worker thread. * @@ -133,14 +173,29 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_lock(&p->mutex); while (1) { - while (p->state == STATE_INPUT_READY && !p->die) - pthread_cond_wait(&p->input_cond, &p->mutex); + while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die) + pthread_cond_wait(&p->input_cond, &p->mutex); if (p->die) break; if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) ff_thread_finish_setup(avctx); + /* If a decoder supports hwaccel, then it must call ff_get_format(). + * Since that call must happen before ff_thread_finish_setup(), the + * decoder is required to implement update_thread_context() and call + * ff_thread_finish_setup() manually. Therefore the above + * ff_thread_finish_setup() call did not happen and hwaccel_serializing + * cannot be true here. */ + av_assert0(!p->hwaccel_serializing); + + /* if the previous thread uses hwaccel then we take the lock to ensure + * the threads don't run concurrently */ + if (avctx->hwaccel) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + av_frame_unref(p->frame); p->got_frame = 0; p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); @@ -152,17 +207,23 @@ static attribute_align_arg void *frame_worker_thread(void *arg) av_frame_unref(p->frame); } - if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); + if (atomic_load(&p->state) == STATE_SETTING_UP) + ff_thread_finish_setup(avctx); + + if (p->hwaccel_serializing) { + p->hwaccel_serializing = 0; + pthread_mutex_unlock(&p->parent->hwaccel_mutex); + } + + if (p->async_serializing) { + p->async_serializing = 0; + + async_unlock(p->parent); + } pthread_mutex_lock(&p->progress_mutex); -#if 0 //BUFREF-FIXME - for (i = 0; i < MAX_BUFFERS; i++) - if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) { - p->progress[i][0] = INT_MAX; - p->progress[i][1] = INT_MAX; - } -#endif - p->state = STATE_INPUT_READY; + + atomic_store(&p->state, STATE_INPUT_READY); pthread_cond_broadcast(&p->progress_cond); pthread_cond_signal(&p->output_cond); @@ -185,12 +246,13 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, { int err = 0; - if (dst != src) { + if (dst != src && (for_user || !(av_codec_get_codec_descriptor(src)->props & AV_CODEC_PROP_INTRA_ONLY))) { dst->time_base = src->time_base; dst->framerate = src->framerate; dst->width = src->width; dst->height = src->height; dst->pix_fmt = src->pix_fmt; + dst->sw_pix_fmt = src->sw_pix_fmt; dst->coded_width = src->coded_width; dst->coded_height = src->coded_height; @@ -226,6 +288,19 @@ FF_ENABLE_DEPRECATION_WARNINGS dst->sample_fmt = src->sample_fmt; dst->channel_layout = src->channel_layout; dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; + + if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx || + (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) { + av_buffer_unref(&dst->hw_frames_ctx); + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) + return AVERROR(ENOMEM); + } + } + + dst->hwaccel_flags = src->hwaccel_flags; } if (for_user) { @@ -307,24 +382,35 @@ static void release_delayed_buffers(PerThreadContext *p) } } -static int submit_packet(PerThreadContext *p, AVPacket *avpkt) +static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, + AVPacket *avpkt) { FrameThreadContext *fctx = p->parent; PerThreadContext *prev_thread = fctx->prev_thread; const AVCodec *codec = p->avctx->codec; + int ret; if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY)) return 0; pthread_mutex_lock(&p->mutex); + ret = update_context_from_user(p->avctx, user_avctx); + if (ret) { + pthread_mutex_unlock(&p->mutex); + return ret; + } + atomic_store_explicit(&p->debug_threads, + (p->avctx->debug & FF_DEBUG_THREADS) != 0, + memory_order_relaxed); + release_delayed_buffers(p); if (prev_thread) { int err; - if (prev_thread->state == STATE_SETTING_UP) { + if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) { pthread_mutex_lock(&prev_thread->progress_mutex); - while (prev_thread->state == STATE_SETTING_UP) + while (atomic_load(&prev_thread->state) == STATE_SETTING_UP) pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); pthread_mutex_unlock(&prev_thread->progress_mutex); } @@ -337,9 +423,14 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) } av_packet_unref(&p->avpkt); - av_packet_ref(&p->avpkt, avpkt); + ret = av_packet_ref(&p->avpkt, avpkt); + if (ret < 0) { + pthread_mutex_unlock(&p->mutex); + av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n"); + return ret; + } - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); @@ -352,13 +443,13 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) if (!p->avctx->thread_safe_callbacks && ( p->avctx->get_format != avcodec_default_get_format || p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { - while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { + while (atomic_load(&p->state) != STATE_SETUP_FINISHED && atomic_load(&p->state) != STATE_INPUT_READY) { int call_done = 1; pthread_mutex_lock(&p->progress_mutex); - while (p->state == STATE_SETTING_UP) + while (atomic_load(&p->state) == STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - switch (p->state) { + switch (atomic_load_explicit(&p->state, memory_order_acquire)) { case STATE_GET_BUFFER: p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); break; @@ -370,7 +461,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) break; } if (call_done) { - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->progress_cond); } pthread_mutex_unlock(&p->progress_mutex); @@ -392,15 +483,18 @@ int ff_thread_decode_frame(AVCodecContext *avctx, PerThreadContext *p; int err; + /* release the async lock, permitting blocked hwaccel threads to + * go forward while we are in this function */ + async_unlock(fctx); + /* * Submit a packet to the next decoding thread. */ p = &fctx->threads[fctx->next_decoding]; - err = update_context_from_user(p->avctx, avctx); - if (err) return err; - err = submit_packet(p, avpkt); - if (err) return err; + err = submit_packet(p, avctx, avpkt); + if (err) + goto finish; /* * If we're still receiving the initial packets, don't return a frame. @@ -411,23 +505,25 @@ int ff_thread_decode_frame(AVCodecContext *avctx, if (fctx->delaying) { *got_picture_ptr=0; - if (avpkt->size) - return avpkt->size; + if (avpkt->size) { + err = avpkt->size; + goto finish; + } } /* * Return the next available frame from the oldest thread. * If we're at the end of the stream, then we have to skip threads that - * didn't output a frame, because we don't want to accidentally signal - * EOF (avpkt->size == 0 && *got_picture_ptr == 0). + * didn't output a frame/error, because we don't want to accidentally signal + * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0). */ do { p = &fctx->threads[finished++]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -435,20 +531,19 @@ int ff_thread_decode_frame(AVCodecContext *avctx, av_frame_move_ref(picture, p->frame); *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; - - if (p->result < 0) - err = p->result; + err = p->result; /* * A later call with avkpt->size == 0 may loop over all threads, - * including this one, searching for a frame to return before being + * including this one, searching for a frame/error to return before being * stopped by the "finished != fctx->next_finished" condition. - * Make sure we don't mistakenly return the same frame again. + * Make sure we don't mistakenly return the same frame/error again. */ p->got_frame = 0; + p->result = 0; if (finished >= avctx->thread_count) finished = 0; - } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished); + } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished); update_context_from_thread(avctx, p->avctx, 1); @@ -456,32 +551,33 @@ int ff_thread_decode_frame(AVCodecContext *avctx, fctx->next_finished = finished; - /* - * When no frame was found while flushing, but an error occurred in - * any thread, return it instead of 0. - * Otherwise the error can get lost. - */ - if (!avpkt->size && !*got_picture_ptr) - return err; - /* return the size of the consumed packet if no error occurred */ - return (p->result >= 0) ? avpkt->size : p->result; + if (err >= 0) + err = avpkt->size; +finish: + async_lock(fctx); + return err; } void ff_thread_report_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_relaxed) >= n) + return; - p = f->owner->internal->thread_ctx; + p = f->owner[field]->internal->thread_ctx; - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); + if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) + av_log(f->owner[field], AV_LOG_DEBUG, + "%p finished %d field %d\n", progress, n, field); pthread_mutex_lock(&p->progress_mutex); - progress[field] = n; + + atomic_store_explicit(&progress[field], n, memory_order_release); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -489,17 +585,20 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) void ff_thread_await_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; - volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; - p = f->owner->internal->thread_ctx; + p = f->owner[field]->internal->thread_ctx; - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); + if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) + av_log(f->owner[field], AV_LOG_DEBUG, + "thread awaiting %d field %d from %p\n", n, field, progress); pthread_mutex_lock(&p->progress_mutex); - while (progress[field] < n) + while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -509,12 +608,26 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; - if(p->state == STATE_SETUP_FINISHED){ - av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); + if (avctx->hwaccel && !p->hwaccel_serializing) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + + /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */ + if (avctx->hwaccel && + !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) { + p->async_serializing = 1; + + async_lock(p->parent); } pthread_mutex_lock(&p->progress_mutex); - p->state = STATE_SETUP_FINISHED; + if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ + av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); + } + + atomic_store(&p->state, STATE_SETUP_FINISHED); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -524,17 +637,21 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count { int i; + async_unlock(fctx); + for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load(&p->state) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } p->got_frame = 0; } + + async_lock(fctx); } void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) @@ -587,13 +704,20 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&p->avctx->slice_offset); } - if (p->avctx) + if (p->avctx) { av_freep(&p->avctx->internal); + av_buffer_unref(&p->avctx->hw_frames_ctx); + } + av_freep(&p->avctx); } av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); + pthread_mutex_destroy(&fctx->hwaccel_mutex); + pthread_mutex_destroy(&fctx->async_mutex); + pthread_cond_destroy(&fctx->async_cond); + av_freep(&avctx->internal->thread_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) @@ -615,8 +739,10 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (!thread_count) { int nb_cpus = av_cpu_count(); +#if FF_API_DEBUG_MV if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) nb_cpus = 1; +#endif // use number of cores + 1 as thread count if there is more than one if (nb_cpus > 1) thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); @@ -640,6 +766,11 @@ int ff_frame_thread_init(AVCodecContext *avctx) } pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_cond_init(&fctx->async_cond, NULL); + + fctx->async_lock = 1; fctx->delaying = 1; for (i = 0; i < thread_count; i++) { @@ -677,7 +808,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) } *copy->internal = *src->internal; copy->internal->thread_ctx = p; - copy->internal->pkt = &p->avpkt; + copy->internal->last_pkt_props = &p->avpkt; if (!i) { src = copy; @@ -701,6 +832,8 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (err) goto error; + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); + err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); p->thread_init= !err; if(!p->thread_init) @@ -736,6 +869,7 @@ void ff_thread_flush(AVCodecContext *avctx) // Make sure decode flush calls with size=0 won't return old frames p->got_frame = 0; av_frame_unref(p->frame); + p->result = 0; release_delayed_buffers(p); @@ -747,7 +881,7 @@ void ff_thread_flush(AVCodecContext *avctx) int ff_thread_can_start_frame(AVCodecContext *avctx) { PerThreadContext *p = avctx->internal->thread_ctx; - if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP && + if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { return 0; } @@ -759,28 +893,29 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int PerThreadContext *p = avctx->internal->thread_ctx; int err; - f->owner = avctx; + f->owner[0] = f->owner[1] = avctx; ff_init_buffer_info(avctx, f->f); if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); - if (p->state != STATE_SETTING_UP && + if (atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; } if (avctx->internal->allocate_progress) { - int *progress; - f->progress = av_buffer_alloc(2 * sizeof(int)); + atomic_int *progress; + f->progress = av_buffer_alloc(2 * sizeof(*progress)); if (!f->progress) { return AVERROR(ENOMEM); } - progress = (int*)f->progress->data; + progress = (atomic_int*)f->progress->data; - progress[0] = progress[1] = -1; + atomic_init(&progress[0], -1); + atomic_init(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); @@ -791,10 +926,10 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int pthread_mutex_lock(&p->progress_mutex); p->requested_frame = f->f; p->requested_flags = flags; - p->state = STATE_GET_BUFFER; + atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); pthread_cond_broadcast(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); err = p->result; @@ -819,16 +954,16 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks || avctx->get_format == avcodec_default_get_format) return ff_get_format(avctx, fmt); - if (p->state != STATE_SETTING_UP) { + if (atomic_load(&p->state) != STATE_SETTING_UP) { av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n"); return -1; } pthread_mutex_lock(&p->progress_mutex); p->available_formats = fmt; - p->state = STATE_GET_FORMAT; + atomic_store(&p->state, STATE_GET_FORMAT); pthread_cond_broadcast(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); res = p->result_format; @@ -862,7 +997,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); av_buffer_unref(&f->progress); - f->owner = NULL; + f->owner[0] = f->owner[1] = NULL; if (can_direct_free) { av_frame_unref(f->f); diff --git a/media/ffvpx/libavcodec/pthread_slice.c b/media/ffvpx/libavcodec/pthread_slice.c index 96a7643f6..d659f9b0b 100644 --- a/media/ffvpx/libavcodec/pthread_slice.c +++ b/media/ffvpx/libavcodec/pthread_slice.c @@ -34,26 +34,21 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/thread.h" +#include "libavutil/slicethread.h" typedef int (action_func)(AVCodecContext *c, void *arg); typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); +typedef int (main_func)(AVCodecContext *c); typedef struct SliceThreadContext { - pthread_t *workers; + AVSliceThread *thread; action_func *func; action_func2 *func2; + main_func *mainfunc; void *args; int *rets; - int job_count; int job_size; - pthread_cond_t last_job_cond; - pthread_cond_t current_job_cond; - pthread_mutex_t current_job_lock; - unsigned current_execute; - int current_job; - int done; - int *entries; int entries_count; int thread_count; @@ -61,43 +56,22 @@ typedef struct SliceThreadContext { pthread_mutex_t *progress_mutex; } SliceThreadContext; -static void* attribute_align_arg worker(void *v) -{ - AVCodecContext *avctx = v; +static void main_function(void *priv) { + AVCodecContext *avctx = priv; SliceThreadContext *c = avctx->internal->thread_ctx; - unsigned last_execute = 0; - int our_job = c->job_count; - int thread_count = avctx->thread_count; - int self_id; - - pthread_mutex_lock(&c->current_job_lock); - self_id = c->current_job++; - for (;;){ - int ret; - while (our_job >= c->job_count) { - if (c->current_job == thread_count + c->job_count) - pthread_cond_signal(&c->last_job_cond); - - while (last_execute == c->current_execute && !c->done) - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); - last_execute = c->current_execute; - our_job = self_id; - - if (c->done) { - pthread_mutex_unlock(&c->current_job_lock); - return NULL; - } - } - pthread_mutex_unlock(&c->current_job_lock); + c->mainfunc(avctx); +} - ret = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size): - c->func2(avctx, c->args, our_job, self_id); - if (c->rets) - c->rets[our_job%c->job_count] = ret; +static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) +{ + AVCodecContext *avctx = priv; + SliceThreadContext *c = avctx->internal->thread_ctx; + int ret; - pthread_mutex_lock(&c->current_job_lock); - our_job = c->current_job++; - } + ret = c->func ? c->func(avctx, (char *)c->args + c->job_size * jobnr) + : c->func2(avctx, c->args, jobnr, threadnr); + if (c->rets) + c->rets[jobnr] = ret; } void ff_slice_thread_free(AVCodecContext *avctx) @@ -105,40 +79,19 @@ void ff_slice_thread_free(AVCodecContext *avctx) SliceThreadContext *c = avctx->internal->thread_ctx; int i; - pthread_mutex_lock(&c->current_job_lock); - c->done = 1; - pthread_cond_broadcast(&c->current_job_cond); - for (i = 0; i < c->thread_count; i++) - pthread_cond_broadcast(&c->progress_cond[i]); - pthread_mutex_unlock(&c->current_job_lock); - - for (i=0; ithread_count; i++) - pthread_join(c->workers[i], NULL); + avpriv_slicethread_free(&c->thread); for (i = 0; i < c->thread_count; i++) { pthread_mutex_destroy(&c->progress_mutex[i]); pthread_cond_destroy(&c->progress_cond[i]); } - pthread_mutex_destroy(&c->current_job_lock); - pthread_cond_destroy(&c->current_job_cond); - pthread_cond_destroy(&c->last_job_cond); - av_freep(&c->entries); av_freep(&c->progress_mutex); av_freep(&c->progress_cond); - - av_freep(&c->workers); av_freep(&avctx->internal->thread_ctx); } -static av_always_inline void thread_park_workers(SliceThreadContext *c, int thread_count) -{ - while (c->current_job != thread_count + c->job_count) - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); - pthread_mutex_unlock(&c->current_job_lock); -} - static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) { SliceThreadContext *c = avctx->internal->thread_ctx; @@ -149,23 +102,12 @@ static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, i if (job_count <= 0) return 0; - pthread_mutex_lock(&c->current_job_lock); - - c->current_job = avctx->thread_count; - c->job_count = job_count; c->job_size = job_size; c->args = arg; c->func = func; - if (ret) { - c->rets = ret; - } else { - c->rets = NULL; - } - c->current_execute++; - pthread_cond_broadcast(&c->current_job_cond); - - thread_park_workers(c, avctx->thread_count); + c->rets = ret; + avpriv_slicethread_execute(c->thread, job_count, !!c->mainfunc ); return 0; } @@ -176,11 +118,19 @@ static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg return thread_execute(avctx, NULL, arg, ret, job_count, 0); } +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, action_func2* func2, main_func *mainfunc, void *arg, int *ret, int job_count) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + c->func2 = func2; + c->mainfunc = mainfunc; + return thread_execute(avctx, NULL, arg, ret, job_count, 0); +} + int ff_slice_thread_init(AVCodecContext *avctx) { - int i; SliceThreadContext *c; int thread_count = avctx->thread_count; + static void (*mainfunc)(void *); #if HAVE_W32THREADS w32thread_init(); @@ -208,35 +158,17 @@ int ff_slice_thread_init(AVCodecContext *avctx) return 0; } - c = av_mallocz(sizeof(SliceThreadContext)); - if (!c) - return -1; - - c->workers = av_mallocz_array(thread_count, sizeof(pthread_t)); - if (!c->workers) { - av_free(c); - return -1; - } - - avctx->internal->thread_ctx = c; - c->current_job = 0; - c->job_count = 0; - c->job_size = 0; - c->done = 0; - pthread_cond_init(&c->current_job_cond, NULL); - pthread_cond_init(&c->last_job_cond, NULL); - pthread_mutex_init(&c->current_job_lock, NULL); - pthread_mutex_lock(&c->current_job_lock); - for (i=0; iworkers[i], NULL, worker, avctx)) { - avctx->thread_count = i; - pthread_mutex_unlock(&c->current_job_lock); - ff_thread_free(avctx); - return -1; - } + avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c)); + mainfunc = avctx->codec->caps_internal & FF_CODEC_CAP_SLICE_THREAD_HAS_MF ? &main_function : NULL; + if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, mainfunc, thread_count)) <= 1) { + if (c) + avpriv_slicethread_free(&c->thread); + av_freep(&avctx->internal->thread_ctx); + avctx->thread_count = 1; + avctx->active_thread_type = 0; + return 0; } - - thread_park_workers(c, thread_count); + avctx->thread_count = thread_count; avctx->execute = thread_execute; avctx->execute2 = thread_execute2; diff --git a/media/ffvpx/libavcodec/put_bits.h b/media/ffvpx/libavcodec/put_bits.h index 68ed39119..1ceb1cc76 100644 --- a/media/ffvpx/libavcodec/put_bits.h +++ b/media/ffvpx/libavcodec/put_bits.h @@ -119,6 +119,18 @@ static inline void flush_put_bits(PutBitContext *s) s->bit_buf = 0; } +static inline void flush_put_bits_le(PutBitContext *s) +{ + while (s->bit_left < 32) { + av_assert0(s->buf_ptr < s->buf_end); + *s->buf_ptr++ = s->bit_buf; + s->bit_buf >>= 8; + s->bit_left += 8; + } + s->bit_left = 32; + s->bit_buf = 0; +} + #ifdef BITSTREAM_WRITER_LE #define avpriv_align_put_bits align_put_bits_unsupported_here #define avpriv_put_string ff_put_string_unsupported_here @@ -197,6 +209,34 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) s->bit_left = bit_left; } +static inline void put_bits_le(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + + av_assert2(n <= 31 && value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value >> bit_left; + bit_left += 32; + } + bit_left -= n; + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + static inline void put_sbits(PutBitContext *pb, int n, int32_t value) { av_assert2(n >= 0 && n <= 31); @@ -209,15 +249,72 @@ static inline void put_sbits(PutBitContext *pb, int n, int32_t value) */ static void av_unused put_bits32(PutBitContext *s, uint32_t value) { - int lo = value & 0xffff; - int hi = value >> 16; + unsigned int bit_buf; + int bit_left; + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + #ifdef BITSTREAM_WRITER_LE - put_bits(s, 16, lo); - put_bits(s, 16, hi); + bit_buf |= value << (32 - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = (uint64_t)value >> bit_left; #else - put_bits(s, 16, hi); - put_bits(s, 16, lo); + bit_buf = (uint64_t)bit_buf << bit_left; + bit_buf |= value >> (32 - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WB32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value; #endif + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + +/** + * Write up to 64 bits into a bitstream. + */ +static inline void put_bits64(PutBitContext *s, int n, uint64_t value) +{ + av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); + + if (n < 32) + put_bits(s, n, value); + else if (n == 32) + put_bits32(s, value); + else if (n < 64) { + uint32_t lo = value & 0xffffffff; + uint32_t hi = value >> 32; +#ifdef BITSTREAM_WRITER_LE + put_bits32(s, lo); + put_bits(s, n - 32, hi); +#else + put_bits(s, n - 32, hi); + put_bits32(s, lo); +#endif + } else { + uint32_t lo = value & 0xffffffff; + uint32_t hi = value >> 32; +#ifdef BITSTREAM_WRITER_LE + put_bits32(s, lo); + put_bits32(s, hi); +#else + put_bits32(s, hi); + put_bits32(s, lo); +#endif + + } } /** diff --git a/media/ffvpx/libavcodec/ratecontrol.h b/media/ffvpx/libavcodec/ratecontrol.h index c15f9e258..2a7aaec64 100644 --- a/media/ffvpx/libavcodec/ratecontrol.h +++ b/media/ffvpx/libavcodec/ratecontrol.h @@ -96,8 +96,4 @@ void ff_rate_control_uninit(struct MpegEncContext *s); int ff_vbv_update(struct MpegEncContext *s, int frame_size); void ff_get_2pass_fcode(struct MpegEncContext *s); -int ff_xvid_rate_control_init(struct MpegEncContext *s); -void ff_xvid_rate_control_uninit(struct MpegEncContext *s); -float ff_xvid_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); - #endif /* AVCODEC_RATECONTROL_H */ diff --git a/media/ffvpx/libavcodec/raw.c b/media/ffvpx/libavcodec/raw.c index f73a134a9..8da2a9735 100644 --- a/media/ffvpx/libavcodec/raw.c +++ b/media/ffvpx/libavcodec/raw.c @@ -119,6 +119,12 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_RGB48BE, MKTAG( 48, 'R', 'G', 'B') }, { AV_PIX_FMT_BGR48LE, MKTAG('B', 'G', 'R', 48 ) }, { AV_PIX_FMT_BGR48BE, MKTAG( 48, 'B', 'G', 'R') }, + { AV_PIX_FMT_GRAY9LE, MKTAG('Y', '1', 0 , 9 ) }, + { AV_PIX_FMT_GRAY9BE, MKTAG( 9 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY10LE, MKTAG('Y', '1', 0 , 10 ) }, + { AV_PIX_FMT_GRAY10BE, MKTAG(10 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY12LE, MKTAG('Y', '1', 0 , 12 ) }, + { AV_PIX_FMT_GRAY12BE, MKTAG(12 , 0 , '1', 'Y') }, { AV_PIX_FMT_GRAY16LE, MKTAG('Y', '1', 0 , 16 ) }, { AV_PIX_FMT_GRAY16BE, MKTAG(16 , 0 , '1', 'Y') }, { AV_PIX_FMT_YUV420P9LE, MKTAG('Y', '3', 11 , 9 ) }, @@ -266,6 +272,14 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_YUV422P10BE, MKTAG('I', '2', 'A', 'B') }, { AV_PIX_FMT_YUV444P10LE, MKTAG('I', '4', 'A', 'L') }, { AV_PIX_FMT_YUV444P10BE, MKTAG('I', '4', 'A', 'B') }, + { AV_PIX_FMT_YUV420P12LE, MKTAG('I', '0', 'C', 'L') }, + { AV_PIX_FMT_YUV420P12BE, MKTAG('I', '0', 'C', 'B') }, + { AV_PIX_FMT_YUV422P12LE, MKTAG('I', '2', 'C', 'L') }, + { AV_PIX_FMT_YUV422P12BE, MKTAG('I', '2', 'C', 'B') }, + { AV_PIX_FMT_YUV444P12LE, MKTAG('I', '4', 'C', 'L') }, + { AV_PIX_FMT_YUV444P12BE, MKTAG('I', '4', 'C', 'B') }, + { AV_PIX_FMT_YUV420P16LE, MKTAG('I', '0', 'F', 'L') }, + { AV_PIX_FMT_YUV420P16BE, MKTAG('I', '0', 'F', 'B') }, { AV_PIX_FMT_YUV444P16LE, MKTAG('I', '4', 'F', 'L') }, { AV_PIX_FMT_YUV444P16BE, MKTAG('I', '4', 'F', 'B') }, diff --git a/media/ffvpx/libavcodec/thread.h b/media/ffvpx/libavcodec/thread.h index c848d7ae8..318619316 100644 --- a/media/ffvpx/libavcodec/thread.h +++ b/media/ffvpx/libavcodec/thread.h @@ -34,7 +34,7 @@ typedef struct ThreadFrame { AVFrame *f; - AVCodecContext *owner; + AVCodecContext *owner[2]; // progress->data is an array of 2 ints holding progress for top/bottom // fields AVBufferRef *progress; @@ -133,8 +133,10 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f); int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); int ff_thread_init(AVCodecContext *s); +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, + int (*action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr), + int (*main_func)(AVCodecContext *c), void *arg, int *ret, int job_count); void ff_thread_free(AVCodecContext *s); - int ff_alloc_entries(AVCodecContext *avctx, int count); void ff_reset_entries(AVCodecContext *avctx); void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); diff --git a/media/ffvpx/libavcodec/utils.c b/media/ffvpx/libavcodec/utils.c index 87de15fc6..0c47e761f 100644 --- a/media/ffvpx/libavcodec/utils.c +++ b/media/ffvpx/libavcodec/utils.c @@ -44,6 +44,7 @@ #include "libavutil/dict.h" #include "libavutil/thread.h" #include "avcodec.h" +#include "decode.h" #include "libavutil/opt.h" #include "me_cmp.h" #include "mpegvideo.h" @@ -172,7 +173,7 @@ int av_codec_is_encoder(const AVCodec *codec) int av_codec_is_decoder(const AVCodec *codec) { - return codec && (codec->decode || codec->send_packet); + return codec && (codec->decode || codec->receive_frame); } av_cold void avcodec_register(AVCodec *codec) @@ -209,7 +210,7 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height) int ff_set_dimensions(AVCodecContext *s, int width, int height) { - int ret = av_image_check_size(width, height, 0, s); + int ret = av_image_check_size2(width, height, s->max_pixels, AV_PIX_FMT_NONE, 0, s); if (ret < 0) width = height = 0; @@ -376,6 +377,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align = 4; h_align = 4; } + if (s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { + w_align = 8; + h_align = 8; + } break; case AV_PIX_FMT_PAL8: case AV_PIX_FMT_BGR8: @@ -385,7 +390,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align = 4; h_align = 4; } - if (s->codec_id == AV_CODEC_ID_JV) { + if (s->codec_id == AV_CODEC_ID_JV || + s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { w_align = 8; h_align = 8; } @@ -503,200 +509,6 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, return ret; } -static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) -{ - FramePool *pool = avctx->internal->pool; - int i, ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: { - uint8_t *data[4]; - int linesize[4]; - int size[4] = { 0 }; - int w = frame->width; - int h = frame->height; - int tmpsize, unaligned; - - if (pool->format == frame->format && - pool->width == frame->width && pool->height == frame->height) - return 0; - - avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); - - do { - // NOTE: do not align linesizes individually, this breaks e.g. assumptions - // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 - ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); - if (ret < 0) - return ret; - // increase alignment of w for next try (rhs gives the lowest bit set in w) - w += w & ~(w - 1); - - unaligned = 0; - for (i = 0; i < 4; i++) - unaligned |= linesize[i] % pool->stride_align[i]; - } while (unaligned); - - tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, - NULL, linesize); - if (tmpsize < 0) - return -1; - - for (i = 0; i < 3 && data[i + 1]; i++) - size[i] = data[i + 1] - data[i]; - size[i] = tmpsize - (data[i] - data[0]); - - for (i = 0; i < 4; i++) { - av_buffer_pool_uninit(&pool->pools[i]); - pool->linesize[i] = linesize[i]; - if (size[i]) { - pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, - CONFIG_MEMORY_POISONING ? - NULL : - av_buffer_allocz); - if (!pool->pools[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - } - pool->format = frame->format; - pool->width = frame->width; - pool->height = frame->height; - - break; - } - case AVMEDIA_TYPE_AUDIO: { - int ch = av_frame_get_channels(frame); //av_get_channel_layout_nb_channels(frame->channel_layout); - int planar = av_sample_fmt_is_planar(frame->format); - int planes = planar ? ch : 1; - - if (pool->format == frame->format && pool->planes == planes && - pool->channels == ch && frame->nb_samples == pool->samples) - return 0; - - av_buffer_pool_uninit(&pool->pools[0]); - ret = av_samples_get_buffer_size(&pool->linesize[0], ch, - frame->nb_samples, frame->format, 0); - if (ret < 0) - goto fail; - - pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); - if (!pool->pools[0]) { - ret = AVERROR(ENOMEM); - goto fail; - } - - pool->format = frame->format; - pool->planes = planes; - pool->channels = ch; - pool->samples = frame->nb_samples; - break; - } - default: av_assert0(0); - } - return 0; -fail: - for (i = 0; i < 4; i++) - av_buffer_pool_uninit(&pool->pools[i]); - pool->format = -1; - pool->planes = pool->channels = pool->samples = 0; - pool->width = pool->height = 0; - return ret; -} - -static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - FramePool *pool = avctx->internal->pool; - int planes = pool->planes; - int i; - - frame->linesize[0] = pool->linesize[0]; - - if (planes > AV_NUM_DATA_POINTERS) { - frame->extended_data = av_mallocz_array(planes, sizeof(*frame->extended_data)); - frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; - frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, - sizeof(*frame->extended_buf)); - if (!frame->extended_data || !frame->extended_buf) { - av_freep(&frame->extended_data); - av_freep(&frame->extended_buf); - return AVERROR(ENOMEM); - } - } else { - frame->extended_data = frame->data; - av_assert0(frame->nb_extended_buf == 0); - } - - for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { - frame->buf[i] = av_buffer_pool_get(pool->pools[0]); - if (!frame->buf[i]) - goto fail; - frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; - } - for (i = 0; i < frame->nb_extended_buf; i++) { - frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); - if (!frame->extended_buf[i]) - goto fail; - frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; - } - - if (avctx->debug & FF_DEBUG_BUFFERS) - av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); - - return 0; -fail: - av_frame_unref(frame); - return AVERROR(ENOMEM); -} - -static int video_get_buffer(AVCodecContext *s, AVFrame *pic) -{ - FramePool *pool = s->internal->pool; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); - int i; - - if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { - av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); - return -1; - } - - if (!desc) { - av_log(s, AV_LOG_ERROR, - "Unable to get pixel format descriptor for format %s\n", - av_get_pix_fmt_name(pic->format)); - return AVERROR(EINVAL); - } - - memset(pic->data, 0, sizeof(pic->data)); - pic->extended_data = pic->data; - - for (i = 0; i < 4 && pool->pools[i]; i++) { - pic->linesize[i] = pool->linesize[i]; - - pic->buf[i] = av_buffer_pool_get(pool->pools[i]); - if (!pic->buf[i]) - goto fail; - - pic->data[i] = pic->buf[i]->data; - } - for (; i < AV_NUM_DATA_POINTERS; i++) { - pic->data[i] = NULL; - pic->linesize[i] = 0; - } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) - avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); - - if (s->debug & FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); - - return 0; -fail: - av_frame_unref(pic); - return AVERROR(ENOMEM); -} - void ff_color_frame(AVFrame *frame, const int c[4]) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); @@ -720,287 +532,6 @@ void ff_color_frame(AVFrame *frame, const int c[4]) } } -int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - int ret; - - if (avctx->hw_frames_ctx) - return av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); - - if ((ret = update_frame_pool(avctx, frame)) < 0) - return ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - return video_get_buffer(avctx, frame); - case AVMEDIA_TYPE_AUDIO: - return audio_get_buffer(avctx, frame); - default: - return -1; - } -} - -static int add_metadata_from_side_data(AVPacket *avpkt, AVFrame *frame) -{ - int size; - const uint8_t *side_metadata; - - AVDictionary **frame_md = avpriv_frame_get_metadatap(frame); - - side_metadata = av_packet_get_side_data(avpkt, - AV_PKT_DATA_STRINGS_METADATA, &size); - return av_packet_unpack_dictionary(side_metadata, size, frame_md); -} - -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 }, - { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, - { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, - }; - - if (pkt) { - frame->pts = pkt->pts; -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = pkt->pts; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - av_frame_set_pkt_pos (frame, pkt->pos); - av_frame_set_pkt_duration(frame, pkt->duration); - av_frame_set_pkt_size (frame, pkt->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); - } - } - add_metadata_from_side_data(pkt, frame); - - if (pkt->flags & AV_PKT_FLAG_DISCARD) { - frame->flags |= AV_FRAME_FLAG_DISCARD; - } else { - frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); - } - } else { - frame->pts = AV_NOPTS_VALUE; -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = AV_NOPTS_VALUE; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - av_frame_set_pkt_pos (frame, -1); - av_frame_set_pkt_duration(frame, 0); - av_frame_set_pkt_size (frame, -1); - } - frame->reordered_opaque = avctx->reordered_opaque; - - if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED) - frame->color_primaries = avctx->color_primaries; - if (frame->color_trc == AVCOL_TRC_UNSPECIFIED) - frame->color_trc = avctx->color_trc; - if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED) - av_frame_set_colorspace(frame, avctx->colorspace); - if (av_frame_get_color_range(frame) == AVCOL_RANGE_UNSPECIFIED) - av_frame_set_color_range(frame, avctx->color_range); - if (frame->chroma_location == AVCHROMA_LOC_UNSPECIFIED) - frame->chroma_location = avctx->chroma_sample_location; - - switch (avctx->codec->type) { - case AVMEDIA_TYPE_VIDEO: - frame->format = avctx->pix_fmt; - if (!frame->sample_aspect_ratio.num) - frame->sample_aspect_ratio = avctx->sample_aspect_ratio; - - if (frame->width && frame->height && - av_image_check_sar(frame->width, frame->height, - frame->sample_aspect_ratio) < 0) { - av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", - frame->sample_aspect_ratio.num, - frame->sample_aspect_ratio.den); - frame->sample_aspect_ratio = (AVRational){ 0, 1 }; - } - - break; - case AVMEDIA_TYPE_AUDIO: - if (!frame->sample_rate) - frame->sample_rate = avctx->sample_rate; - if (frame->format < 0) - frame->format = avctx->sample_fmt; - if (!frame->channel_layout) { - if (avctx->channel_layout) { - if (av_get_channel_layout_nb_channels(avctx->channel_layout) != - avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " - "configuration.\n"); - return AVERROR(EINVAL); - } - - frame->channel_layout = avctx->channel_layout; - } else { - if (avctx->channels > FF_SANE_NB_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", - avctx->channels); - return AVERROR(ENOSYS); - } - } - } - av_frame_set_channels(frame, avctx->channels); - break; - } - return 0; -} - -int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) -{ - return ff_init_buffer_info(avctx, frame); -} - -static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) -{ - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - int i; - int num_planes = av_pix_fmt_count_planes(frame->format); - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - int flags = desc ? desc->flags : 0; - if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) - num_planes = 2; - for (i = 0; i < num_planes; i++) { - av_assert0(frame->data[i]); - } - // For now do not enforce anything for palette of pseudopal formats - if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) - num_planes = 2; - // For formats without data like hwaccel allow unused pointers to be non-NULL. - for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) { - if (frame->data[i]) - av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n"); - frame->data[i] = NULL; - } - } -} - -static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - const AVHWAccel *hwaccel = avctx->hwaccel; - int override_dimensions = 1; - int ret; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0 || avctx->pix_fmt<0) { - av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); - return AVERROR(EINVAL); - } - - if (frame->width <= 0 || frame->height <= 0) { - frame->width = FFMAX(avctx->width, AV_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); - frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); - override_dimensions = 0; - } - - if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) { - av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n"); - return AVERROR(EINVAL); - } - } - ret = ff_decode_frame_props(avctx, frame); - if (ret < 0) - return ret; - - if (hwaccel) { - if (hwaccel->alloc_frame) { - ret = hwaccel->alloc_frame(avctx, frame); - goto end; - } - } else - avctx->sw_pix_fmt = avctx->pix_fmt; - - ret = avctx->get_buffer2(avctx, frame, flags); - if (ret >= 0) - validate_avframe_allocation(avctx, frame); - -end: - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) { - frame->width = avctx->width; - frame->height = avctx->height; - } - - return ret; -} - -int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - int ret = get_buffer_internal(avctx, frame, flags); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - frame->width = frame->height = 0; - } - return ret; -} - -static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) -{ - AVFrame *tmp; - int ret; - - av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); - - if (frame->data[0] && (frame->width != avctx->width || frame->height != avctx->height || frame->format != avctx->pix_fmt)) { - av_log(avctx, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n", - frame->width, frame->height, av_get_pix_fmt_name(frame->format), avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); - av_frame_unref(frame); - } - - ff_init_buffer_info(avctx, frame); - - if (!frame->data[0]) - return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - - if (av_frame_is_writable(frame)) - return ff_decode_frame_props(avctx, frame); - - tmp = av_frame_alloc(); - if (!tmp) - return AVERROR(ENOMEM); - - av_frame_move_ref(tmp, frame); - - ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - if (ret < 0) { - av_frame_free(&tmp); - return ret; - } - - av_frame_copy(frame, tmp); - av_frame_free(&tmp); - - return 0; -} - -int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - int ret = reget_buffer_internal(avctx, frame); - if (ret < 0) - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return ret; -} - int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) { int i; @@ -1038,145 +569,6 @@ enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, return AV_PIX_FMT_NONE; } -static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; -} - -enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) -{ - while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) - ++fmt; - return fmt[0]; -} - -static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, - enum AVPixelFormat pix_fmt) -{ - AVHWAccel *hwaccel = NULL; - - while ((hwaccel = av_hwaccel_next(hwaccel))) - if (hwaccel->id == codec_id - && hwaccel->pix_fmt == pix_fmt) - return hwaccel; - 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 (avctx->active_thread_type & FF_THREAD_FRAME) { - av_log(avctx, AV_LOG_WARNING, - "Hardware accelerated decoding with frame threading is known to be unstable and its use is discouraged.\n"); - } - - if (!hwa) { - av_log(avctx, AV_LOG_ERROR, - "Could not find an AVHWAccel for the pixel format: %s", - name); - return AVERROR(ENOENT); - } - - if (hwa->capabilities & HWACCEL_CODEC_CAP_EXPERIMENTAL && - avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", - hwa->name); - return AVERROR_PATCHWELCOME; - } - - 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 *choices; - enum AVPixelFormat ret; - unsigned n = 0; - - while (fmt[n] != AV_PIX_FMT_NONE) - ++n; - - av_assert0(n >= 1); - avctx->sw_pix_fmt = fmt[n - 1]; - av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); - - choices = av_malloc_array(n + 1, sizeof(*choices)); - if (!choices) - return AV_PIX_FMT_NONE; - - memcpy(choices, fmt, (n + 1) * sizeof(*choices)); - - for (;;) { - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; - - av_buffer_unref(&avctx->hw_frames_ctx); - - ret = avctx->get_format(avctx, choices); - - desc = av_pix_fmt_desc_get(ret); - if (!desc) { - ret = AV_PIX_FMT_NONE; - break; - } - - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - break; -#if FF_API_CAP_VDPAU - if (avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU) - break; -#endif - - if (avctx->hw_frames_ctx) { - AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (hw_frames_ctx->format != ret) { - av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " - "does not match the format of provided AVHWFramesContext\n"); - ret = AV_PIX_FMT_NONE; - 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; -} - MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase) MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor) MAKE_ACCESSORS(AVCodecContext, codec, int, lowres) @@ -1197,12 +589,6 @@ int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec){ return !!(codec->caps_internal & FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM); } -static void get_subtitle_defaults(AVSubtitle *sub) -{ - memset(sub, 0, sizeof(*sub)); - sub->pts = AV_NOPTS_VALUE; -} - static int64_t get_bit_rate(AVCodecContext *ctx) { int64_t bit_rate; @@ -1269,7 +655,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if (ret < 0) return ret; - avctx->internal = av_mallocz(sizeof(AVCodecInternal)); + avctx->internal = av_mallocz(sizeof(*avctx->internal)); if (!avctx->internal) { ret = AVERROR(ENOMEM); goto end; @@ -1287,6 +673,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->compat_decode_frame = av_frame_alloc(); + if (!avctx->internal->compat_decode_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + avctx->internal->buffer_frame = av_frame_alloc(); if (!avctx->internal->buffer_frame) { ret = AVERROR(ENOMEM); @@ -1299,14 +691,28 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } - if (codec->priv_data_size > 0) { - if (!avctx->priv_data) { - avctx->priv_data = av_mallocz(codec->priv_data_size); - if (!avctx->priv_data) { - ret = AVERROR(ENOMEM); - goto end; - } - if (codec->priv_class) { + avctx->internal->ds.in_pkt = av_packet_alloc(); + if (!avctx->internal->ds.in_pkt) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->last_pkt_props = av_packet_alloc(); + if (!avctx->internal->last_pkt_props) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->skip_samples_multiplier = 1; + + if (codec->priv_data_size > 0) { + if (!avctx->priv_data) { + avctx->priv_data = av_mallocz(codec->priv_data_size); + if (!avctx->priv_data) { + ret = AVERROR(ENOMEM); + goto end; + } + if (codec->priv_class) { *(const AVClass **)avctx->priv_data = codec->priv_class; av_opt_set_defaults(avctx->priv_data); } @@ -1337,8 +743,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) - && ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0 - || av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)) { + && ( av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0 + || av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)) { av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); ff_set_dimensions(avctx, 0, 0); } @@ -1559,1465 +965,199 @@ FF_ENABLE_DEPRECATION_WARNINGS goto free_and_end; } } - if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) - && avctx->bit_rate>0 && avctx->bit_rate<1000) { - av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", (int64_t)avctx->bit_rate, (int64_t)avctx->bit_rate); - } - - if (!avctx->rc_initial_buffer_occupancy) - avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3 / 4; - - if (avctx->ticks_per_frame && avctx->time_base.num && - avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { - av_log(avctx, AV_LOG_ERROR, - "ticks_per_frame %d too large for the timebase %d/%d.", - avctx->ticks_per_frame, - avctx->time_base.num, - avctx->time_base.den); - goto free_and_end; - } - - if (avctx->hw_frames_ctx) { - AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (frames_ctx->format != avctx->pix_fmt) { - av_log(avctx, AV_LOG_ERROR, - "Mismatching AVCodecContext.pix_fmt and AVHWFramesContext.format\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } - } - } - - avctx->pts_correction_num_faulty_pts = - avctx->pts_correction_num_faulty_dts = 0; - avctx->pts_correction_last_pts = - avctx->pts_correction_last_dts = INT64_MIN; - - if ( !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY - && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO) - av_log(avctx, AV_LOG_WARNING, - "gray decoding requested but not enabled at configuration time\n"); - - if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) - || avctx->internal->frame_thread_encoder)) { - ret = avctx->codec->init(avctx); - if (ret < 0) { - goto free_and_end; - } - } - - 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); - /* validate channel layout from the decoder */ - if (avctx->channel_layout) { - int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); - if (!avctx->channels) - avctx->channels = channels; - else if (channels != avctx->channels) { - char buf[512]; - av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); - av_log(avctx, AV_LOG_WARNING, - "Channel layout '%s' with %d channels does not match specified number of channels %d: " - "ignoring specified channel layout\n", - buf, channels, avctx->channels); - avctx->channel_layout = 0; - } - } - if (avctx->channels && avctx->channels < 0 || - avctx->channels > FF_SANE_NB_CHANNELS) { - ret = AVERROR(EINVAL); - goto free_and_end; - } - if (avctx->sub_charenc) { - if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { - av_log(avctx, AV_LOG_ERROR, "Character encoding is only " - "supported with subtitles codecs\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) { - av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, " - "subtitles character encoding will be ignored\n", - avctx->codec_descriptor->name); - avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING; - } else { - /* input character encoding is set for a text based subtitle - * codec at this point */ - if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC) - avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER; - - if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) { -#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); - goto free_and_end; - } - iconv_close(cd); -#else - av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles " - "conversion needs a libavcodec built with iconv support " - "for this codec\n"); - ret = AVERROR(ENOSYS); - goto free_and_end; -#endif - } - } - } - -#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 - } - if (codec->priv_data_size > 0 && avctx->priv_data && codec->priv_class) { - av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class); - } - -end: - ff_unlock_avcodec(codec); - if (options) { - av_dict_free(options); - *options = tmp; - } - - return ret; -free_and_end: - if (avctx->codec && - (avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP)) - avctx->codec->close(avctx); - - if (codec->priv_class && codec->priv_data_size) - av_opt_free(avctx->priv_data); - av_opt_free(avctx); - -#if FF_API_CODED_FRAME -FF_DISABLE_DEPRECATION_WARNINGS - av_frame_free(&avctx->coded_frame); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - av_dict_free(&tmp); - av_freep(&avctx->priv_data); - if (avctx->internal) { - av_packet_free(&avctx->internal->buffer_pkt); - av_frame_free(&avctx->internal->buffer_frame); - av_frame_free(&avctx->internal->to_free); - av_freep(&avctx->internal->pool); - } - av_freep(&avctx->internal); - avctx->codec = NULL; - goto end; -} - -int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size) -{ - if (avpkt->size < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size); - return AVERROR(EINVAL); - } - if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n", - size, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); - return AVERROR(EINVAL); - } - - if (avctx && 2*min_size < size) { // FIXME The factor needs to be finetuned - av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer); - if (!avpkt->data || avpkt->size < size) { - av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); - avpkt->data = avctx->internal->byte_buffer; - avpkt->size = avctx->internal->byte_buffer_size; - } - } - - if (avpkt->data) { - AVBufferRef *buf = avpkt->buf; - - if (avpkt->size < size) { - av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %"PRId64")\n", avpkt->size, size); - return AVERROR(EINVAL); - } - - av_init_packet(avpkt); - avpkt->buf = buf; - avpkt->size = size; - return 0; - } else { - int ret = av_new_packet(avpkt, size); - if (ret < 0) - av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size); - return ret; - } -} - -int ff_alloc_packet(AVPacket *avpkt, int size) -{ - return ff_alloc_packet2(NULL, avpkt, size, 0); -} - -/** - * Pad last frame with silence. - */ -static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) -{ - AVFrame *frame = NULL; - int ret; - - if (!(frame = av_frame_alloc())) - return AVERROR(ENOMEM); - - frame->format = src->format; - frame->channel_layout = src->channel_layout; - av_frame_set_channels(frame, av_frame_get_channels(src)); - frame->nb_samples = s->frame_size; - ret = av_frame_get_buffer(frame, 32); - if (ret < 0) - goto fail; - - ret = av_frame_copy_props(frame, src); - if (ret < 0) - goto fail; - - if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, - src->nb_samples, s->channels, s->sample_fmt)) < 0) - goto fail; - if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples, - frame->nb_samples - src->nb_samples, - s->channels, s->sample_fmt)) < 0) - goto fail; - - *dst = frame; - - return 0; - -fail: - av_frame_free(&frame); - return ret; -} - -int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - AVFrame *extended_frame = NULL; - AVFrame *padded_frame = NULL; - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - return 0; - } - - /* ensure that extended_data is properly set */ - if (frame && !frame->extended_data) { - if (av_sample_fmt_is_planar(avctx->sample_fmt) && - avctx->channels > AV_NUM_DATA_POINTERS) { - av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " - "with more than %d channels, but extended_data is not set.\n", - AV_NUM_DATA_POINTERS); - return AVERROR(EINVAL); - } - av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); - - extended_frame = av_frame_alloc(); - if (!extended_frame) - return AVERROR(ENOMEM); - - memcpy(extended_frame, frame, sizeof(AVFrame)); - extended_frame->extended_data = extended_frame->data; - frame = extended_frame; - } - - /* extract audio service type metadata */ - if (frame) { - AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); - if (sd && sd->size >= sizeof(enum AVAudioServiceType)) - avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; - } - - /* check for valid frame size */ - if (frame) { - if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { - if (frame->nb_samples > avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n"); - ret = AVERROR(EINVAL); - goto end; - } - } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { - if (frame->nb_samples < avctx->frame_size && - !avctx->internal->last_audio_frame) { - ret = pad_last_frame(avctx, &padded_frame, frame); - if (ret < 0) - goto end; - - frame = padded_frame; - avctx->internal->last_audio_frame = 1; - } - - if (frame->nb_samples != avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size); - ret = AVERROR(EINVAL); - goto end; - } - } - } - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (!ret) { - if (*got_packet_ptr) { - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { - if (avpkt->pts == AV_NOPTS_VALUE) - avpkt->pts = frame->pts; - if (!avpkt->duration) - avpkt->duration = ff_samples_to_time_base(avctx, - frame->nb_samples); - } - avpkt->dts = avpkt->pts; - } else { - avpkt->size = 0; - } - } - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else { - if (av_dup_packet(avpkt) < 0) { - ret = AVERROR(ENOMEM); - } - } - } - - if (!ret) { - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - goto end; - } - - /* NOTE: if we add any audio encoders which output non-keyframe packets, - * this needs to be moved to the encoders, but for now we can do it - * here to simplify things */ - avpkt->flags |= AV_PKT_FLAG_KEY; - -end: - av_frame_free(&padded_frame); - av_free(extended_frame); - -#if FF_API_AUDIOENC_DELAY - avctx->delay = avctx->initial_padding; -#endif - - return ret; -} - -int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if(CONFIG_FRAME_THREAD_ENCODER && - avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME)) - return ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr); - - if ((avctx->flags&AV_CODEC_FLAG_PASS1) && avctx->stats_out) - avctx->stats_out[0] = '\0'; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - avpkt->size = 0; - return 0; - } - - if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) - return AVERROR(EINVAL); - - if (frame && frame->format == AV_PIX_FMT_NONE) - av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); - if (frame && (frame->width == 0 || frame->height == 0)) - av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - av_assert0(ret <= 0); - - emms_c(); - - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else { - if (av_dup_packet(avpkt) < 0) { - ret = AVERROR(ENOMEM); - } - } - } - - if (!ret) { - if (!*got_packet_ptr) - avpkt->size = 0; - else if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - avpkt->pts = avpkt->dts = frame->pts; - - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) - av_packet_unref(avpkt); - - return ret; -} - -int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub) -{ - int ret; - if (sub->start_display_time) { - av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); - return -1; - } - - ret = avctx->codec->encode_sub(avctx, buf, buf_size, sub); - avctx->frame_number++; - return ret; -} - -/** - * Attempt to guess proper monotonic timestamps for decoded video frames - * which might have incorrect times. Input timestamps may wrap around, in - * which case the output will as well. - * - * @param pts the pts field of the decoded AVPacket, as passed through - * AVFrame.pts - * @param dts the dts field of the decoded AVPacket - * @return one of the input values, may be AV_NOPTS_VALUE - */ -static int64_t guess_correct_pts(AVCodecContext *ctx, - int64_t reordered_pts, int64_t dts) -{ - int64_t pts = AV_NOPTS_VALUE; - - if (dts != AV_NOPTS_VALUE) { - ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; - ctx->pts_correction_last_dts = dts; - } else if (reordered_pts != AV_NOPTS_VALUE) - ctx->pts_correction_last_dts = reordered_pts; - - if (reordered_pts != AV_NOPTS_VALUE) { - ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; - ctx->pts_correction_last_pts = reordered_pts; - } else if(dts != AV_NOPTS_VALUE) - ctx->pts_correction_last_pts = dts; - - if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) - && reordered_pts != AV_NOPTS_VALUE) - pts = reordered_pts; - else - pts = dts; - - return pts; -} - -static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) -{ - int size = 0, ret; - const uint8_t *data; - uint32_t flags; - int64_t val; - - data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); - if (!data) - return 0; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { - av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " - "changes, but PARAM_CHANGE side data was sent to it.\n"); - ret = AVERROR(EINVAL); - goto fail2; - } - - if (size < 4) - goto fail; - - flags = bytestream_get_le32(&data); - size -= 4; - - if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { - if (size < 4) - goto fail; - val = bytestream_get_le32(&data); - if (val <= 0 || val > INT_MAX) { - av_log(avctx, AV_LOG_ERROR, "Invalid channel count"); - ret = AVERROR_INVALIDDATA; - goto fail2; - } - avctx->channels = val; - size -= 4; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { - if (size < 8) - goto fail; - avctx->channel_layout = bytestream_get_le64(&data); - size -= 8; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { - if (size < 4) - goto fail; - val = bytestream_get_le32(&data); - if (val <= 0 || val > INT_MAX) { - av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); - ret = AVERROR_INVALIDDATA; - goto fail2; - } - avctx->sample_rate = val; - size -= 4; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { - if (size < 8) - goto fail; - avctx->width = bytestream_get_le32(&data); - avctx->height = bytestream_get_le32(&data); - size -= 8; - ret = ff_set_dimensions(avctx, avctx->width, avctx->height); - if (ret < 0) - goto fail2; - } - - return 0; -fail: - av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); - ret = AVERROR_INVALIDDATA; -fail2: - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); - if (avctx->err_recognition & AV_EF_EXPLODE) - return ret; - } - return 0; -} - -static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) -{ - int ret; - - /* move the original frame to our backup */ - av_frame_unref(avci->to_free); - av_frame_move_ref(avci->to_free, frame); - - /* now copy everything except the AVBufferRefs back - * note that we make a COPY of the side data, so calling av_frame_free() on - * the caller's frame will work properly */ - ret = av_frame_copy_props(frame, avci->to_free); - if (ret < 0) - return ret; - - memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); - memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); - if (avci->to_free->extended_data != avci->to_free->data) { - int planes = av_frame_get_channels(avci->to_free); - int size = planes * sizeof(*frame->extended_data); - - if (!size) { - av_frame_unref(frame); - return AVERROR_BUG; - } - - frame->extended_data = av_malloc(size); - if (!frame->extended_data) { - av_frame_unref(frame); - return AVERROR(ENOMEM); - } - memcpy(frame->extended_data, avci->to_free->extended_data, - size); - } else - frame->extended_data = frame->data; - - frame->format = avci->to_free->format; - frame->width = avci->to_free->width; - frame->height = avci->to_free->height; - frame->channel_layout = avci->to_free->channel_layout; - frame->nb_samples = avci->to_free->nb_samples; - av_frame_set_channels(frame, av_frame_get_channels(avci->to_free)); - - return 0; -} - -int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - const AVPacket *avpkt) -{ - AVCodecInternal *avci = avctx->internal; - int ret; - // copy to ensure we do not change avpkt - AVPacket tmp = *avpkt; - - if (!avctx->codec) - return AVERROR(EINVAL); - if (avctx->codec->type != AVMEDIA_TYPE_VIDEO) { - av_log(avctx, AV_LOG_ERROR, "Invalid media type for video\n"); - return AVERROR(EINVAL); - } - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - *got_picture_ptr = 0; - if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) - return AVERROR(EINVAL); - - avctx->internal->pkt = avpkt; - ret = apply_param_change(avctx, avpkt); - if (ret < 0) - return ret; - - av_frame_unref(picture); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || - (avctx->active_thread_type & FF_THREAD_FRAME)) { - int did_split = av_packet_split_side_data(&tmp); - ret = apply_param_change(avctx, &tmp); - if (ret < 0) - goto fail; - - avctx->internal->pkt = &tmp; - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, - &tmp); - else { - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - &tmp); - if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) - picture->pkt_dts = avpkt->dts; - - if(!avctx->has_b_frames){ - av_frame_set_pkt_pos(picture, avpkt->pos); - } - //FIXME these should be under if(!avctx->has_b_frames) - /* get_buffer is supposed to set frame parameters */ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { - if (!picture->sample_aspect_ratio.num) picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - if (!picture->width) picture->width = avctx->width; - if (!picture->height) picture->height = avctx->height; - if (picture->format == AV_PIX_FMT_NONE) picture->format = avctx->pix_fmt; - } - } - -fail: - emms_c(); //needed to avoid an emms_c() call before every return; - - avctx->internal->pkt = NULL; - if (did_split) { - av_packet_free_side_data(&tmp); - if(ret == tmp.size) - ret = avpkt->size; - } - if (picture->flags & AV_FRAME_FLAG_DISCARD) { - *got_picture_ptr = 0; - } - if (*got_picture_ptr) { - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, picture); - if (err < 0) - return err; - } - - avctx->frame_number++; - av_frame_set_best_effort_timestamp(picture, - guess_correct_pts(avctx, - picture->pts, - picture->pkt_dts)); - } else - av_frame_unref(picture); - } else - ret = 0; - - /* many decoders assign whole AVFrames, thus overwriting extended_data; - * 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; -} - -int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, - AVFrame *frame, - int *got_frame_ptr, - const AVPacket *avpkt) -{ - AVCodecInternal *avci = avctx->internal; - int ret = 0; - - *got_frame_ptr = 0; - - if (!avctx->codec) - return AVERROR(EINVAL); - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - if (!avpkt->data && avpkt->size) { - av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); - return AVERROR(EINVAL); - } - if (avctx->codec->type != AVMEDIA_TYPE_AUDIO) { - av_log(avctx, AV_LOG_ERROR, "Invalid media type for audio\n"); - return AVERROR(EINVAL); - } - - av_frame_unref(frame); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { - 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); - ret = apply_param_change(avctx, &tmp); - if (ret < 0) - goto fail; - - avctx->internal->pkt = &tmp; - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp); - else { - ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp); - av_assert0(ret <= tmp.size); - frame->pkt_dts = avpkt->dts; - } - if (ret >= 0 && *got_frame_ptr) { - avctx->frame_number++; - av_frame_set_best_effort_timestamp(frame, - guess_correct_pts(avctx, - frame->pts, - frame->pkt_dts)); - if (frame->format == AV_SAMPLE_FMT_NONE) - frame->format = avctx->sample_fmt; - if (!frame->channel_layout) - frame->channel_layout = avctx->channel_layout; - if (!av_frame_get_channels(frame)) - av_frame_set_channels(frame, avctx->channels); - if (!frame->sample_rate) - frame->sample_rate = avctx->sample_rate; - } - - side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); - if(side && side_size>=10) { - avctx->internal->skip_samples = AV_RL32(side); - discard_padding = AV_RL32(side + 4); - av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", - avctx->internal->skip_samples, (int)discard_padding); - skip_reason = AV_RL8(side + 8); - discard_reason = AV_RL8(side + 9); - } - - if ((frame->flags & AV_FRAME_FLAG_DISCARD) && *got_frame_ptr && - !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { - avctx->internal->skip_samples -= frame->nb_samples; - *got_frame_ptr = 0; - } - - if (avctx->internal->skip_samples > 0 && *got_frame_ptr && - !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { - if(frame->nb_samples <= avctx->internal->skip_samples){ - *got_frame_ptr = 0; - avctx->internal->skip_samples -= frame->nb_samples; - av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", - avctx->internal->skip_samples); - } else { - av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples, - frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format); - if(avctx->pkt_timebase.num && avctx->sample_rate) { - int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples, - (AVRational){1, avctx->sample_rate}, - avctx->pkt_timebase); - if(frame->pts!=AV_NOPTS_VALUE) - frame->pts += diff_ts; -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - if(frame->pkt_pts!=AV_NOPTS_VALUE) - frame->pkt_pts += diff_ts; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - if(frame->pkt_dts!=AV_NOPTS_VALUE) - frame->pkt_dts += diff_ts; - if (av_frame_get_pkt_duration(frame) >= diff_ts) - av_frame_set_pkt_duration(frame, av_frame_get_pkt_duration(frame) - diff_ts); - } else { - av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); - } - av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", - avctx->internal->skip_samples, frame->nb_samples); - frame->nb_samples -= avctx->internal->skip_samples; - avctx->internal->skip_samples = 0; - } - } - - if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr && - !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { - if (discard_padding == frame->nb_samples) { - *got_frame_ptr = 0; - } else { - if(avctx->pkt_timebase.num && avctx->sample_rate) { - int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, - (AVRational){1, avctx->sample_rate}, - avctx->pkt_timebase); - av_frame_set_pkt_duration(frame, diff_ts); - } else { - av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); - } - av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", - (int)discard_padding, frame->nb_samples); - frame->nb_samples -= discard_padding; - } - } - - if ((avctx->flags2 & AV_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) { - av_packet_free_side_data(&tmp); - if(ret == tmp.size) - ret = avpkt->size; - } - - if (ret >= 0 && *got_frame_ptr) { - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, frame); - if (err < 0) - return err; - } - } else - av_frame_unref(frame); - } - - av_assert0(ret <= avpkt->size); - - if (!avci->showed_multi_packet_warning && - ret >= 0 && ret != avpkt->size && !(avctx->codec->capabilities & AV_CODEC_CAP_SUBFRAMES)) { - av_log(avctx, AV_LOG_WARNING, "Multiple frames in a packet.\n"); - avci->showed_multi_packet_warning = 1; - } - - return ret; -} - -#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ -static int recode_subtitle(AVCodecContext *avctx, - AVPacket *outpkt, const AVPacket *inpkt) -{ -#if CONFIG_ICONV - iconv_t cd = (iconv_t)-1; - int ret = 0; - char *inb, *outb; - size_t inl, outl; - AVPacket tmp; -#endif - - if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) - return 0; - -#if CONFIG_ICONV - cd = iconv_open("UTF-8", avctx->sub_charenc); - av_assert0(cd != (iconv_t)-1); - - inb = inpkt->data; - inl = inpkt->size; - - if (inl >= INT_MAX / UTF8_MAX_BYTES - AV_INPUT_BUFFER_PADDING_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n"); - ret = AVERROR(ENOMEM); - goto end; - } - - ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES); - if (ret < 0) - goto end; - outpkt->buf = tmp.buf; - outpkt->data = tmp.data; - outpkt->size = tmp.size; - outb = outpkt->data; - outl = outpkt->size; - - 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_packet_unref(&tmp); - goto end; - } - outpkt->size -= outl; - memset(outpkt->data + outpkt->size, 0, outl); - -end: - if (cd != (iconv_t)-1) - iconv_close(cd); - return ret; -#else - av_log(avctx, AV_LOG_ERROR, "requesting subtitles recoding without iconv"); - return AVERROR(EINVAL); -#endif -} - -static int utf8_check(const uint8_t *str) -{ - const uint8_t *byte; - uint32_t codepoint, min; - - while (*str) { - byte = str; - GET_UTF8(codepoint, *(byte++), return 0;); - min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : - 1 << (5 * (byte - str) - 4); - if (codepoint < min || codepoint >= 0x110000 || - codepoint == 0xFFFE /* BOM */ || - codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) - return 0; - str = byte; - } - return 1; -} - -#if FF_API_ASS_TIMING -static void insert_ts(AVBPrint *buf, int ts) -{ - if (ts == -1) { - av_bprintf(buf, "9:59:59.99,"); - } else { - int h, m, s; - - h = ts/360000; ts -= 360000*h; - m = ts/ 6000; ts -= 6000*m; - s = ts/ 100; ts -= 100*s; - av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts); - } -} - -static int convert_sub_to_old_ass_form(AVSubtitle *sub, const AVPacket *pkt, AVRational tb) -{ - int i; - AVBPrint buf; - - av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); - - for (i = 0; i < sub->num_rects; i++) { - char *final_dialog; - const char *dialog; - AVSubtitleRect *rect = sub->rects[i]; - int ts_start, ts_duration = -1; - long int layer; - - if (rect->type != SUBTITLE_ASS || !strncmp(rect->ass, "Dialogue: ", 10)) - continue; - - av_bprint_clear(&buf); - - /* skip ReadOrder */ - dialog = strchr(rect->ass, ','); - if (!dialog) - continue; - dialog++; - - /* extract Layer or Marked */ - layer = strtol(dialog, (char**)&dialog, 10); - if (*dialog != ',') - continue; - dialog++; - - /* rescale timing to ASS time base (ms) */ - ts_start = av_rescale_q(pkt->pts, tb, av_make_q(1, 100)); - if (pkt->duration != -1) - ts_duration = av_rescale_q(pkt->duration, tb, av_make_q(1, 100)); - sub->end_display_time = FFMAX(sub->end_display_time, 10 * ts_duration); - - /* construct ASS (standalone file form with timestamps) string */ - av_bprintf(&buf, "Dialogue: %ld,", layer); - insert_ts(&buf, ts_start); - insert_ts(&buf, ts_duration == -1 ? -1 : ts_start + ts_duration); - av_bprintf(&buf, "%s\r\n", dialog); - - final_dialog = av_strdup(buf.str); - if (!av_bprint_is_complete(&buf) || !final_dialog) { - av_freep(&final_dialog); - av_bprint_finalize(&buf, NULL); - return AVERROR(ENOMEM); - } - av_freep(&rect->ass); - rect->ass = final_dialog; - } - - av_bprint_finalize(&buf, NULL); - return 0; -} -#endif - -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt) -{ - int i, ret = 0; - - if (!avpkt->data && avpkt->size) { - av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); - return AVERROR(EINVAL); - } - if (!avctx->codec) - return AVERROR(EINVAL); - if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { - av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); - return AVERROR(EINVAL); - } - - *got_sub_ptr = 0; - get_subtitle_defaults(sub); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { - AVPacket pkt_recoded; - AVPacket tmp = *avpkt; - int did_split = av_packet_split_side_data(&tmp); - //apply_param_change(avctx, &tmp); - - if (did_split) { - /* FFMIN() prevents overflow in case the packet wasn't allocated with - * proper padding. - * If the side data is smaller than the buffer padding size, the - * remaining bytes should have already been filled with zeros by the - * original packet allocation anyway. */ - memset(tmp.data + tmp.size, 0, - FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE)); - } - - pkt_recoded = tmp; - ret = recode_subtitle(avctx, &pkt_recoded, &tmp); - if (ret < 0) { - *got_sub_ptr = 0; - } else { - avctx->internal->pkt = &pkt_recoded; - - if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) - sub->pts = av_rescale_q(avpkt->pts, - avctx->pkt_timebase, AV_TIME_BASE_Q); - ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); - av_assert1((ret >= 0) >= !!*got_sub_ptr && - !!*got_sub_ptr >= !!sub->num_rects); - -#if FF_API_ASS_TIMING - if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS - && *got_sub_ptr && sub->num_rects) { - const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase - : avctx->time_base; - int err = convert_sub_to_old_ass_form(sub, avpkt, tb); - if (err < 0) - ret = err; - } -#endif - - if (sub->num_rects && !sub->end_display_time && avpkt->duration && - avctx->pkt_timebase.num) { - AVRational ms = { 1, 1000 }; - sub->end_display_time = av_rescale_q(avpkt->duration, - avctx->pkt_timebase, ms); - } - - for (i = 0; i < sub->num_rects; i++) { - if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { - av_log(avctx, AV_LOG_ERROR, - "Invalid UTF-8 in decoded subtitles text; " - "maybe missing -sub_charenc option\n"); - avsubtitle_free(sub); - return AVERROR_INVALIDDATA; - } - } - - if (tmp.data != pkt_recoded.data) { // did we recode? - /* prevent from destroying side data from original packet */ - pkt_recoded.side_data = NULL; - pkt_recoded.side_data_elems = 0; - - av_packet_unref(&pkt_recoded); - } - if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) - sub->format = 0; - else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) - sub->format = 1; - avctx->internal->pkt = NULL; - } - - if (did_split) { - av_packet_free_side_data(&tmp); - if(ret == tmp.size) - ret = avpkt->size; + if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) + && avctx->bit_rate>0 && avctx->bit_rate<1000) { + av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", avctx->bit_rate, avctx->bit_rate); } - if (*got_sub_ptr) - avctx->frame_number++; - } - - return ret; -} - -void avsubtitle_free(AVSubtitle *sub) -{ - int i; - - for (i = 0; i < sub->num_rects; i++) { - av_freep(&sub->rects[i]->data[0]); - av_freep(&sub->rects[i]->data[1]); - av_freep(&sub->rects[i]->data[2]); - av_freep(&sub->rects[i]->data[3]); - av_freep(&sub->rects[i]->text); - av_freep(&sub->rects[i]->ass); - av_freep(&sub->rects[i]); - } - - av_freep(&sub->rects); - - memset(sub, 0, sizeof(AVSubtitle)); -} - -static int do_decode(AVCodecContext *avctx, AVPacket *pkt) -{ - int got_frame; - int ret; - - av_assert0(!avctx->internal->buffer_frame->buf[0]); - - if (!pkt) - pkt = avctx->internal->buffer_pkt; - - // This is the lesser evil. The field is for compatibility with legacy users - // of the legacy API, and users using the new API should not be forced to - // even know about this field. - avctx->refcounted_frames = 1; - - // Some codecs (at least wma lossless) will crash when feeding drain packets - // after EOF was signaled. - if (avctx->internal->draining_done) - return AVERROR_EOF; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_decode_video2(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - if (ret >= 0) - ret = pkt->size; - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_decode_audio4(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - } else { - ret = AVERROR(EINVAL); - } - - if (ret == AVERROR(EAGAIN)) - ret = pkt->size; - - if (ret < 0) - return ret; - - if (avctx->internal->draining && !got_frame) - avctx->internal->draining_done = 1; - - if (ret >= pkt->size) { - av_packet_unref(avctx->internal->buffer_pkt); - } else { - int consumed = ret; + if (!avctx->rc_initial_buffer_occupancy) + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3LL / 4; - if (pkt != avctx->internal->buffer_pkt) { - av_packet_unref(avctx->internal->buffer_pkt); - if ((ret = av_packet_ref(avctx->internal->buffer_pkt, pkt)) < 0) - return ret; + if (avctx->ticks_per_frame && avctx->time_base.num && + avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { + av_log(avctx, AV_LOG_ERROR, + "ticks_per_frame %d too large for the timebase %d/%d.", + avctx->ticks_per_frame, + avctx->time_base.num, + avctx->time_base.den); + goto free_and_end; } - avctx->internal->buffer_pkt->data += consumed; - avctx->internal->buffer_pkt->size -= consumed; - avctx->internal->buffer_pkt->pts = AV_NOPTS_VALUE; - avctx->internal->buffer_pkt->dts = AV_NOPTS_VALUE; + if (avctx->hw_frames_ctx) { + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (frames_ctx->format != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.pix_fmt and AVHWFramesContext.format\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE && + avctx->sw_pix_fmt != frames_ctx->sw_format) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.sw_pix_fmt (%s) " + "and AVHWFramesContext.sw_format (%s)\n", + av_get_pix_fmt_name(avctx->sw_pix_fmt), + av_get_pix_fmt_name(frames_ctx->sw_format)); + ret = AVERROR(EINVAL); + goto free_and_end; + } + avctx->sw_pix_fmt = frames_ctx->sw_format; + } } - if (got_frame) - av_assert0(avctx->internal->buffer_frame->buf[0]); - - return 0; -} - -int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) -{ - int ret; - - if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->internal->draining) - return AVERROR_EOF; - - if (avpkt && !avpkt->size && avpkt->data) - return AVERROR(EINVAL); - - if (!avpkt || !avpkt->size) { - avctx->internal->draining = 1; - avpkt = NULL; + avctx->pts_correction_num_faulty_pts = + avctx->pts_correction_num_faulty_dts = 0; + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } + if ( !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY + && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO) + av_log(avctx, AV_LOG_WARNING, + "gray decoding requested but not enabled at configuration time\n"); - if (avctx->codec->send_packet) { - if (avpkt) { - AVPacket tmp = *avpkt; - int did_split = av_packet_split_side_data(&tmp); - ret = apply_param_change(avctx, &tmp); - if (ret >= 0) - ret = avctx->codec->send_packet(avctx, &tmp); - if (did_split) - av_packet_free_side_data(&tmp); - return ret; - } else { - return avctx->codec->send_packet(avctx, NULL); + if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) + || avctx->internal->frame_thread_encoder)) { + ret = avctx->codec->init(avctx); + if (ret < 0) { + goto free_and_end; } } - // Emulation via old API. Assume avpkt is likely not refcounted, while - // decoder output is always refcounted, and avoid copying. - - if (avctx->internal->buffer_pkt->size || avctx->internal->buffer_frame->buf[0]) - return AVERROR(EAGAIN); - - // The goal is decoding the first frame of the packet without using memcpy, - // because the common case is having only 1 frame per packet (especially - // with video, but audio too). In other cases, it can't be avoided, unless - // the user is feeding refcounted packets. - return do_decode(avctx, (AVPacket *)avpkt); -} - -int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) -{ - int ret; - - av_frame_unref(frame); + ret=0; - if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) - return AVERROR(EINVAL); +#if FF_API_AUDIOENC_DELAY + if (av_codec_is_encoder(avctx->codec)) + avctx->delay = avctx->initial_padding; +#endif - if (avctx->codec->receive_frame) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - ret = avctx->codec->receive_frame(avctx, frame); - if (ret >= 0) { - if (av_frame_get_best_effort_timestamp(frame) == AV_NOPTS_VALUE) { - av_frame_set_best_effort_timestamp(frame, - guess_correct_pts(avctx, frame->pts, frame->pkt_dts)); + if (av_codec_is_decoder(avctx->codec)) { + if (!avctx->bit_rate) + avctx->bit_rate = get_bit_rate(avctx); + /* validate channel layout from the decoder */ + if (avctx->channel_layout) { + int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + if (!avctx->channels) + avctx->channels = channels; + else if (channels != avctx->channels) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_WARNING, + "Channel layout '%s' with %d channels does not match specified number of channels %d: " + "ignoring specified channel layout\n", + buf, channels, avctx->channels); + avctx->channel_layout = 0; } } - return ret; - } - - // Emulation via old API. - - if (!avctx->internal->buffer_frame->buf[0]) { - if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining) - return AVERROR(EAGAIN); + if (avctx->channels && avctx->channels < 0 || + avctx->channels > FF_SANE_NB_CHANNELS) { + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->sub_charenc) { + if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { + av_log(avctx, AV_LOG_ERROR, "Character encoding is only " + "supported with subtitles codecs\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) { + av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, " + "subtitles character encoding will be ignored\n", + avctx->codec_descriptor->name); + avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING; + } else { + /* input character encoding is set for a text based subtitle + * codec at this point */ + if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC) + avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER; - while (1) { - if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) { - av_packet_unref(avctx->internal->buffer_pkt); - return ret; + if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) { +#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); + goto free_and_end; + } + iconv_close(cd); +#else + av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles " + "conversion needs a libavcodec built with iconv support " + "for this codec\n"); + ret = AVERROR(ENOSYS); + goto free_and_end; +#endif + } } - // Some audio decoders may consume partial data without returning - // a frame (fate-wmapro-2ch). There is no way to make the caller - // call avcodec_receive_frame() again without returning a frame, - // so try to decode more in these cases. - if (avctx->internal->buffer_frame->buf[0] || - !avctx->internal->buffer_pkt->size) - break; } - } - - if (!avctx->internal->buffer_frame->buf[0]) - return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN); - - av_frame_move_ref(frame, avctx->internal->buffer_frame); - return 0; -} - -static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) -{ - int ret; - *got_packet = 0; - - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else { - ret = AVERROR(EINVAL); +#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 + } + if (codec->priv_data_size > 0 && avctx->priv_data && codec->priv_class) { + av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class); } - if (ret >= 0 && *got_packet) { - // Encoders must always return ref-counted buffers. - // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); - avctx->internal->buffer_pkt_valid = 1; - ret = 0; - } else { - av_packet_unref(avctx->internal->buffer_pkt); +end: + ff_unlock_avcodec(codec); + if (options) { + av_dict_free(options); + *options = tmp; } return ret; -} - -int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) -{ - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->internal->draining) - return AVERROR_EOF; - - if (!frame) { - avctx->internal->draining = 1; +free_and_end: + if (avctx->codec && + (avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP)) + avctx->codec->close(avctx); - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } + if (codec->priv_class && codec->priv_data_size) + av_opt_free(avctx->priv_data); + av_opt_free(avctx); - if (avctx->codec->send_frame) - return avctx->codec->send_frame(avctx, frame); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif - // Emulation via old API. Do it here instead of avcodec_receive_packet, because: - // 1. if the AVFrame is not refcounted, the copying will be much more - // expensive than copying the packet data - // 2. assume few users use non-refcounted AVPackets, so usually no copy is - // needed + av_dict_free(&tmp); + av_freep(&avctx->priv_data); + if (avctx->internal) { + av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); + av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); - if (avctx->internal->buffer_pkt_valid) - return AVERROR(EAGAIN); + av_packet_free(&avctx->internal->ds.in_pkt); - return do_encode(avctx, frame, &(int){0}); + av_freep(&avctx->internal->pool); + } + av_freep(&avctx->internal); + avctx->codec = NULL; + goto end; } -int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +void avsubtitle_free(AVSubtitle *sub) { - av_packet_unref(avpkt); - - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); + int i; - if (avctx->codec->receive_packet) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - return avctx->codec->receive_packet(avctx, avpkt); + for (i = 0; i < sub->num_rects; i++) { + av_freep(&sub->rects[i]->data[0]); + av_freep(&sub->rects[i]->data[1]); + av_freep(&sub->rects[i]->data[2]); + av_freep(&sub->rects[i]->data[3]); + av_freep(&sub->rects[i]->text); + av_freep(&sub->rects[i]->ass); + av_freep(&sub->rects[i]); } - // Emulation via old API. - - if (!avctx->internal->buffer_pkt_valid) { - int got_packet; - int ret; - if (!avctx->internal->draining) - return AVERROR(EAGAIN); - ret = do_encode(avctx, NULL, &got_packet); - if (ret < 0) - return ret; - if (ret >= 0 && !got_packet) - return AVERROR_EOF; - } + av_freep(&sub->rects); - av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - return 0; + memset(sub, 0, sizeof(*sub)); } av_cold int avcodec_close(AVCodecContext *avctx) @@ -3040,8 +1180,13 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->internal->byte_buffer_size = 0; av_freep(&avctx->internal->byte_buffer); av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); av_frame_free(&avctx->internal->buffer_frame); av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); av_freep(&avctx->internal->pool); @@ -3050,6 +1195,8 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->hwaccel->uninit(avctx); av_freep(&avctx->internal->hwaccel_priv_data); + ff_decode_bsfs_uninit(avctx); + av_freep(&avctx->internal); } @@ -3059,6 +1206,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->nb_coded_side_data = 0; av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) av_opt_free(avctx->priv_data); @@ -3215,12 +1363,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %d reference frame%s", enc->refs, enc->refs > 1 ? "s" : ""); - if (enc->codec_tag) { - char tag_buf[32]; - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%s / 0x%04X)", tag_buf, enc->codec_tag); - } + if (enc->codec_tag) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", + av_fourcc2str(enc->codec_tag), enc->codec_tag); switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -3377,7 +1522,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %"PRId64" kb/s", bitrate / 1000); } else if (enc->rc_max_rate > 0) { snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", max. %"PRId64" kb/s", (int64_t)enc->rc_max_rate / 1000); + ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); } } @@ -3432,26 +1577,6 @@ const char *avcodec_license(void) return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; } -void avcodec_flush_buffers(AVCodecContext *avctx) -{ - avctx->internal->draining = 0; - avctx->internal->draining_done = 0; - av_frame_unref(avctx->internal->buffer_frame); - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ff_thread_flush(avctx); - else if (avctx->codec->flush) - avctx->codec->flush(avctx); - - avctx->pts_correction_last_pts = - avctx->pts_correction_last_dts = INT64_MIN; - - if (!avctx->refcounted_frames) - av_frame_unref(avctx->internal->to_free); -} - int av_get_exact_bits_per_sample(enum AVCodecID codec_id) { switch (codec_id) { @@ -3499,6 +1624,8 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_U32LE: case AV_CODEC_ID_PCM_F32BE: case AV_CODEC_ID_PCM_F32LE: + case AV_CODEC_ID_PCM_F24LE: + case AV_CODEC_ID_PCM_F16LE: return 32; case AV_CODEC_ID_PCM_F64BE: case AV_CODEC_ID_PCM_F64LE: @@ -3595,6 +1722,9 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (id == AV_CODEC_ID_BINKAUDIO_DCT) return (480 << (sr / 22050)) / ch; } + + if (id == AV_CODEC_ID_MP3) + return sr <= 24000 ? 576 : 1152; } if (ba > 0) { @@ -3627,7 +1757,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (bps > 0) { /* calc from frame_bytes and bits_per_coded_sample */ - if (id == AV_CODEC_ID_ADPCM_G726) + if (id == AV_CODEC_ID_ADPCM_G726 || id == AV_CODEC_ID_ADPCM_G726LE) return frame_bytes * 8 / bps; } @@ -3931,7 +2061,8 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) { int ret; - dst->owner = src->owner; + dst->owner[0] = src->owner[0]; + dst->owner[1] = src->owner[1]; ret = av_frame_ref(dst->f, src->f); if (ret < 0) @@ -3941,7 +2072,7 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) if (src->progress && !(dst->progress = av_buffer_ref(src->progress))) { - ff_thread_release_buffer(dst->owner, dst); + ff_thread_release_buffer(dst->owner[0], dst); return AVERROR(ENOMEM); } @@ -3957,7 +2088,7 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { - f->owner = avctx; + f->owner[0] = f->owner[1] = avctx; return ff_get_buffer(avctx, f->f, flags); } @@ -4319,3 +2450,24 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, return 0; } + +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) +{ + AVRational framerate = avctx->framerate; + int bits_per_coded_sample = avctx->bits_per_coded_sample; + int64_t bitrate; + + if (!(framerate.num && framerate.den)) + framerate = av_inv_q(avctx->time_base); + if (!(framerate.num && framerate.den)) + return 0; + + if (!bits_per_coded_sample) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + bits_per_coded_sample = av_get_bits_per_pixel(desc); + } + bitrate = (int64_t)bits_per_coded_sample * avctx->width * avctx->height * + framerate.num / framerate.den; + + return bitrate; +} diff --git a/media/ffvpx/libavcodec/version.h b/media/ffvpx/libavcodec/version.h index ec8837a4e..10d9ac4eb 100644 --- a/media/ffvpx/libavcodec/version.h +++ b/media/ffvpx/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 64 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 107 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -60,9 +60,6 @@ #ifndef FF_API_AVCODEC_RESAMPLE #define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT #endif -#ifndef FF_API_GETCHROMA -#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 58) -#endif #ifndef FF_API_MISSING_SAMPLE #define FF_API_MISSING_SAMPLE (LIBAVCODEC_VERSION_MAJOR < 58) #endif @@ -157,6 +154,9 @@ #ifndef FF_API_VAAPI_CONTEXT #define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 58) #endif +#ifndef FF_API_MERGE_SD +#define FF_API_MERGE_SD (LIBAVCODEC_VERSION_MAJOR < 58) +#endif #ifndef FF_API_AVCTX_TIMEBASE #define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) #endif @@ -226,5 +226,18 @@ #ifndef FF_API_NVENC_OLD_NAME #define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_STRUCT_VAAPI_CONTEXT +#define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_MERGE_SD_API +#define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_TAG_STRING +#define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_GETCHROMA +#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) +#endif + #endif /* AVCODEC_VERSION_H */ diff --git a/media/ffvpx/libavcodec/videodsp.c b/media/ffvpx/libavcodec/videodsp.c index ba618a7bb..ce9e9eb14 100644 --- a/media/ffvpx/libavcodec/videodsp.c +++ b/media/ffvpx/libavcodec/videodsp.c @@ -52,4 +52,6 @@ av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc) ff_videodsp_init_ppc(ctx, bpc); if (ARCH_X86) ff_videodsp_init_x86(ctx, bpc); + if (ARCH_MIPS) + ff_videodsp_init_mips(ctx, bpc); } diff --git a/media/ffvpx/libavcodec/videodsp.h b/media/ffvpx/libavcodec/videodsp.h index fc01a31dc..c0545f22b 100644 --- a/media/ffvpx/libavcodec/videodsp.h +++ b/media/ffvpx/libavcodec/videodsp.h @@ -83,5 +83,6 @@ void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc); void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc); void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc); void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc); +void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc); #endif /* AVCODEC_VIDEODSP_H */ diff --git a/media/ffvpx/libavcodec/vlc.h b/media/ffvpx/libavcodec/vlc.h index 9e38f8c6b..42ccddf3f 100644 --- a/media/ffvpx/libavcodec/vlc.h +++ b/media/ffvpx/libavcodec/vlc.h @@ -54,12 +54,28 @@ void ff_free_vlc(VLC *vlc); #define INIT_VLC_LE 2 #define INIT_VLC_USE_NEW_STATIC 4 -#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ +#define INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ + do { \ + static VLC_TYPE table[static_size][2]; \ + (vlc)->table = table; \ + (vlc)->table_allocated = static_size; \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + INIT_VLC_USE_NEW_STATIC); \ + } while (0) + +#define INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ do { \ static VLC_TYPE table[static_size][2]; \ (vlc)->table = table; \ (vlc)->table_allocated = static_size; \ - init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); \ } while (0) +#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ + INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) + +#define INIT_LE_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ + INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) + #endif /* AVCODEC_VLC_H */ diff --git a/media/ffvpx/libavcodec/vorbis_parser.h b/media/ffvpx/libavcodec/vorbis_parser.h index 92050277e..789932ac4 100644 --- a/media/ffvpx/libavcodec/vorbis_parser.h +++ b/media/ffvpx/libavcodec/vorbis_parser.h @@ -32,9 +32,6 @@ typedef struct AVVorbisParseContext AVVorbisParseContext; /** * Allocate and initialize the Vorbis parser using headers in the extradata. - * - * @param avctx codec context - * @param s Vorbis parser context */ AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata, int extradata_size); diff --git a/media/ffvpx/libavcodec/vp3dsp.h b/media/ffvpx/libavcodec/vp3dsp.h index b95adae79..2fdad162c 100644 --- a/media/ffvpx/libavcodec/vp3dsp.h +++ b/media/ffvpx/libavcodec/vp3dsp.h @@ -38,11 +38,11 @@ typedef struct VP3DSPContext { const uint8_t *b, ptrdiff_t stride, int h); - void (*idct_put)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_add)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_dc_add)(uint8_t *dest, int line_size, int16_t *block); - void (*v_loop_filter)(uint8_t *src, int stride, int *bounding_values); - void (*h_loop_filter)(uint8_t *src, int stride, int *bounding_values); + void (*idct_put)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*idct_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*idct_dc_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*v_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values); + void (*h_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values); } VP3DSPContext; void ff_vp3dsp_init(VP3DSPContext *c, int flags); diff --git a/media/ffvpx/libavcodec/vp56.h b/media/ffvpx/libavcodec/vp56.h index 56c30919b..b8dda9e73 100644 --- a/media/ffvpx/libavcodec/vp56.h +++ b/media/ffvpx/libavcodec/vp56.h @@ -26,6 +26,7 @@ #ifndef AVCODEC_VP56_H #define AVCODEC_VP56_H +#include "avcodec.h" #include "get_bits.h" #include "hpeldsp.h" #include "bytestream.h" @@ -72,9 +73,9 @@ typedef struct VP56mv { typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, VP56mv *vect); typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, - int offset1, int offset2, int stride, + int offset1, int offset2, ptrdiff_t stride, VP56mv mv, int mask, int select, int luma); -typedef void (*VP56ParseCoeff)(VP56Context *s); +typedef int (*VP56ParseCoeff)(VP56Context *s); typedef void (*VP56DefaultModelsInit)(VP56Context *s); typedef void (*VP56ParseVectorModels)(VP56Context *s); typedef int (*VP56ParseCoeffModels)(VP56Context *s); @@ -179,7 +180,7 @@ struct vp56_context { int flip; /* are we flipping ? */ int frbi; /* first row block index in MB */ int srbi; /* second row block index in MB */ - int stride[4]; /* stride for each plan */ + ptrdiff_t stride[4]; /* stride for each plan */ const uint8_t *vp56_coord_div; VP56ParseVectorAdjustment parse_vector_adjustment; @@ -203,6 +204,9 @@ struct vp56_context { VLC runv_vlc[2]; VLC ract_vlc[2][3][6]; unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ + + int have_undamaged_frame; + int discard_frame; }; @@ -221,7 +225,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, */ extern const uint8_t ff_vp56_norm_shift[256]; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); +int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c) { diff --git a/media/ffvpx/libavcodec/vp56dsp.h b/media/ffvpx/libavcodec/vp56dsp.h index 7807baa4b..e35e232ea 100644 --- a/media/ffvpx/libavcodec/vp56dsp.h +++ b/media/ffvpx/libavcodec/vp56dsp.h @@ -21,22 +21,24 @@ #ifndef AVCODEC_VP56DSP_H #define AVCODEC_VP56DSP_H +#include #include -#include "avcodec.h" typedef struct VP56DSPContext { - void (*edge_filter_hor)(uint8_t *yuv, int stride, int t); - void (*edge_filter_ver)(uint8_t *yuv, int stride, int t); + void (*edge_filter_hor)(uint8_t *yuv, ptrdiff_t stride, int t); + void (*edge_filter_ver)(uint8_t *yuv, ptrdiff_t stride, int t); - void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, + void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights,const int16_t *v_weights); } VP56DSPContext; -void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, +void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights, const int16_t *v_weights); -void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec); +void ff_vp5dsp_init(VP56DSPContext *s); +void ff_vp6dsp_init(VP56DSPContext *s); + +void ff_vp6dsp_init_arm(VP56DSPContext *s); +void ff_vp6dsp_init_x86(VP56DSPContext *s); #endif /* AVCODEC_VP56DSP_H */ diff --git a/media/ffvpx/libavcodec/vp56rac.c b/media/ffvpx/libavcodec/vp56rac.c index 6061b7ee7..e70302bf8 100644 --- a/media/ffvpx/libavcodec/vp56rac.c +++ b/media/ffvpx/libavcodec/vp56rac.c @@ -37,11 +37,14 @@ const uint8_t ff_vp56_norm_shift[256]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size) +int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size) { c->high = 255; c->bits = -16; c->buffer = buf; c->end = buf + buf_size; + if (buf_size < 1) + return AVERROR_INVALIDDATA; c->code_word = bytestream_get_be24(&c->buffer); + return 0; } diff --git a/media/ffvpx/libavcodec/vp8.c b/media/ffvpx/libavcodec/vp8.c index c1c3eb707..7841a9d96 100644 --- a/media/ffvpx/libavcodec/vp8.c +++ b/media/ffvpx/libavcodec/vp8.c @@ -261,6 +261,7 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) { const uint8_t *sizes = buf; int i; + int ret; s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2); @@ -274,13 +275,13 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) if (buf_size - size < 0) return -1; - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + if (ret < 0) + return ret; buf += size; buf_size -= size; } - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); - - return 0; + return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); } static void vp7_get_quants(VP8Context *s) @@ -434,8 +435,8 @@ static void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height) } } -static void fade(uint8_t *dst, int dst_linesize, - const uint8_t *src, int src_linesize, +static void fade(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, int width, int height, int alpha, int beta) { @@ -518,7 +519,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab)); - ff_vp56_init_range_decoder(c, buf, part1_size); + ret = ff_vp56_init_range_decoder(c, buf, part1_size); + if (ret < 0) + return ret; buf += part1_size; buf_size -= part1_size; @@ -570,7 +573,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->lf_delta.enabled = 0; s->num_coeff_partitions = 1; - ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + if (ret < 0) + return ret; if (!s->macroblocks_base || /* first frame */ width != s->avctx->width || height != s->avctx->height || @@ -699,7 +704,9 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memset(&s->lf_delta, 0, sizeof(s->lf_delta)); } - ff_vp56_init_range_decoder(c, buf, header_size); + ret = ff_vp56_init_range_decoder(c, buf, header_size); + if (ret < 0) + return ret; buf += header_size; buf_size -= header_size; @@ -765,7 +772,7 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si } static av_always_inline -void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src) +void clamp_mv(VP8mvbounds *s, VP56mv *dst, const VP56mv *src) { dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX), av_clip(s->mv_max.x, INT16_MIN, INT16_MAX)); @@ -1024,7 +1031,7 @@ void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb, } static av_always_inline -void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, +void vp8_decode_mvs(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, int layout) { VP8Macroblock *mb_edge[3] = { 0 /* top */, @@ -1095,7 +1102,7 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) { if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) { /* Choose the best mv out of 0,0 and the nearest mv */ - clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]); + clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]); cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) + (mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 + (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT); @@ -1109,11 +1116,11 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, mb->bmv[0] = mb->mv; } } else { - clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]); + clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAR]); mb->bmv[0] = mb->mv; } } else { - clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]); + clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAREST]); mb->bmv[0] = mb->mv; } } else { @@ -1159,14 +1166,15 @@ void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, } static av_always_inline -void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, +void decode_mb_mode(VP8Context *s, VP8mvbounds *mv_bounds, + VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, uint8_t *ref, int layout, int is_vp7) { VP56RangeCoder *c = &s->c; - static const char *vp7_feature_name[] = { "q-index", - "lf-delta", - "partial-golden-update", - "blit-pitch" }; + static const char * const vp7_feature_name[] = { "q-index", + "lf-delta", + "partial-golden-update", + "blit-pitch" }; if (is_vp7) { int i; *segment = 0; @@ -1223,7 +1231,7 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, if (is_vp7) vp7_decode_mvs(s, mb, mb_x, mb_y, layout); else - vp8_decode_mvs(s, mb, mb_x, mb_y, layout); + vp8_decode_mvs(s, mv_bounds, mb, mb_x, mb_y, layout); } else { // intra MB, 16.1 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16); @@ -1461,7 +1469,7 @@ void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c, static av_always_inline void backup_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, - int linesize, int uvlinesize, int simple) + ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple) { AV_COPY128(top_border, src_y + 15 * linesize); if (!simple) { @@ -1472,7 +1480,7 @@ void backup_mb_border(uint8_t *top_border, uint8_t *src_y, static av_always_inline void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, - uint8_t *src_cr, int linesize, int uvlinesize, int mb_x, + uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int mb_x, int mb_y, int mb_width, int simple, int xchg) { uint8_t *top_border_m1 = top_border - 32; // for TL prediction @@ -1625,7 +1633,8 @@ void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], for (y = 0; y < 4; y++) { uint8_t *topright = ptr + 4 - s->linesize; for (x = 0; x < 4; x++) { - int copy = 0, linesize = s->linesize; + int copy = 0; + ptrdiff_t linesize = s->linesize; uint8_t *dst = ptr + 4 * x; LOCAL_ALIGNED(4, uint8_t, copy_dst, [5 * 8]); @@ -1731,7 +1740,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, uint8_t *src = ref->f->data[0]; if (AV_RN32A(mv)) { - int src_linesize = linesize; + ptrdiff_t src_linesize = linesize; int mx = (mv->x * 2) & 7, mx_idx = subpel_idx[0][mx]; int my = (mv->y * 2) & 7, my_idx = subpel_idx[0][my]; @@ -2077,8 +2086,8 @@ void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, int filter_level = f->filter_level; int inner_limit = f->inner_limit; int inner_filter = f->inner_filter; - int linesize = s->linesize; - int uvlinesize = s->uvlinesize; + ptrdiff_t linesize = s->linesize; + ptrdiff_t uvlinesize = s->uvlinesize; static const uint8_t hev_thresh_lut[2][64] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -2164,7 +2173,7 @@ void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int filter_level = f->filter_level; int inner_limit = f->inner_limit; int inner_filter = f->inner_filter; - int linesize = s->linesize; + ptrdiff_t linesize = s->linesize; if (!filter_level) return; @@ -2197,8 +2206,8 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, VP8Context *s = avctx->priv_data; int mb_x, mb_y; - s->mv_min.y = -MARGIN; - s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; + s->mv_bounds.mv_min.y = -MARGIN; + s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { VP8Macroblock *mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1); @@ -2206,20 +2215,20 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101); - s->mv_min.x = -MARGIN; - s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; + s->mv_bounds.mv_min.x = -MARGIN; + s->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { if (mb_y == 0) AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top, DC_PRED * 0x01010101); - decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, + decode_mb_mode(s, &s->mv_bounds, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, prev_frame && prev_frame->seg_map ? prev_frame->seg_map->data + mb_xy : NULL, 1, is_vp7); - s->mv_min.x -= 64; - s->mv_max.x -= 64; + s->mv_bounds.mv_min.x -= 64; + s->mv_bounds.mv_max.x -= 64; } - s->mv_min.y -= 64; - s->mv_max.y -= 64; + s->mv_bounds.mv_min.y -= 64; + s->mv_bounds.mv_max.y -= 64; } } @@ -2239,15 +2248,15 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, #define check_thread_pos(td, otd, mb_x_check, mb_y_check) \ do { \ int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \ - if (otd->thread_mb_pos < tmp) { \ + if (atomic_load(&otd->thread_mb_pos) < tmp) { \ pthread_mutex_lock(&otd->lock); \ - td->wait_mb_pos = tmp; \ + atomic_store(&td->wait_mb_pos, tmp); \ do { \ - if (otd->thread_mb_pos >= tmp) \ + if (atomic_load(&otd->thread_mb_pos) >= tmp) \ break; \ pthread_cond_wait(&otd->cond, &otd->lock); \ } while (1); \ - td->wait_mb_pos = INT_MAX; \ + atomic_store(&td->wait_mb_pos, INT_MAX); \ pthread_mutex_unlock(&otd->lock); \ } \ } while (0) @@ -2258,12 +2267,10 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \ (num_jobs > 1); \ int is_null = !next_td || !prev_td; \ - int pos_check = (is_null) ? 1 \ - : (next_td != td && \ - pos >= next_td->wait_mb_pos) || \ - (prev_td != td && \ - pos >= prev_td->wait_mb_pos); \ - td->thread_mb_pos = pos; \ + int pos_check = (is_null) ? 1 : \ + (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \ + (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \ + atomic_store(&td->thread_mb_pos, pos); \ if (sliced_threading && pos_check) { \ pthread_mutex_lock(&td->lock); \ pthread_cond_broadcast(&td->cond); \ @@ -2275,12 +2282,12 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, #define update_pos(td, mb_y, mb_x) while(0) #endif -static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7) { VP8Context *s = avctx->priv_data; VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr]; - int mb_y = td->thread_mb_pos >> 16; + int mb_y = atomic_load(&td->thread_mb_pos) >> 16; int mb_x, mb_xy = mb_y * s->mb_width; int num_jobs = s->num_jobs; VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame; @@ -2291,6 +2298,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize, curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize }; + + if (c->end <= c->buffer && c->bits >= 0) + return AVERROR_INVALIDDATA; + if (mb_y == 0) prev_td = td; else @@ -2315,10 +2326,12 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void if (!is_vp7 || mb_y == 0) memset(td->left_nnz, 0, sizeof(td->left_nnz)); - s->mv_min.x = -MARGIN; - s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; + td->mv_bounds.mv_min.x = -MARGIN; + td->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { + if (c->end <= c->buffer && c->bits >= 0) + return AVERROR_INVALIDDATA; // Wait for previous thread to read mb_x+2, and reach mb_y-1. if (prev_td != td) { if (threadnr != 0) { @@ -2338,7 +2351,7 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void dst[2] - dst[1], 2); if (!s->mb_layout) - decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, + decode_mb_mode(s, &td->mv_bounds, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, prev_frame && prev_frame->seg_map ? prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7); @@ -2385,8 +2398,8 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void dst[0] += 16; dst[1] += 8; dst[2] += 8; - s->mv_min.x -= 64; - s->mv_max.x -= 64; + td->mv_bounds.mv_min.x -= 64; + td->mv_bounds.mv_max.x -= 64; if (mb_x == s->mb_width + 1) { update_pos(td, mb_y, s->mb_width + 3); @@ -2394,18 +2407,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void update_pos(td, mb_y, mb_x); } } + return 0; } -static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { - decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); + return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); } -static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { - decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); + return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); } static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, @@ -2413,7 +2427,7 @@ static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, { VP8Context *s = avctx->priv_data; VP8ThreadData *td = &s->thread_data[threadnr]; - int mb_x, mb_y = td->thread_mb_pos >> 16, num_jobs = s->num_jobs; + int mb_x, mb_y = atomic_load(&td->thread_mb_pos) >> 16, num_jobs = s->num_jobs; AVFrame *curframe = s->curframe->tf.f; VP8Macroblock *mb; VP8ThreadData *prev_td, *next_td; @@ -2488,19 +2502,24 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, VP8ThreadData *next_td = NULL, *prev_td = NULL; VP8Frame *curframe = s->curframe; int mb_y, num_jobs = s->num_jobs; + int ret; td->thread_nr = threadnr; + td->mv_bounds.mv_min.y = -MARGIN - 64 * threadnr; + td->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN - 64 * threadnr; for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { - if (mb_y >= s->mb_height) - break; - td->thread_mb_pos = mb_y << 16; - s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); + atomic_store(&td->thread_mb_pos, mb_y << 16); + ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); + if (ret < 0) { + update_pos(td, s->mb_height, INT_MAX & 0xFFFF); + return ret; + } if (s->deblock_filter) s->filter_mb_row(avctx, tdata, jobnr, threadnr); update_pos(td, mb_y, INT_MAX & 0xFFFF); - s->mv_min.y -= 64; - s->mv_max.y -= 64; + td->mv_bounds.mv_min.y -= 64 * num_jobs; + td->mv_bounds.mv_max.y -= 64 * num_jobs; if (avctx->active_thread_type == FF_THREAD_FRAME) ff_thread_report_progress(&curframe->tf, mb_y, 0); @@ -2531,6 +2550,8 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, enum AVDiscard skip_thresh; VP8Frame *av_uninit(curframe), *prev_frame; + av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVA420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P); + if (is_vp7) ret = vp7_decode_frame_header(s, avpkt->data, avpkt->size); else @@ -2646,11 +2667,12 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->num_jobs = num_jobs; s->curframe = curframe; s->prev_frame = prev_frame; - s->mv_min.y = -MARGIN; - s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; + s->mv_bounds.mv_min.y = -MARGIN; + s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN; for (i = 0; i < MAX_THREADS; i++) { - s->thread_data[i].thread_mb_pos = 0; - s->thread_data[i].wait_mb_pos = INT_MAX; + VP8ThreadData *td = &s->thread_data[i]; + atomic_init(&td->thread_mb_pos, 0); + atomic_init(&td->wait_mb_pos, INT_MAX); } if (is_vp7) avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL, diff --git a/media/ffvpx/libavcodec/vp8.h b/media/ffvpx/libavcodec/vp8.h index 374e1388e..8263997e3 100644 --- a/media/ffvpx/libavcodec/vp8.h +++ b/media/ffvpx/libavcodec/vp8.h @@ -26,6 +26,8 @@ #ifndef AVCODEC_VP8_H #define AVCODEC_VP8_H +#include + #include "libavutil/buffer.h" #include "libavutil/thread.h" @@ -91,6 +93,16 @@ typedef struct VP8Macroblock { VP56mv bmv[16]; } VP8Macroblock; +typedef struct VP8intmv { + int x; + int y; +} VP8intmv; + +typedef struct VP8mvbounds { + VP8intmv mv_min; + VP8intmv mv_max; +} VP8mvbounds; + typedef struct VP8ThreadData { DECLARE_ALIGNED(16, int16_t, block)[6][4][16]; DECLARE_ALIGNED(16, int16_t, block_dc)[16]; @@ -114,12 +126,13 @@ typedef struct VP8ThreadData { pthread_mutex_t lock; pthread_cond_t cond; #endif - int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF) - int wait_mb_pos; // What the current thread is waiting on. + atomic_int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF) + atomic_int wait_mb_pos; // What the current thread is waiting on. #define EDGE_EMU_LINESIZE 32 DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE]; VP8FilterStrength *filter_strength; + VP8mvbounds mv_bounds; } VP8ThreadData; typedef struct VP8Frame { @@ -127,11 +140,6 @@ typedef struct VP8Frame { AVBufferRef *seg_map; } VP8Frame; -typedef struct VP8intmv { - int x; - int y; -} VP8intmv; - #define MAX_THREADS 8 typedef struct VP8Context { VP8ThreadData *thread_data; @@ -143,15 +151,14 @@ typedef struct VP8Context { uint16_t mb_width; /* number of horizontal MB */ uint16_t mb_height; /* number of vertical MB */ - int linesize; - int uvlinesize; + ptrdiff_t linesize; + ptrdiff_t uvlinesize; uint8_t keyframe; uint8_t deblock_filter; uint8_t mbskip_enabled; uint8_t profile; - VP8intmv mv_min; - VP8intmv mv_max; + VP8mvbounds mv_bounds; int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type int ref_count[3]; @@ -275,7 +282,7 @@ typedef struct VP8Context { */ int mb_layout; - void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); + int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); int vp7; diff --git a/media/ffvpx/libavcodec/vp8_parser.c b/media/ffvpx/libavcodec/vp8_parser.c index afc7f991e..609f5077d 100644 --- a/media/ffvpx/libavcodec/vp8_parser.c +++ b/media/ffvpx/libavcodec/vp8_parser.c @@ -1,6 +1,4 @@ /* - * Copyright (C) 2008 Michael Niedermayer - * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,15 +16,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "parser.h" +#include "libavutil/intreadwrite.h" + +#include "avcodec.h" static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { - s->pict_type = (buf[0] & 0x01) ? AV_PICTURE_TYPE_P - : AV_PICTURE_TYPE_I; + unsigned int frame_type; + unsigned int profile; + + if (buf_size < 3) + return buf_size; + + frame_type = buf[0] & 1; + profile = (buf[0] >> 1) & 7; + if (profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid profile %u.\n", profile); + return buf_size; + } + + avctx->profile = profile; + s->key_frame = frame_type == 0; + s->pict_type = frame_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + s->format = AV_PIX_FMT_YUV420P; + s->field_order = AV_FIELD_PROGRESSIVE; + s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; + + if (frame_type == 0) { + unsigned int sync_code; + unsigned int width, height; + + if (buf_size < 10) + return buf_size; + + sync_code = AV_RL24(buf + 3); + if (sync_code != 0x2a019d) { + av_log(avctx, AV_LOG_ERROR, "Invalid sync code %06x.\n", sync_code); + return buf_size; + } + + width = AV_RL16(buf + 6) & 0x3fff; + height = AV_RL16(buf + 8) & 0x3fff; + + s->width = width; + s->height = height; + s->coded_width = FFALIGN(width, 16); + s->coded_height = FFALIGN(height, 16); + } *poutbuf = buf; *poutbuf_size = buf_size; diff --git a/media/ffvpx/libavcodec/vp8dsp.c b/media/ffvpx/libavcodec/vp8dsp.c index 07bea69c7..fed5c67a9 100644 --- a/media/ffvpx/libavcodec/vp8dsp.c +++ b/media/ffvpx/libavcodec/vp8dsp.c @@ -53,7 +53,8 @@ static void name ## _idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], \ #if CONFIG_VP7_DECODER static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16]) { - int i, a1, b1, c1, d1; + int i; + unsigned a1, b1, c1, d1; int16_t tmp[16]; for (i = 0; i < 4; i++) { @@ -61,10 +62,10 @@ static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16]) b1 = (dc[i * 4 + 0] - dc[i * 4 + 2]) * 23170; c1 = dc[i * 4 + 1] * 12540 - dc[i * 4 + 3] * 30274; d1 = dc[i * 4 + 1] * 30274 + dc[i * 4 + 3] * 12540; - tmp[i * 4 + 0] = (a1 + d1) >> 14; - tmp[i * 4 + 3] = (a1 - d1) >> 14; - tmp[i * 4 + 1] = (b1 + c1) >> 14; - tmp[i * 4 + 2] = (b1 - c1) >> 14; + tmp[i * 4 + 0] = (int)(a1 + d1) >> 14; + tmp[i * 4 + 3] = (int)(a1 - d1) >> 14; + tmp[i * 4 + 1] = (int)(b1 + c1) >> 14; + tmp[i * 4 + 2] = (int)(b1 - c1) >> 14; } for (i = 0; i < 4; i++) { @@ -73,10 +74,10 @@ static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16]) c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274; d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540; AV_ZERO64(dc + i * 4); - block[0][i][0] = (a1 + d1 + 0x20000) >> 18; - block[3][i][0] = (a1 - d1 + 0x20000) >> 18; - block[1][i][0] = (b1 + c1 + 0x20000) >> 18; - block[2][i][0] = (b1 - c1 + 0x20000) >> 18; + block[0][i][0] = (int)(a1 + d1 + 0x20000) >> 18; + block[3][i][0] = (int)(a1 - d1 + 0x20000) >> 18; + block[1][i][0] = (int)(b1 + c1 + 0x20000) >> 18; + block[2][i][0] = (int)(b1 - c1 + 0x20000) >> 18; } } @@ -95,7 +96,8 @@ static void vp7_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16]) static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride) { - int i, a1, b1, c1, d1; + int i; + unsigned a1, b1, c1, d1; int16_t tmp[16]; for (i = 0; i < 4; i++) { @@ -104,10 +106,10 @@ static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride) c1 = block[i * 4 + 1] * 12540 - block[i * 4 + 3] * 30274; d1 = block[i * 4 + 1] * 30274 + block[i * 4 + 3] * 12540; AV_ZERO64(block + i * 4); - tmp[i * 4 + 0] = (a1 + d1) >> 14; - tmp[i * 4 + 3] = (a1 - d1) >> 14; - tmp[i * 4 + 1] = (b1 + c1) >> 14; - tmp[i * 4 + 2] = (b1 - c1) >> 14; + tmp[i * 4 + 0] = (int)(a1 + d1) >> 14; + tmp[i * 4 + 3] = (int)(a1 - d1) >> 14; + tmp[i * 4 + 1] = (int)(b1 + c1) >> 14; + tmp[i * 4 + 2] = (int)(b1 - c1) >> 14; } for (i = 0; i < 4; i++) { @@ -116,13 +118,13 @@ static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride) c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274; d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540; dst[0 * stride + i] = av_clip_uint8(dst[0 * stride + i] + - ((a1 + d1 + 0x20000) >> 18)); + ((int)(a1 + d1 + 0x20000) >> 18)); dst[3 * stride + i] = av_clip_uint8(dst[3 * stride + i] + - ((a1 - d1 + 0x20000) >> 18)); + ((int)(a1 - d1 + 0x20000) >> 18)); dst[1 * stride + i] = av_clip_uint8(dst[1 * stride + i] + - ((b1 + c1 + 0x20000) >> 18)); + ((int)(b1 + c1 + 0x20000) >> 18)); dst[2 * stride + i] = av_clip_uint8(dst[2 * stride + i] + - ((b1 - c1 + 0x20000) >> 18)); + ((int)(b1 - c1 + 0x20000) >> 18)); } } diff --git a/media/ffvpx/libavcodec/vp8dsp.h b/media/ffvpx/libavcodec/vp8dsp.h index 0401c9221..eaae4aed6 100644 --- a/media/ffvpx/libavcodec/vp8dsp.h +++ b/media/ffvpx/libavcodec/vp8dsp.h @@ -70,12 +70,12 @@ typedef struct VP8DSPContext { void (*vp8_h_loop_filter_simple)(uint8_t *dst, ptrdiff_t stride, int flim); /** - * first dimension: width>>3, height is assumed equal to width + * first dimension: 4-log2(width) * second dimension: 0 if no vertical interpolation is needed; * 1 4-tap vertical interpolation filter (my & 1) * 2 6-tap vertical interpolation filter (!(my & 1)) * third dimension: same as second dimension, for horizontal interpolation - * so something like put_vp8_epel_pixels_tab[width>>3][2*!!my-(my&1)][2*!!mx-(mx&1)](..., mx, my) + * so something like put_vp8_epel_pixels_tab[4-log2(width)][2*!!my-(my&1)][2*!!mx-(mx&1)](..., mx, my) */ vp8_mc_func put_vp8_epel_pixels_tab[3][3][3]; vp8_mc_func put_vp8_bilinear_pixels_tab[3][3][3]; diff --git a/media/ffvpx/libavcodec/vp9.c b/media/ffvpx/libavcodec/vp9.c index 1aab6ba03..f2cf19424 100644 --- a/media/ffvpx/libavcodec/vp9.c +++ b/media/ffvpx/libavcodec/vp9.c @@ -30,176 +30,97 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" -#include "vp9dsp.h" +#include "vp9dec.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" #define VP9_SYNCCODE 0x498342 -struct VP9Filter { - uint8_t level[8 * 8]; - uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] - [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; -}; +#if HAVE_THREADS +static void vp9_free_entries(AVCodecContext *avctx) { + VP9Context *s = avctx->priv_data; -typedef struct VP9Block { - uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; - enum FilterMode filter; - VP56mv mv[4 /* b_idx */][2 /* ref */]; - enum BlockSize bs; - enum TxfmMode tx, uvtx; - enum BlockLevel bl; - enum BlockPartition bp; -} VP9Block; - -typedef struct VP9Context { - VP9SharedContext s; - - VP9DSPContext dsp; - VideoDSPContext vdsp; - GetBitContext gb; - VP56RangeCoder c; - VP56RangeCoder *c_b; - unsigned c_b_size; - VP9Block *b_base, *b; - int pass; - int row, row7, col, col7; - uint8_t *dst[3]; - ptrdiff_t y_stride, uv_stride; - - uint8_t ss_h, ss_v; - uint8_t last_bpp, bpp, bpp_index, bytesperpixel; - uint8_t last_keyframe; - // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal - // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads - // and are therefore per-stream. pix_fmt represents the value in the header - // of the currently processed frame. - int w, h; - enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; - unsigned sb_cols, sb_rows, rows, cols; - ThreadFrame next_refs[8]; - - struct { - uint8_t lim_lut[64]; - uint8_t mblim_lut[64]; - } filter_lut; - unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; - struct { - prob_context p; - uint8_t coef[4][2][2][6][6][3]; - } prob_ctx[4]; - struct { - prob_context p; - uint8_t coef[4][2][2][6][6][11]; - } prob; - struct { - unsigned y_mode[4][10]; - unsigned uv_mode[10][10]; - unsigned filter[4][3]; - unsigned mv_mode[7][4]; - unsigned intra[4][2]; - unsigned comp[5][2]; - unsigned single_ref[5][2][2]; - unsigned comp_ref[5][2]; - unsigned tx32p[2][4]; - unsigned tx16p[2][3]; - unsigned tx8p[2][2]; - unsigned skip[3][2]; - unsigned mv_joint[4]; - struct { - unsigned sign[2]; - unsigned classes[11]; - unsigned class0[2]; - unsigned bits[10][2]; - unsigned class0_fp[2][4]; - unsigned fp[4]; - unsigned class0_hp[2]; - unsigned hp[2]; - } mv_comp[2]; - unsigned partition[4][4][4]; - unsigned coef[4][2][2][6][6][3]; - unsigned eob[4][2][2][6][6][2]; - } counts; - - // contextual (left/above) cache - DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; - DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; - DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; - DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16]; - DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; - DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; - uint8_t *above_partition_ctx; - uint8_t *above_mode_ctx; - // FIXME maybe merge some of the below in a flags field? - uint8_t *above_y_nnz_ctx; - uint8_t *above_uv_nnz_ctx[2]; - uint8_t *above_skip_ctx; // 1bit - uint8_t *above_txfm_ctx; // 2bit - uint8_t *above_segpred_ctx; // 1bit - uint8_t *above_intra_ctx; // 1bit - uint8_t *above_comp_ctx; // 1bit - uint8_t *above_ref_ctx; // 2bit - uint8_t *above_filter_ctx; - VP56mv (*above_mv_ctx)[2]; - - // whole-frame cache - uint8_t *intra_pred_data[3]; - struct VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; - - // block reconstruction intermediates - int block_alloc_using_2pass; - int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; - uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; - struct { int x, y; } min_mv, max_mv; - DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; - DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; - uint16_t mvscale[3][2]; - uint8_t mvstep[3][2]; -} VP9Context; - -static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { - { - { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, - { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, - }, { - { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, - { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, + if (avctx->active_thread_type & FF_THREAD_SLICE) { + pthread_mutex_destroy(&s->progress_mutex); + pthread_cond_destroy(&s->progress_cond); + av_freep(&s->entries); } -}; +} + +static int vp9_alloc_entries(AVCodecContext *avctx, int n) { + VP9Context *s = avctx->priv_data; + int i; + + if (avctx->active_thread_type & FF_THREAD_SLICE) { + if (s->entries) + av_freep(&s->entries); + + s->entries = av_malloc_array(n, sizeof(atomic_int)); + + if (!s->entries) { + av_freep(&s->entries); + return AVERROR(ENOMEM); + } + + for (i = 0; i < n; i++) + atomic_init(&s->entries[i], 0); + + pthread_mutex_init(&s->progress_mutex, NULL); + pthread_cond_init(&s->progress_cond, NULL); + } + return 0; +} + +static void vp9_report_tile_progress(VP9Context *s, int field, int n) { + pthread_mutex_lock(&s->progress_mutex); + atomic_fetch_add_explicit(&s->entries[field], n, memory_order_release); + pthread_cond_signal(&s->progress_cond); + pthread_mutex_unlock(&s->progress_mutex); +} + +static void vp9_await_tile_progress(VP9Context *s, int field, int n) { + if (atomic_load_explicit(&s->entries[field], memory_order_acquire) >= n) + return; + + pthread_mutex_lock(&s->progress_mutex); + while (atomic_load_explicit(&s->entries[field], memory_order_relaxed) != n) + pthread_cond_wait(&s->progress_cond, &s->progress_mutex); + pthread_mutex_unlock(&s->progress_mutex); +} +#else +static void vp9_free_entries(AVCodecContext *avctx) {} +static int vp9_alloc_entries(AVCodecContext *avctx, int n) { return 0; } +#endif -static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f) +static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) { - ff_thread_release_buffer(ctx, &f->tf); + ff_thread_release_buffer(avctx, &f->tf); av_buffer_unref(&f->extradata); av_buffer_unref(&f->hwaccel_priv_buf); f->segmentation_map = NULL; f->hwaccel_picture_private = NULL; } -static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) +static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int ret, sz; - if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0) + ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) return ret; + sz = 64 * s->sb_cols * s->sb_rows; - if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) { + f->extradata = av_buffer_allocz(sz * (1 + sizeof(VP9mvrefPair))); + if (!f->extradata) { goto fail; } f->segmentation_map = f->extradata->data; - f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz); + f->mv = (VP9mvrefPair *) (f->extradata->data + sz); - if (ctx->hwaccel) { - const AVHWAccel *hwaccel = ctx->hwaccel; + if (avctx->hwaccel) { + const AVHWAccel *hwaccel = avctx->hwaccel; av_assert0(!f->hwaccel_picture_private); if (hwaccel->frame_priv_data_size) { f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); @@ -212,19 +133,21 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) return 0; fail: - vp9_unref_frame(ctx, f); + vp9_frame_unref(avctx, f); return AVERROR(ENOMEM); } -static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) +static int vp9_frame_ref(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) { - int res; + int ret; + + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + return ret; - if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) { - return res; - } else if (!(dst->extradata = av_buffer_ref(src->extradata))) { + dst->extradata = av_buffer_ref(src->extradata); + if (!dst->extradata) goto fail; - } dst->segmentation_map = src->segmentation_map; dst->mv = src->mv; @@ -240,44 +163,54 @@ static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) return 0; fail: - vp9_unref_frame(ctx, dst); + vp9_frame_unref(avctx, dst); return AVERROR(ENOMEM); } -static int update_size(AVCodecContext *ctx, int w, int h) +static int update_size(AVCodecContext *avctx, int w, int h) { -#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL + CONFIG_VP9_VAAPI_HWACCEL) +#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL * 2 + CONFIG_VP9_VAAPI_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; uint8_t *p; - int bytesperpixel = s->bytesperpixel, res, cols, rows; + int bytesperpixel = s->bytesperpixel, ret, cols, rows; + int lflvl_len, i; av_assert0(w > 0 && h > 0); if (!(s->pix_fmt == s->gf_fmt && w == s->w && h == s->h)) { - if ((res = ff_set_dimensions(ctx, w, h)) < 0) - return res; + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) + return ret; - if (s->pix_fmt == AV_PIX_FMT_YUV420P) { + switch (s->pix_fmt) { + case AV_PIX_FMT_YUV420P: #if CONFIG_VP9_DXVA2_HWACCEL *fmtp++ = AV_PIX_FMT_DXVA2_VLD; #endif #if CONFIG_VP9_D3D11VA_HWACCEL *fmtp++ = AV_PIX_FMT_D3D11VA_VLD; + *fmtp++ = AV_PIX_FMT_D3D11; +#endif +#if CONFIG_VP9_VAAPI_HWACCEL + *fmtp++ = AV_PIX_FMT_VAAPI; #endif + break; + case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_YUV420P12: #if CONFIG_VP9_VAAPI_HWACCEL *fmtp++ = AV_PIX_FMT_VAAPI; #endif + break; } *fmtp++ = s->pix_fmt; *fmtp = AV_PIX_FMT_NONE; - res = ff_thread_get_format(ctx, pix_fmts); - if (res < 0) - return res; + ret = ff_thread_get_format(avctx, pix_fmts); + if (ret < 0) + return ret; - ctx->pix_fmt = res; + avctx->pix_fmt = ret; s->gf_fmt = s->pix_fmt; s->w = w; s->h = h; @@ -294,13 +227,14 @@ static int update_size(AVCodecContext *ctx, int w, int h) s->sb_rows = (h + 63) >> 6; s->cols = (w + 7) >> 3; s->rows = (h + 7) >> 3; + lflvl_len = avctx->active_thread_type == FF_THREAD_SLICE ? s->sb_rows : 1; #define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var) av_freep(&s->intra_pred_data[0]); // FIXME we slightly over-allocate here for subsampled chroma, but a little // bit of padding shouldn't affect performance... p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel + - sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); + lflvl_len * sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); if (!p) return AVERROR(ENOMEM); assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel); @@ -319,65 +253,78 @@ static int update_size(AVCodecContext *ctx, int w, int h) assign(s->above_comp_ctx, uint8_t *, 8); assign(s->above_ref_ctx, uint8_t *, 8); assign(s->above_filter_ctx, uint8_t *, 8); - assign(s->lflvl, struct VP9Filter *, 1); + assign(s->lflvl, VP9Filter *, lflvl_len); #undef assign - // these will be re-allocated a little later - av_freep(&s->b_base); - av_freep(&s->block_base); + if (s->td) { + for (i = 0; i < s->active_tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); + } + } - if (s->bpp != s->last_bpp) { - ff_vp9dsp_init(&s->dsp, s->bpp, ctx->flags & AV_CODEC_FLAG_BITEXACT); - ff_videodsp_init(&s->vdsp, s->bpp); - s->last_bpp = s->bpp; + if (s->s.h.bpp != s->last_bpp) { + ff_vp9dsp_init(&s->dsp, s->s.h.bpp, avctx->flags & AV_CODEC_FLAG_BITEXACT); + ff_videodsp_init(&s->vdsp, s->s.h.bpp); + s->last_bpp = s->s.h.bpp; } return 0; } -static int update_block_buffers(AVCodecContext *ctx) +static int update_block_buffers(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + int i; + VP9Context *s = avctx->priv_data; int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel; + VP9TileData *td = &s->td[0]; - if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) + if (td->b_base && td->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) return 0; - av_free(s->b_base); - av_free(s->block_base); + av_free(td->b_base); + av_free(td->block_base); chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v); chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v); if (s->s.frames[CUR_FRAME].uses_2pass) { int sbs = s->sb_cols * s->sb_rows; - s->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); - s->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + td->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); + td->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + 16 * 16 + 2 * chroma_eobs) * sbs); - if (!s->b_base || !s->block_base) + if (!td->b_base || !td->block_base) return AVERROR(ENOMEM); - s->uvblock_base[0] = s->block_base + sbs * 64 * 64 * bytesperpixel; - s->uvblock_base[1] = s->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); - s->uveob_base[0] = s->eob_base + 16 * 16 * sbs; - s->uveob_base[1] = s->uveob_base[0] + chroma_eobs * sbs; + td->uvblock_base[0] = td->block_base + sbs * 64 * 64 * bytesperpixel; + td->uvblock_base[1] = td->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; + td->eob_base = (uint8_t *) (td->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); + td->uveob_base[0] = td->eob_base + 16 * 16 * sbs; + td->uveob_base[1] = td->uveob_base[0] + chroma_eobs * sbs; } else { - s->b_base = av_malloc(sizeof(VP9Block)); - s->block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + - 16 * 16 + 2 * chroma_eobs); - if (!s->b_base || !s->block_base) - return AVERROR(ENOMEM); - s->uvblock_base[0] = s->block_base + 64 * 64 * bytesperpixel; - s->uvblock_base[1] = s->uvblock_base[0] + chroma_blocks * bytesperpixel; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + chroma_blocks * bytesperpixel); - s->uveob_base[0] = s->eob_base + 16 * 16; - s->uveob_base[1] = s->uveob_base[0] + chroma_eobs; + for (i = 1; i < s->active_tile_cols; i++) { + if (s->td[i].b_base && s->td[i].block_base) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + } + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].b_base = av_malloc(sizeof(VP9Block)); + s->td[i].block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + 16 * 16 + 2 * chroma_eobs); + if (!s->td[i].b_base || !s->td[i].block_base) + return AVERROR(ENOMEM); + s->td[i].uvblock_base[0] = s->td[i].block_base + 64 * 64 * bytesperpixel; + s->td[i].uvblock_base[1] = s->td[i].uvblock_base[0] + chroma_blocks * bytesperpixel; + s->td[i].eob_base = (uint8_t *) (s->td[i].uvblock_base[1] + chroma_blocks * bytesperpixel); + s->td[i].uveob_base[0] = s->td[i].eob_base + 16 * 16; + s->td[i].uveob_base[1] = s->td[i].uveob_base[0] + chroma_eobs; + } } s->block_alloc_using_2pass = s->s.frames[CUR_FRAME].uses_2pass; return 0; } -// for some reason the sign bit is at the end, not the start, of a bit sequence +// The sign bit is at the end, not the start, of a bit sequence static av_always_inline int get_sbits_inv(GetBitContext *gb, int n) { int v = get_bits(gb, n); @@ -386,7 +333,11 @@ static av_always_inline int get_sbits_inv(GetBitContext *gb, int n) static av_always_inline int inv_recenter_nonneg(int v, int m) { - return v > 2 * m ? v : v & 1 ? m - ((v + 1) >> 1) : m + (v >> 1); + if (v > 2 * m) + return v; + if (v & 1) + return m - ((v + 1) >> 1); + return m + (v >> 1); } // differential forward probability updates @@ -417,13 +368,13 @@ static int update_prob(VP56RangeCoder *c, int p) /* This code is trying to do a differential probability update. For a * current probability A in the range [1, 255], the difference to a new - * probability of any value can be expressed differentially as 1-A,255-A + * probability of any value can be expressed differentially as 1-A, 255-A * where some part of this (absolute range) exists both in positive as * well as the negative part, whereas another part only exists in one * half. We're trying to code this shared part differentially, i.e. * times two where the value of the lowest bit specifies the sign, and * the single part is then coded on top of this. This absolute difference - * then again has a value of [0,254], but a bigger value in this range + * then again has a value of [0, 254], but a bigger value in this range * indicates that we're further away from the original value A, so we * can code this as a VLC code, since higher values are increasingly * unlikely. The first 20 values in inv_map_table[] allow 'cheap, rough' @@ -448,34 +399,34 @@ static int update_prob(VP56RangeCoder *c, int p) 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p); } -static int read_colorspace_details(AVCodecContext *ctx) +static int read_colorspace_details(AVCodecContext *avctx) { static const enum AVColorSpace colorspaces[8] = { AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709, AVCOL_SPC_SMPTE170M, AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED, AVCOL_SPC_RGB, }; - VP9Context *s = ctx->priv_data; - int bits = ctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12 + VP9Context *s = avctx->priv_data; + int bits = avctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12 s->bpp_index = bits; - s->bpp = 8 + bits * 2; - s->bytesperpixel = (7 + s->bpp) >> 3; - ctx->colorspace = colorspaces[get_bits(&s->gb, 3)]; - if (ctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1 + s->s.h.bpp = 8 + bits * 2; + s->bytesperpixel = (7 + s->s.h.bpp) >> 3; + avctx->colorspace = colorspaces[get_bits(&s->gb, 3)]; + if (avctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1 static const enum AVPixelFormat pix_fmt_rgb[3] = { AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12 }; s->ss_h = s->ss_v = 0; - ctx->color_range = AVCOL_RANGE_JPEG; + avctx->color_range = AVCOL_RANGE_JPEG; s->pix_fmt = pix_fmt_rgb[bits]; - if (ctx->profile & 1) { + if (avctx->profile & 1) { if (get_bits1(&s->gb)) { - av_log(ctx, AV_LOG_ERROR, "Reserved bit set in RGB\n"); + av_log(avctx, AV_LOG_ERROR, "Reserved bit set in RGB\n"); return AVERROR_INVALIDDATA; } } else { - av_log(ctx, AV_LOG_ERROR, "RGB not supported in profile %d\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "RGB not supported in profile %d\n", + avctx->profile); return AVERROR_INVALIDDATA; } } else { @@ -487,18 +438,18 @@ static int read_colorspace_details(AVCodecContext *ctx) { { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12 }, { AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12 } } }; - ctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; - if (ctx->profile & 1) { + avctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + if (avctx->profile & 1) { s->ss_h = get_bits1(&s->gb); s->ss_v = get_bits1(&s->gb); s->pix_fmt = pix_fmt_for_ss[bits][s->ss_v][s->ss_h]; if (s->pix_fmt == AV_PIX_FMT_YUV420P) { - av_log(ctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n", + avctx->profile); return AVERROR_INVALIDDATA; } else if (get_bits1(&s->gb)) { - av_log(ctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n", + avctx->profile); return AVERROR_INVALIDDATA; } } else { @@ -510,48 +461,51 @@ static int read_colorspace_details(AVCodecContext *ctx) return 0; } -static int decode_frame_header(AVCodecContext *ctx, +static int decode_frame_header(AVCodecContext *avctx, const uint8_t *data, int size, int *ref) { - VP9Context *s = ctx->priv_data; - int c, i, j, k, l, m, n, w, h, max, size2, res, sharp; + VP9Context *s = avctx->priv_data; + int c, i, j, k, l, m, n, w, h, max, size2, ret, sharp; int last_invisible; const uint8_t *data2; /* general header */ - if ((res = init_get_bits8(&s->gb, data, size)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n"); - return res; + if ((ret = init_get_bits8(&s->gb, data, size)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n"); + return ret; } if (get_bits(&s->gb, 2) != 0x2) { // frame marker - av_log(ctx, AV_LOG_ERROR, "Invalid frame marker\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid frame marker\n"); return AVERROR_INVALIDDATA; } - ctx->profile = get_bits1(&s->gb); - ctx->profile |= get_bits1(&s->gb) << 1; - if (ctx->profile == 3) ctx->profile += get_bits1(&s->gb); - if (ctx->profile > 3) { - av_log(ctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", ctx->profile); + avctx->profile = get_bits1(&s->gb); + avctx->profile |= get_bits1(&s->gb) << 1; + if (avctx->profile == 3) avctx->profile += get_bits1(&s->gb); + if (avctx->profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", avctx->profile); return AVERROR_INVALIDDATA; } - s->s.h.profile = ctx->profile; + s->s.h.profile = avctx->profile; if (get_bits1(&s->gb)) { *ref = get_bits(&s->gb, 3); return 0; } + s->last_keyframe = s->s.h.keyframe; - s->s.h.keyframe = !get_bits1(&s->gb); - last_invisible = s->s.h.invisible; - s->s.h.invisible = !get_bits1(&s->gb); - s->s.h.errorres = get_bits1(&s->gb); + s->s.h.keyframe = !get_bits1(&s->gb); + + last_invisible = s->s.h.invisible; + s->s.h.invisible = !get_bits1(&s->gb); + s->s.h.errorres = get_bits1(&s->gb); s->s.h.use_last_frame_mvs = !s->s.h.errorres && !last_invisible; + if (s->s.h.keyframe) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if ((res = read_colorspace_details(ctx)) < 0) - return res; + if ((ret = read_colorspace_details(avctx)) < 0) + return ret; // for profile 1, here follows the subsampling bits s->s.h.refreshrefmask = 0xff; w = get_bits(&s->gb, 16) + 1; @@ -559,24 +513,24 @@ static int decode_frame_header(AVCodecContext *ctx, if (get_bits1(&s->gb)) // display size skip_bits(&s->gb, 32); } else { - s->s.h.intraonly = s->s.h.invisible ? get_bits1(&s->gb) : 0; - s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); + s->s.h.intraonly = s->s.h.invisible ? get_bits1(&s->gb) : 0; + s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); if (s->s.h.intraonly) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if (ctx->profile >= 1) { - if ((res = read_colorspace_details(ctx)) < 0) - return res; + if (avctx->profile >= 1) { + if ((ret = read_colorspace_details(avctx)) < 0) + return ret; } else { s->ss_h = s->ss_v = 1; - s->bpp = 8; + s->s.h.bpp = 8; s->bpp_index = 0; s->bytesperpixel = 1; s->pix_fmt = AV_PIX_FMT_YUV420P; - ctx->colorspace = AVCOL_SPC_BT470BG; - ctx->color_range = AVCOL_RANGE_JPEG; + avctx->colorspace = AVCOL_SPC_BT470BG; + avctx->color_range = AVCOL_RANGE_MPEG; } s->s.h.refreshrefmask = get_bits(&s->gb, 8); w = get_bits(&s->gb, 16) + 1; @@ -594,7 +548,7 @@ static int decode_frame_header(AVCodecContext *ctx, if (!s->s.refs[s->s.h.refidx[0]].f->buf[0] || !s->s.refs[s->s.h.refidx[1]].f->buf[0] || !s->s.refs[s->s.h.refidx[2]].f->buf[0]) { - av_log(ctx, AV_LOG_ERROR, "Not all references are available\n"); + av_log(avctx, AV_LOG_ERROR, "Not all references are available\n"); return AVERROR_INVALIDDATA; } if (get_bits1(&s->gb)) { @@ -660,8 +614,20 @@ static int decode_frame_header(AVCodecContext *ctx, sharp = get_bits(&s->gb, 3); // if sharpness changed, reinit lim/mblim LUTs. if it didn't change, keep // the old cache values since they are still valid - if (s->s.h.filter.sharpness != sharp) - memset(s->filter_lut.lim_lut, 0, sizeof(s->filter_lut.lim_lut)); + if (s->s.h.filter.sharpness != sharp) { + for (i = 1; i <= 63; i++) { + int limit = i; + + if (sharp > 0) { + limit >>= (sharp + 3) >> 2; + limit = FFMIN(limit, 9 - sharp); + } + limit = FFMAX(limit, 1); + + s->filter_lut.lim_lut[i] = limit; + s->filter_lut.mblim_lut[i] = 2 * (i + 2) + limit; + } + } s->s.h.filter.sharpness = sharp; if ((s->s.h.lf_delta.enabled = get_bits1(&s->gb))) { if ((s->s.h.lf_delta.updated = get_bits1(&s->gb))) { @@ -682,7 +648,7 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.lossless = s->s.h.yac_qi == 0 && s->s.h.ydc_qdelta == 0 && s->s.h.uvdc_qdelta == 0 && s->s.h.uvac_qdelta == 0; if (s->s.h.lossless) - ctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; + avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; /* segmentation header info */ if ((s->s.h.segmentation.enabled = get_bits1(&s->gb))) { @@ -690,11 +656,10 @@ static int decode_frame_header(AVCodecContext *ctx, for (i = 0; i < 7; i++) s->s.h.segmentation.prob[i] = get_bits1(&s->gb) ? get_bits(&s->gb, 8) : 255; - if ((s->s.h.segmentation.temporal = get_bits1(&s->gb))) { + if ((s->s.h.segmentation.temporal = get_bits1(&s->gb))) for (i = 0; i < 3; i++) s->s.h.segmentation.pred_prob[i] = get_bits1(&s->gb) ? get_bits(&s->gb, 8) : 255; - } } if (get_bits1(&s->gb)) { @@ -728,10 +693,10 @@ static int decode_frame_header(AVCodecContext *ctx, quvac = av_clip_uintp2(qyac + s->s.h.uvac_qdelta, 8); qyac = av_clip_uintp2(qyac, 8); - s->s.h.segmentation.feat[i].qmul[0][0] = vp9_dc_qlookup[s->bpp_index][qydc]; - s->s.h.segmentation.feat[i].qmul[0][1] = vp9_ac_qlookup[s->bpp_index][qyac]; - s->s.h.segmentation.feat[i].qmul[1][0] = vp9_dc_qlookup[s->bpp_index][quvdc]; - s->s.h.segmentation.feat[i].qmul[1][1] = vp9_ac_qlookup[s->bpp_index][quvac]; + s->s.h.segmentation.feat[i].qmul[0][0] = ff_vp9_dc_qlookup[s->bpp_index][qydc]; + s->s.h.segmentation.feat[i].qmul[0][1] = ff_vp9_ac_qlookup[s->bpp_index][qyac]; + s->s.h.segmentation.feat[i].qmul[1][0] = ff_vp9_dc_qlookup[s->bpp_index][quvdc]; + s->s.h.segmentation.feat[i].qmul[1][1] = ff_vp9_ac_qlookup[s->bpp_index][quvac]; sh = s->s.h.filter.level >= 32; if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[i].lf_enabled) { @@ -761,10 +726,10 @@ static int decode_frame_header(AVCodecContext *ctx, } /* tiling info */ - if ((res = update_size(ctx, w, h)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", + if ((ret = update_size(avctx, w, h)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, s->pix_fmt); - return res; + return ret; } for (s->s.h.tiling.log2_tile_cols = 0; s->sb_cols > (64 << s->s.h.tiling.log2_tile_cols); @@ -780,12 +745,36 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.tiling.log2_tile_rows = decode012(&s->gb); s->s.h.tiling.tile_rows = 1 << s->s.h.tiling.log2_tile_rows; if (s->s.h.tiling.tile_cols != (1 << s->s.h.tiling.log2_tile_cols)) { + int n_range_coders; + VP56RangeCoder *rc; + + if (s->td) { + for (i = 0; i < s->active_tile_cols; i++) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + av_free(s->td); + } + s->s.h.tiling.tile_cols = 1 << s->s.h.tiling.log2_tile_cols; - s->c_b = av_fast_realloc(s->c_b, &s->c_b_size, - sizeof(VP56RangeCoder) * s->s.h.tiling.tile_cols); - if (!s->c_b) { - av_log(ctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n"); + vp9_free_entries(avctx); + s->active_tile_cols = avctx->active_thread_type == FF_THREAD_SLICE ? + s->s.h.tiling.tile_cols : 1; + vp9_alloc_entries(avctx, s->sb_rows); + if (avctx->active_thread_type == FF_THREAD_SLICE) { + n_range_coders = 4; // max_tile_rows + } else { + n_range_coders = s->s.h.tiling.tile_cols; + } + s->td = av_mallocz_array(s->active_tile_cols, sizeof(VP9TileData) + + n_range_coders * sizeof(VP56RangeCoder)); + if (!s->td) return AVERROR(ENOMEM); + rc = (VP56RangeCoder *) &s->td[s->active_tile_cols]; + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].s = s; + s->td[i].c_b = rc; + rc += n_range_coders; } } @@ -795,17 +784,17 @@ static int decode_frame_header(AVCodecContext *ctx, AVFrame *ref = s->s.refs[s->s.h.refidx[i]].f; int refw = ref->width, refh = ref->height; - if (ref->format != ctx->pix_fmt) { - av_log(ctx, AV_LOG_ERROR, + if (ref->format != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, "Ref pixfmt (%s) did not match current frame (%s)", av_get_pix_fmt_name(ref->format), - av_get_pix_fmt_name(ctx->pix_fmt)); + av_get_pix_fmt_name(avctx->pix_fmt)); return AVERROR_INVALIDDATA; } else if (refw == w && refh == h) { s->mvscale[i][0] = s->mvscale[i][1] = 0; } else { if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 16 * refh) { - av_log(ctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Invalid ref frame dimensions %dx%d for frame size %dx%d\n", refw, refh, w, h); return AVERROR_INVALIDDATA; @@ -820,19 +809,19 @@ static int decode_frame_header(AVCodecContext *ctx, if (s->s.h.keyframe || s->s.h.errorres || (s->s.h.intraonly && s->s.h.resetctx == 3)) { s->prob_ctx[0].p = s->prob_ctx[1].p = s->prob_ctx[2].p = - s->prob_ctx[3].p = vp9_default_probs; - memcpy(s->prob_ctx[0].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); - memcpy(s->prob_ctx[1].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); - memcpy(s->prob_ctx[2].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); - memcpy(s->prob_ctx[3].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); + s->prob_ctx[3].p = ff_vp9_default_probs; + memcpy(s->prob_ctx[0].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[1].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[2].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[3].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); } else if (s->s.h.intraonly && s->s.h.resetctx == 2) { - s->prob_ctx[c].p = vp9_default_probs; - memcpy(s->prob_ctx[c].coef, vp9_default_coef_probs, - sizeof(vp9_default_coef_probs)); + s->prob_ctx[c].p = ff_vp9_default_probs; + memcpy(s->prob_ctx[c].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); } // next 16 bits is size of the rest of the header (arith-coded) @@ -841,24 +830,30 @@ static int decode_frame_header(AVCodecContext *ctx, data2 = align_get_bits(&s->gb); if (size2 > size - (data2 - data)) { - av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid compressed header size\n"); return AVERROR_INVALIDDATA; } - ff_vp56_init_range_decoder(&s->c, data2, size2); + ret = ff_vp56_init_range_decoder(&s->c, data2, size2); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit - av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n"); + av_log(avctx, AV_LOG_ERROR, "Marker bit was set\n"); return AVERROR_INVALIDDATA; } - if (s->s.h.keyframe || s->s.h.intraonly) { - memset(s->counts.coef, 0, sizeof(s->counts.coef)); - memset(s->counts.eob, 0, sizeof(s->counts.eob)); - } else { - memset(&s->counts, 0, sizeof(s->counts)); + for (i = 0; i < s->active_tile_cols; i++) { + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(s->td[i].counts.coef, 0, sizeof(s->td[0].counts.coef)); + memset(s->td[i].counts.eob, 0, sizeof(s->td[0].counts.eob)); + } else { + memset(&s->td[i].counts, 0, sizeof(s->td[0].counts)); + } } - // FIXME is it faster to not copy here, but do it down in the fw updates - // as explicit copies if the fw update is missing (and skip the copy upon - // fw update)? + + /* FIXME is it faster to not copy here, but do it down in the fw updates + * as explicit copies if the fw update is missing (and skip the copy upon + * fw update)? */ s->prob.p = s->prob_ctx[c].p; // txfm updates @@ -899,13 +894,12 @@ static int decode_frame_header(AVCodecContext *ctx, if (m >= 3 && l == 0) // dc only has 3 pt break; for (n = 0; n < 3; n++) { - if (vp56_rac_get_prob_branchy(&s->c, 252)) { + if (vp56_rac_get_prob_branchy(&s->c, 252)) p[n] = update_prob(&s->c, r[n]); - } else { + else p[n] = r[n]; - } } - p[3] = 0; + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); } } else { for (j = 0; j < 2; j++) @@ -917,7 +911,7 @@ static int decode_frame_header(AVCodecContext *ctx, if (m > 3 && l == 0) // dc only has 3 pt break; memcpy(p, r, 3); - p[3] = 0; + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); } } if (s->s.h.txfmmode == i) @@ -988,7 +982,8 @@ static int decode_frame_header(AVCodecContext *ctx, for (k = 0; k < 3; k++) if (vp56_rac_get_prob_branchy(&s->c, 252)) s->prob.p.partition[3 - i][j][k] = - update_prob(&s->c, s->prob.p.partition[3 - i][j][k]); + update_prob(&s->c, + s->prob.p.partition[3 - i][j][k]); // mv fields don't use the update_prob subexp model for some reason for (i = 0; i < 3; i++) @@ -997,7 +992,8 @@ static int decode_frame_header(AVCodecContext *ctx, for (i = 0; i < 2; i++) { if (vp56_rac_get_prob_branchy(&s->c, 252)) - s->prob.p.mv_comp[i].sign = (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].sign = + (vp8_rac_get_uint(&s->c, 7) << 1) | 1; for (j = 0; j < 10; j++) if (vp56_rac_get_prob_branchy(&s->c, 252)) @@ -1005,7 +1001,8 @@ static int decode_frame_header(AVCodecContext *ctx, (vp8_rac_get_uint(&s->c, 7) << 1) | 1; if (vp56_rac_get_prob_branchy(&s->c, 252)) - s->prob.p.mv_comp[i].class0 = (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].class0 = + (vp8_rac_get_uint(&s->c, 7) << 1) | 1; for (j = 0; j < 10; j++) if (vp56_rac_get_prob_branchy(&s->c, 252)) @@ -1042,2955 +1039,438 @@ static int decode_frame_header(AVCodecContext *ctx, return (data2 - data) + size2; } -static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, - VP9Context *s) -{ - dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x); - dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y); -} - -static void find_ref_mvs(VP9Context *s, - VP56mv *pmv, int ref, int z, int idx, int sb) +static void decode_sb(VP9TileData *td, int row, int col, VP9Filter *lflvl, + ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { - [BS_64x64] = {{ 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 }, - { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 }}, - [BS_64x32] = {{ 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 }}, - [BS_32x64] = {{ -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 }, - { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 }}, - [BS_32x32] = {{ 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_32x16] = {{ 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 }, - { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_16x32] = {{ -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 }, - { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 }}, - [BS_16x16] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 }, - { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }}, - [BS_16x8] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 }, - { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 }}, - [BS_8x16] = {{ -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 }, - { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 }}, - [BS_8x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_8x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_4x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - [BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, - { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }}, - }; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; - const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; -#define INVALID_MV 0x80008000U - uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; - int i; - -#define RETURN_DIRECT_MV(mv) \ - do { \ - uint32_t m = AV_RN32A(&mv); \ - if (!idx) { \ - AV_WN32A(pmv, m); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - AV_WN32A(pmv, m); \ - return; \ - } \ - } while (0) - - if (sb >= 0) { - if (sb == 2 || sb == 1) { - RETURN_DIRECT_MV(b->mv[0][z]); - } else if (sb == 3) { - RETURN_DIRECT_MV(b->mv[2][z]); - RETURN_DIRECT_MV(b->mv[1][z]); - RETURN_DIRECT_MV(b->mv[0][z]); - } + const VP9Context *s = td->s; + int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | + (((td->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); + const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? ff_vp9_default_kf_partition_probs[bl][c] : + s->prob.p.partition[bl][c]; + enum BlockPartition bp; + ptrdiff_t hbs = 4 >> bl; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; + int bytesperpixel = s->bytesperpixel; -#define RETURN_MV(mv) \ - do { \ - if (sb > 0) { \ - VP56mv tmp; \ - uint32_t m; \ - av_assert2(idx == 1); \ - av_assert2(mem != INVALID_MV); \ - if (mem_sub8x8 == INVALID_MV) { \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (m != mem) { \ - AV_WN32A(pmv, m); \ - return; \ - } \ - mem_sub8x8 = AV_RN32A(&mv); \ - } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (m != mem) { \ - AV_WN32A(pmv, m); \ - } else { \ - /* BUG I'm pretty sure this isn't the intention */ \ - AV_WN32A(pmv, 0); \ - } \ - return; \ - } \ - } else { \ - uint32_t m = AV_RN32A(&mv); \ - if (!idx) { \ - clamp_mv(pmv, &mv, s); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - clamp_mv(pmv, &mv, s); \ - return; \ - } \ - } \ - } while (0) - - if (row > 0) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; - if (mv->ref[0] == ref) { - RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); + if (bl == BL_8X8) { + bp = vp8_rac_get_tree(td->c, ff_vp9_partition_tree, p); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); + } else if (col + hbs < s->cols) { // FIXME why not <=? + if (row + hbs < s->rows) { // FIXME why not <=? + bp = vp8_rac_get_tree(td->c, ff_vp9_partition_tree, p); + switch (bp) { + case PARTITION_NONE: + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); + break; + case PARTITION_H: + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, bl, bp); + break; + case PARTITION_V: + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); + yoff += hbs * 8 * bytesperpixel; + uvoff += hbs * 8 * bytesperpixel >> s->ss_h; + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, bl, bp); + break; + case PARTITION_SPLIT: + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row + hbs, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + break; + default: + av_assert0(0); } + } else if (vp56_rac_get_prob_branchy(td->c, p[1])) { + bp = PARTITION_SPLIT; + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + } else { + bp = PARTITION_H; + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } - if (col > s->tile_col_start) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; - if (mv->ref[0] == ref) { - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]); - } + } else if (row + hbs < s->rows) { // FIXME why not <=? + if (vp56_rac_get_prob_branchy(td->c, p[2])) { + bp = PARTITION_SPLIT; + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + } else { + bp = PARTITION_V; + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } - i = 2; } else { - i = 0; + bp = PARTITION_SPLIT; + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); } + td->counts.partition[bl][c][bp]++; +} - // previously coded MVs in this neighbourhood, using same reference frame - for (; i < 8; i++) { - int c = p[i][0] + col, r = p[i][1] + row; - - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; +static void decode_sb_mem(VP9TileData *td, int row, int col, VP9Filter *lflvl, + ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) +{ + const VP9Context *s = td->s; + VP9Block *b = td->b; + ptrdiff_t hbs = 4 >> bl; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; + int bytesperpixel = s->bytesperpixel; - if (mv->ref[0] == ref) { - RETURN_MV(mv->mv[0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(mv->mv[1]); - } + if (bl == BL_8X8) { + av_assert2(b->bl == BL_8X8); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (td->b->bl == bl) { + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + if (b->bp == PARTITION_H && row + hbs < s->rows) { + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (b->bp == PARTITION_V && col + hbs < s->cols) { + yoff += hbs * 8 * bytesperpixel; + uvoff += hbs * 8 * bytesperpixel >> s->ss_h; + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); } - } - - // MV at this position in previous frame, using same reference frame - if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; - - if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) - ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0); - if (mv->ref[0] == ref) { - RETURN_MV(mv->mv[0]); - } else if (mv->ref[1] == ref) { - RETURN_MV(mv->mv[1]); + } else { + decode_sb_mem(td, row, col, lflvl, yoff, uvoff, bl + 1); + if (col + hbs < s->cols) { // FIXME why not <=? + if (row + hbs < s->rows) { + decode_sb_mem(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row + hbs, col + hbs, lflvl, + yoff + 8 * hbs * bytesperpixel, + uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); + } else { + yoff += hbs * 8 * bytesperpixel; + uvoff += hbs * 8 * bytesperpixel >> s->ss_h; + decode_sb_mem(td, row, col + hbs, lflvl, yoff, uvoff, bl + 1); + } + } else if (row + hbs < s->rows) { + yoff += hbs * 8 * y_stride; + uvoff += hbs * 8 * uv_stride >> s->ss_v; + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } } +} -#define RETURN_SCALE_MV(mv, scale) \ - do { \ - if (scale) { \ - VP56mv mv_temp = { -mv.x, -mv.y }; \ - RETURN_MV(mv_temp); \ - } else { \ - RETURN_MV(mv); \ - } \ - } while (0) - - // previously coded MVs in this neighbourhood, using different reference frame - for (i = 0; i < 8; i++) { - int c = p[i][0] + col, r = p[i][1] + row; +static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) +{ + int sb_start = ( idx * n) >> log2_n; + int sb_end = ((idx + 1) * n) >> log2_n; + *start = FFMIN(sb_start, n) << 3; + *end = FFMIN(sb_end, n) << 3; +} - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; +static void free_buffers(VP9Context *s) +{ + int i; - if (mv->ref[0] != ref && mv->ref[0] >= 0) { - RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); - } - if (mv->ref[1] != ref && mv->ref[1] >= 0 && - // BUG - libvpx has this condition regardless of whether - // we used the first ref MV and pre-scaling - AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { - RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); - } - } + av_freep(&s->intra_pred_data[0]); + for (i = 0; i < s->active_tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); } +} - // MV at this position in previous frame, using different reference frame - if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; +static av_cold int vp9_decode_free(AVCodecContext *avctx) +{ + VP9Context *s = avctx->priv_data; + int i; - // no need to await_progress, because we already did that above - if (mv->ref[0] != ref && mv->ref[0] >= 0) { - RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); - } - if (mv->ref[1] != ref && mv->ref[1] >= 0 && - // BUG - libvpx has this condition regardless of whether - // we used the first ref MV and pre-scaling - AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { - RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); - } + for (i = 0; i < 3; i++) { + if (s->s.frames[i].tf.f->buf[0]) + vp9_frame_unref(avctx, &s->s.frames[i]); + av_frame_free(&s->s.frames[i].tf.f); + } + for (i = 0; i < 8; i++) { + if (s->s.refs[i].f->buf[0]) + ff_thread_release_buffer(avctx, &s->s.refs[i]); + av_frame_free(&s->s.refs[i].f); + if (s->next_refs[i].f->buf[0]) + ff_thread_release_buffer(avctx, &s->next_refs[i]); + av_frame_free(&s->next_refs[i].f); } - AV_ZERO32(pmv); - clamp_mv(pmv, pmv, s); -#undef INVALID_MV -#undef RETURN_MV -#undef RETURN_SCALE_MV + free_buffers(s); + vp9_free_entries(avctx); + av_freep(&s->td); + return 0; } -static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) +static int decode_tiles(AVCodecContext *avctx, + const uint8_t *data, int size) { - int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign); - int n, c = vp8_rac_get_tree(&s->c, vp9_mv_class_tree, - s->prob.p.mv_comp[idx].classes); - - s->counts.mv_comp[idx].sign[sign]++; - s->counts.mv_comp[idx].classes[c]++; - if (c) { - int m; - - for (n = 0, m = 0; m < c; m++) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]); - n |= bit << m; - s->counts.mv_comp[idx].bits[m][bit]++; - } - n <<= 3; - bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp); - n |= bit << 1; - s->counts.mv_comp[idx].fp[bit]++; - if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp); - s->counts.mv_comp[idx].hp[bit]++; - n |= bit; - } else { - n |= 1; - // bug in libvpx - we count for bw entropy purposes even if the - // bit wasn't coded - s->counts.mv_comp[idx].hp[1]++; - } - n += 8 << c; - } else { - n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0); - s->counts.mv_comp[idx].class0[n]++; - bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree, - s->prob.p.mv_comp[idx].class0_fp[n]); - s->counts.mv_comp[idx].class0_fp[n][bit]++; - n = (n << 3) | (bit << 1); - if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp); - s->counts.mv_comp[idx].class0_hp[bit]++; - n |= bit; - } else { - n |= 1; - // bug in libvpx - we count for bw entropy purposes even if the - // bit wasn't coded - s->counts.mv_comp[idx].class0_hp[1]++; - } - } + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[0]; + int row, col, tile_row, tile_col, ret; + int bytesperpixel; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + AVFrame *f; + ptrdiff_t yoff, uvoff, ls_y, ls_uv; - return sign ? -(n + 1) : (n + 1); -} + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + bytesperpixel = s->bytesperpixel; -static void fill_mv(VP9Context *s, - VP56mv *mv, int mode, int sb) -{ - VP9Block *b = s->b; + yoff = uvoff = 0; + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); - if (mode == ZEROMV) { - AV_ZERO64(mv); - } else { - int hp; - - // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV, - mode == NEWMV ? -1 : sb); - // FIXME maybe move this code into find_ref_mvs() - if ((mode == NEWMV || sb == -1) && - !(hp = s->s.h.highprecisionmvs && abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) { - if (mv[0].y & 1) { - if (mv[0].y < 0) - mv[0].y++; - else - mv[0].y--; + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + int64_t tile_size; + + if (tile_col == s->s.h.tiling.tile_cols - 1 && + tile_row == s->s.h.tiling.tile_rows - 1) { + tile_size = size; + } else { + tile_size = AV_RB32(data); + data += 4; + size -= 4; + } + if (tile_size > size) { + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return AVERROR_INVALIDDATA; } - if (mv[0].x & 1) { - if (mv[0].x < 0) - mv[0].x++; - else - mv[0].x--; + ret = ff_vp56_init_range_decoder(&td->c_b[tile_col], data, tile_size); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&td->c_b[tile_col], 128)) { // marker bit + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return AVERROR_INVALIDDATA; } + data += tile_size; + size -= tile_size; } - if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree, - s->prob.p.mv_joint); - - s->counts.mv_joint[j]++; - if (j >= MV_JOINT_V) - mv[0].y += read_mv_component(s, 0, hp); - if (j & 1) - mv[0].x += read_mv_component(s, 1, hp); - } - if (b->comp) { - // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV, - mode == NEWMV ? -1 : sb); - if ((mode == NEWMV || sb == -1) && - !(hp = s->s.h.highprecisionmvs && abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) { - if (mv[1].y & 1) { - if (mv[1].y < 0) - mv[1].y++; - else - mv[1].y--; + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + VP9Filter *lflvl_ptr = s->lflvl; + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + set_tile_offset(&tile_col_start, &tile_col_end, + tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + if (s->pass != 2) { + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); + + td->c = &td->c_b[tile_col]; } - if (mv[1].x & 1) { - if (mv[1].x < 0) - mv[1].x++; - else - mv[1].x--; + + for (col = tile_col_start; + col < tile_col_end; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + if (s->pass != 1) { + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + } + + if (s->pass == 2) { + decode_sb_mem(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } else { + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } } } - if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree, - s->prob.p.mv_joint); - - s->counts.mv_joint[j]++; - if (j >= MV_JOINT_V) - mv[1].y += read_mv_component(s, 0, hp); - if (j & 1) - mv[1].x += read_mv_component(s, 1, hp); + + if (s->pass == 1) + continue; + + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0], + f->data[0] + yoff + 63 * ls_y, + 8 * s->cols * bytesperpixel); + memcpy(s->intra_pred_data[1], + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * s->cols * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2], + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * s->cols * bytesperpixel >> s->ss_h); + } + + // loopfilter one row + if (s->s.h.filter.level) { + yoff2 = yoff; + uvoff2 = uvoff; + lflvl_ptr = s->lflvl; + for (col = 0; col < s->cols; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, + yoff2, uvoff2); + } } - } - } -} -static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, - ptrdiff_t stride, int v) -{ - switch (w) { - case 1: - do { - *ptr = v; - ptr += stride; - } while (--h); - break; - case 2: { - int v16 = v * 0x0101; - do { - AV_WN16A(ptr, v16); - ptr += stride; - } while (--h); - break; - } - case 4: { - uint32_t v32 = v * 0x01010101; - do { - AV_WN32A(ptr, v32); - ptr += stride; - } while (--h); - break; - } - case 8: { -#if HAVE_FAST_64BIT - uint64_t v64 = v * 0x0101010101010101ULL; - do { - AV_WN64A(ptr, v64); - ptr += stride; - } while (--h); -#else - uint32_t v32 = v * 0x01010101; - do { - AV_WN32A(ptr, v32); - AV_WN32A(ptr + 4, v32); - ptr += stride; - } while (--h); -#endif - break; - } + // FIXME maybe we can make this more finegrained by running the + // loopfilter per-block instead of after each sbrow + // In fact that would also make intra pred left preparation easier? + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0); + } } + return 0; } -static void decode_mode(AVCodecContext *ctx) +#if HAVE_THREADS +static av_always_inline +int decode_tiles_mt(AVCodecContext *avctx, void *tdata, int jobnr, + int threadnr) { - static const uint8_t left_ctx[N_BS_SIZES] = { - 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf - }; - static const uint8_t above_ctx[N_BS_SIZES] = { - 0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf - }; - static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = { - TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, - TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 - }; - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; - enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; - int bw4 = bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); - int bh4 = bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; - int have_a = row > 0, have_l = col > s->tile_col_start; - int vref, filter_id; - - if (!s->s.h.segmentation.enabled) { - b->seg_id = 0; - } else if (s->s.h.keyframe || s->s.h.intraonly) { - b->seg_id = !s->s.h.segmentation.update_map ? 0 : - vp8_rac_get_tree(&s->c, vp9_segmentation_tree, s->s.h.segmentation.prob); - } else if (!s->s.h.segmentation.update_map || - (s->s.h.segmentation.temporal && - vp56_rac_get_prob_branchy(&s->c, - s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + - s->left_segpred_ctx[row7]]))) { - if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { - int pred = 8, x; - uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; - - if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass) - ff_thread_await_progress(&s->s.frames[REF_FRAME_SEGMAP].tf, row >> 3, 0); - for (y = 0; y < h4; y++) { - int idx_base = (y + row) * 8 * s->sb_cols + col; - for (x = 0; x < w4; x++) - pred = FFMIN(pred, refsegmap[idx_base + x]); - } - av_assert1(pred < 8); - b->seg_id = pred; - } else { - b->seg_id = 0; - } + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[jobnr]; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + int bytesperpixel = s->bytesperpixel, row, col, tile_row; + unsigned tile_cols_len; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + VP9Filter *lflvl_ptr_base; + AVFrame *f; - memset(&s->above_segpred_ctx[col], 1, w4); - memset(&s->left_segpred_ctx[row7], 1, h4); - } else { - b->seg_id = vp8_rac_get_tree(&s->c, vp9_segmentation_tree, - s->s.h.segmentation.prob); + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; - memset(&s->above_segpred_ctx[col], 0, w4); - memset(&s->left_segpred_ctx[row7], 0, h4); - } - if (s->s.h.segmentation.enabled && - (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { - setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col], - bw4, bh4, 8 * s->sb_cols, b->seg_id); - } + set_tile_offset(&tile_col_start, &tile_col_end, + jobnr, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + uvoff = (64 * bytesperpixel >> s->ss_h)*(tile_col_start >> 3); + yoff = (64 * bytesperpixel)*(tile_col_start >> 3); + lflvl_ptr_base = s->lflvl+(tile_col_start >> 3); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); + + td->c = &td->c_b[tile_row]; + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + VP9Filter *lflvl_ptr = lflvl_ptr_base+s->sb_cols*(row >> 3); + + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); - b->skip = s->s.h.segmentation.enabled && - s->s.h.segmentation.feat[b->seg_id].skip_enabled; - if (!b->skip) { - int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col]; - b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]); - s->counts.skip[c][b->skip]++; - } + for (col = tile_col_start; + col < tile_col_end; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } - if (s->s.h.keyframe || s->s.h.intraonly) { - b->intra = 1; - } else if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { - b->intra = !s->s.h.segmentation.feat[b->seg_id].ref_val; - } else { - int c, bit; + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + tile_cols_len = tile_col_end - tile_col_start; + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0] + (tile_col_start * 8 * bytesperpixel), + f->data[0] + yoff + 63 * ls_y, + 8 * tile_cols_len * bytesperpixel); + memcpy(s->intra_pred_data[1] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + } - if (have_a && have_l) { - c = s->above_intra_ctx[col] + s->left_intra_ctx[row7]; - c += (c == 2); - } else { - c = have_a ? 2 * s->above_intra_ctx[col] : - have_l ? 2 * s->left_intra_ctx[row7] : 0; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]); - s->counts.intra[c][bit]++; - b->intra = !bit; - } - - if ((b->intra || !b->skip) && s->s.h.txfmmode == TX_SWITCHABLE) { - int c; - if (have_a) { - if (have_l) { - c = (s->above_skip_ctx[col] ? max_tx : - s->above_txfm_ctx[col]) + - (s->left_skip_ctx[row7] ? max_tx : - s->left_txfm_ctx[row7]) > max_tx; - } else { - c = s->above_skip_ctx[col] ? 1 : - (s->above_txfm_ctx[col] * 2 > max_tx); - } - } else if (have_l) { - c = s->left_skip_ctx[row7] ? 1 : - (s->left_txfm_ctx[row7] * 2 > max_tx); - } else { - c = 1; - } - switch (max_tx) { - case TX_32X32: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]); - if (b->tx) { - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]); - if (b->tx == 2) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]); - } - s->counts.tx32p[c][b->tx]++; - break; - case TX_16X16: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]); - if (b->tx) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]); - s->counts.tx16p[c][b->tx]++; - break; - case TX_8X8: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]); - s->counts.tx8p[c][b->tx]++; - break; - case TX_4X4: - b->tx = TX_4X4; - break; - } - } else { - b->tx = FFMIN(max_tx, s->s.h.txfmmode); - } - - if (s->s.h.keyframe || s->s.h.intraonly) { - uint8_t *a = &s->above_mode_ctx[col * 2]; - uint8_t *l = &s->left_mode_ctx[(row7) << 1]; - - b->comp = 0; - if (b->bs > BS_8x8) { - // FIXME the memory storage intermediates here aren't really - // necessary, they're just there to make the code slightly - // simpler for now - b->mode[0] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[0]][l[0]]); - if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); - l[0] = a[1] = b->mode[1]; - } else { - l[0] = a[1] = b->mode[1] = b->mode[0]; - } - if (b->bs != BS_4x8) { - b->mode[2] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[0]][l[1]]); - if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); - l[1] = a[1] = b->mode[3]; - } else { - l[1] = a[1] = b->mode[3] = b->mode[2]; - } - } else { - b->mode[2] = b->mode[0]; - l[1] = a[1] = b->mode[3] = b->mode[1]; - } - } else { - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_ymode_probs[*a][*l]); - b->mode[3] = b->mode[2] = b->mode[1] = b->mode[0]; - // FIXME this can probably be optimized - memset(a, b->mode[0], bwh_tab[0][b->bs][0]); - memset(l, b->mode[0], bwh_tab[0][b->bs][1]); - } - b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - vp9_default_kf_uvmode_probs[b->mode[3]]); - } else if (b->intra) { - b->comp = 0; - if (b->bs > BS_8x8) { - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[0]]++; - if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[1]]++; - } else { - b->mode[1] = b->mode[0]; - } - if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[2]]++; - if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[3]]++; - } else { - b->mode[3] = b->mode[2]; - } - } else { - b->mode[2] = b->mode[0]; - b->mode[3] = b->mode[1]; - } - } else { - static const uint8_t size_group[10] = { - 3, 3, 3, 3, 2, 2, 2, 1, 1, 1 - }; - int sz = size_group[b->bs]; - - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.y_mode[sz]); - b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.y_mode[sz][b->mode[3]]++; - } - b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree, - s->prob.p.uv_mode[b->mode[3]]); - s->counts.uv_mode[b->mode[3]][b->uvmode]++; - } else { - static const uint8_t inter_mode_ctx_lut[14][14] = { - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 }, - }; - - if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { - av_assert2(s->s.h.segmentation.feat[b->seg_id].ref_val != 0); - b->comp = 0; - b->ref[0] = s->s.h.segmentation.feat[b->seg_id].ref_val - 1; - } else { - // read comp_pred flag - if (s->s.h.comppredmode != PRED_SWITCHABLE) { - b->comp = s->s.h.comppredmode == PRED_COMPREF; - } else { - int c; - - // FIXME add intra as ref=0xff (or -1) to make these easier? - if (have_a) { - if (have_l) { - if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) { - c = 4; - } else if (s->above_comp_ctx[col]) { - c = 2 + (s->left_intra_ctx[row7] || - s->left_ref_ctx[row7] == s->s.h.fixcompref); - } else if (s->left_comp_ctx[row7]) { - c = 2 + (s->above_intra_ctx[col] || - s->above_ref_ctx[col] == s->s.h.fixcompref); - } else { - c = (!s->above_intra_ctx[col] && - s->above_ref_ctx[col] == s->s.h.fixcompref) ^ - (!s->left_intra_ctx[row7] && - s->left_ref_ctx[row & 7] == s->s.h.fixcompref); - } - } else { - c = s->above_comp_ctx[col] ? 3 : - (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); - } - } else if (have_l) { - c = s->left_comp_ctx[row7] ? 3 : - (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->s.h.fixcompref); - } else { - c = 1; - } - b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]); - s->counts.comp[c][b->comp]++; - } - - // read actual references - // FIXME probably cache a few variables here to prevent repetitive - // memory accesses below - if (b->comp) /* two references */ { - int fix_idx = s->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; - - b->ref[fix_idx] = s->s.h.fixcompref; - // FIXME can this codeblob be replaced by some sort of LUT? - if (have_a) { - if (have_l) { - if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else { - c = 1 + 2 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } - } else if (s->left_intra_ctx[row7]) { - c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } else { - int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; - - if (refl == refa && refa == s->s.h.varcompref[1]) { - c = 0; - } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { - if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || - (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { - c = 4; - } else { - c = (refa == refl) ? 3 : 1; - } - } else if (!s->left_comp_ctx[row7]) { - if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { - c = 1; - } else { - c = (refl == s->s.h.varcompref[1] && - refa != s->s.h.varcompref[1]) ? 2 : 4; - } - } else if (!s->above_comp_ctx[col]) { - if (refl == s->s.h.varcompref[1] && refa != s->s.h.varcompref[1]) { - c = 1; - } else { - c = (refa == s->s.h.varcompref[1] && - refl != s->s.h.varcompref[1]) ? 2 : 4; - } - } else { - c = (refl == refa) ? 4 : 2; - } - } - } else { - if (s->above_intra_ctx[col]) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 4 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } else { - c = 3 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } - } - } else if (have_l) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 4 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } else { - c = 3 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]); - b->ref[var_idx] = s->s.h.varcompref[bit]; - s->counts.comp_ref[c][bit]++; - } else /* single reference */ { - int bit, c; - - if (have_a && !s->above_intra_ctx[col]) { - if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_comp_ctx[row7]) { - if (s->above_comp_ctx[col]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7] || - !s->above_ref_ctx[col]); - } else { - c = (3 * !s->above_ref_ctx[col]) + - (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); - } - } else if (s->above_comp_ctx[col]) { - c = (3 * !s->left_ref_ctx[row7]) + - (!s->s.h.fixcompref || !s->above_ref_ctx[col]); - } else { - c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; - } - } else if (s->above_intra_ctx[col]) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 1 + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); - } else { - c = 4 * (!s->above_ref_ctx[col]); - } - } else if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); - } else { - c = 4 * (!s->left_ref_ctx[row7]); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]); - s->counts.single_ref[c][0][bit]++; - if (!bit) { - b->ref[0] = 0; - } else { - // FIXME can this codeblob be replaced by some sort of LUT? - if (have_a) { - if (have_l) { - if (s->left_intra_ctx[row7]) { - if (s->above_intra_ctx[col]) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->above_ref_ctx[col] == 1); - } else if (!s->above_ref_ctx[col]) { - c = 3; - } else { - c = 4 * (s->above_ref_ctx[col] == 1); - } - } else if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else if (!s->left_ref_ctx[row7]) { - c = 3; - } else { - c = 4 * (s->left_ref_ctx[row7] == 1); - } - } else if (s->above_comp_ctx[col]) { - if (s->left_comp_ctx[row7]) { - if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) { - c = 3 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else { - c = 2; - } - } else if (!s->left_ref_ctx[row7]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->above_ref_ctx[col] == 1); - } else { - c = 3 * (s->left_ref_ctx[row7] == 1) + - (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); - } - } else if (s->left_comp_ctx[row7]) { - if (!s->above_ref_ctx[col]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else { - c = 3 * (s->above_ref_ctx[col] == 1) + - (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); - } - } else if (!s->above_ref_ctx[col]) { - if (!s->left_ref_ctx[row7]) { - c = 3; - } else { - c = 4 * (s->left_ref_ctx[row7] == 1); - } - } else if (!s->left_ref_ctx[row7]) { - c = 4 * (s->above_ref_ctx[col] == 1); - } else { - c = 2 * (s->left_ref_ctx[row7] == 1) + - 2 * (s->above_ref_ctx[col] == 1); - } - } else { - if (s->above_intra_ctx[col] || - (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) { - c = 2; - } else if (s->above_comp_ctx[col]) { - c = 3 * (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); - } else { - c = 4 * (s->above_ref_ctx[col] == 1); - } - } - } else if (have_l) { - if (s->left_intra_ctx[row7] || - (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) { - c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 3 * (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); - } else { - c = 4 * (s->left_ref_ctx[row7] == 1); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]); - s->counts.single_ref[c][1][bit]++; - b->ref[0] = 1 + bit; - } - } - } - - if (b->bs <= BS_8x8) { - if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled) { - b->mode[0] = b->mode[1] = b->mode[2] = b->mode[3] = ZEROMV; - } else { - static const uint8_t off[10] = { - 3, 0, 0, 1, 0, 0, 0, 0, 0, 0 - }; - - // FIXME this needs to use the LUT tables from find_ref_mvs - // because not all are -1,0/0,-1 - int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]] - [s->left_mode_ctx[row7 + off[b->bs]]]; - - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.mv_mode[c][b->mode[0] - 10]++; - } - } - - if (s->s.h.filtermode == FILTER_SWITCHABLE) { - int c; - - if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { - if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ? - s->left_filter_ctx[row7] : 3; - } else { - c = s->above_filter_ctx[col]; - } - } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->left_filter_ctx[row7]; - } else { - c = 3; - } - - filter_id = vp8_rac_get_tree(&s->c, vp9_filter_tree, - s->prob.p.filter[c]); - s->counts.filter[c][filter_id]++; - b->filter = vp9_filter_lut[filter_id]; - } else { - b->filter = s->s.h.filtermode; - } - - if (b->bs > BS_8x8) { - int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]]; - - b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[0] - 10]++; - fill_mv(s, b->mv[0], b->mode[0], 0); - - if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[1] - 10]++; - fill_mv(s, b->mv[1], b->mode[1], 1); - } else { - b->mode[1] = b->mode[0]; - AV_COPY32(&b->mv[1][0], &b->mv[0][0]); - AV_COPY32(&b->mv[1][1], &b->mv[0][1]); - } - - if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[2] - 10]++; - fill_mv(s, b->mv[2], b->mode[2], 2); - - if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree, - s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[3] - 10]++; - fill_mv(s, b->mv[3], b->mode[3], 3); - } else { - b->mode[3] = b->mode[2]; - AV_COPY32(&b->mv[3][0], &b->mv[2][0]); - AV_COPY32(&b->mv[3][1], &b->mv[2][1]); - } - } else { - b->mode[2] = b->mode[0]; - AV_COPY32(&b->mv[2][0], &b->mv[0][0]); - AV_COPY32(&b->mv[2][1], &b->mv[0][1]); - b->mode[3] = b->mode[1]; - AV_COPY32(&b->mv[3][0], &b->mv[1][0]); - AV_COPY32(&b->mv[3][1], &b->mv[1][1]); - } - } else { - fill_mv(s, b->mv[0], b->mode[0], -1); - AV_COPY32(&b->mv[1][0], &b->mv[0][0]); - AV_COPY32(&b->mv[2][0], &b->mv[0][0]); - AV_COPY32(&b->mv[3][0], &b->mv[0][0]); - AV_COPY32(&b->mv[1][1], &b->mv[0][1]); - AV_COPY32(&b->mv[2][1], &b->mv[0][1]); - AV_COPY32(&b->mv[3][1], &b->mv[0][1]); - } - - vref = b->ref[b->comp ? s->s.h.signbias[s->s.h.varcompref[0]] : 0]; - } - -#if HAVE_FAST_64BIT -#define SPLAT_CTX(var, val, n) \ - switch (n) { \ - case 1: var = val; break; \ - case 2: AV_WN16A(&var, val * 0x0101); break; \ - case 4: AV_WN32A(&var, val * 0x01010101); break; \ - case 8: AV_WN64A(&var, val * 0x0101010101010101ULL); break; \ - case 16: { \ - uint64_t v64 = val * 0x0101010101010101ULL; \ - AV_WN64A( &var, v64); \ - AV_WN64A(&((uint8_t *) &var)[8], v64); \ - break; \ - } \ - } -#else -#define SPLAT_CTX(var, val, n) \ - switch (n) { \ - case 1: var = val; break; \ - case 2: AV_WN16A(&var, val * 0x0101); break; \ - case 4: AV_WN32A(&var, val * 0x01010101); break; \ - case 8: { \ - uint32_t v32 = val * 0x01010101; \ - AV_WN32A( &var, v32); \ - AV_WN32A(&((uint8_t *) &var)[4], v32); \ - break; \ - } \ - case 16: { \ - uint32_t v32 = val * 0x01010101; \ - AV_WN32A( &var, v32); \ - AV_WN32A(&((uint8_t *) &var)[4], v32); \ - AV_WN32A(&((uint8_t *) &var)[8], v32); \ - AV_WN32A(&((uint8_t *) &var)[12], v32); \ - break; \ - } \ - } -#endif - - switch (bwh_tab[1][b->bs][0]) { -#define SET_CTXS(dir, off, n) \ - do { \ - SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \ - SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \ - SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ - if (!s->s.h.keyframe && !s->s.h.intraonly) { \ - SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \ - SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \ - SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \ - if (!b->intra) { \ - SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \ - if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ - SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \ - } \ - } \ - } \ - } while (0) - case 1: SET_CTXS(above, col, 1); break; - case 2: SET_CTXS(above, col, 2); break; - case 4: SET_CTXS(above, col, 4); break; - case 8: SET_CTXS(above, col, 8); break; - } - switch (bwh_tab[1][b->bs][1]) { - case 1: SET_CTXS(left, row7, 1); break; - case 2: SET_CTXS(left, row7, 2); break; - case 4: SET_CTXS(left, row7, 4); break; - case 8: SET_CTXS(left, row7, 8); break; - } -#undef SPLAT_CTX -#undef SET_CTXS - - if (!s->s.h.keyframe && !s->s.h.intraonly) { - if (b->bs > BS_8x8) { - int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); - - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1); - AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]); - AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]); - AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0); - AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1); - } else { - int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); - - for (n = 0; n < w4 * 2; n++) { - AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0); - AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1); - } - for (n = 0; n < h4 * 2; n++) { - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1); - } - } - } - - // FIXME kinda ugly - for (y = 0; y < h4; y++) { - int x, o = (row + y) * s->sb_cols * 8 + col; - struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o]; - - if (b->intra) { - for (x = 0; x < w4; x++) { - mv[x].ref[0] = - mv[x].ref[1] = -1; - } - } else if (b->comp) { - for (x = 0; x < w4; x++) { - mv[x].ref[0] = b->ref[0]; - mv[x].ref[1] = b->ref[1]; - AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); - AV_COPY32(&mv[x].mv[1], &b->mv[3][1]); - } - } else { - for (x = 0; x < w4; x++) { - mv[x].ref[0] = b->ref[0]; - mv[x].ref[1] = -1; - AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); - } - } - } -} - -// FIXME merge cnt/eob arguments? -static av_always_inline int -decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, - int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3], - unsigned (*eob)[6][2], uint8_t (*p)[6][11], - int nnz, const int16_t *scan, const int16_t (*nb)[2], - const int16_t *band_counts, const int16_t *qmul) -{ - int i = 0, band = 0, band_left = band_counts[band]; - uint8_t *tp = p[0][nnz]; - uint8_t cache[1024]; - - do { - int val, rc; - - val = vp56_rac_get_prob_branchy(c, tp[0]); // eob - eob[band][nnz][val]++; - if (!val) - break; - - skip_eob: - if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero - cnt[band][nnz][0]++; - if (!--band_left) - band_left = band_counts[++band]; - cache[scan[i]] = 0; - nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; - tp = p[band][nnz]; - if (++i == n_coeffs) - break; //invalid input; blocks should end with EOB - goto skip_eob; - } - - rc = scan[i]; - if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one - cnt[band][nnz][1]++; - val = 1; - cache[rc] = 1; - } else { - // fill in p[3-10] (model fill) - only once per frame for each pos - if (!tp[3]) - memcpy(&tp[3], vp9_model_pareto8[tp[2]], 8); - - cnt[band][nnz][2]++; - if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4 - if (!vp56_rac_get_prob_branchy(c, tp[4])) { - cache[rc] = val = 2; - } else { - val = 3 + vp56_rac_get_prob(c, tp[5]); - cache[rc] = 3; - } - } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2 - cache[rc] = 4; - if (!vp56_rac_get_prob_branchy(c, tp[7])) { - val = 5 + vp56_rac_get_prob(c, 159); - } else { - val = 7 + (vp56_rac_get_prob(c, 165) << 1); - val += vp56_rac_get_prob(c, 145); - } - } else { // cat 3-6 - cache[rc] = 5; - if (!vp56_rac_get_prob_branchy(c, tp[8])) { - if (!vp56_rac_get_prob_branchy(c, tp[9])) { - val = 11 + (vp56_rac_get_prob(c, 173) << 2); - val += (vp56_rac_get_prob(c, 148) << 1); - val += vp56_rac_get_prob(c, 140); - } else { - val = 19 + (vp56_rac_get_prob(c, 176) << 3); - val += (vp56_rac_get_prob(c, 155) << 2); - val += (vp56_rac_get_prob(c, 140) << 1); - val += vp56_rac_get_prob(c, 135); - } - } else if (!vp56_rac_get_prob_branchy(c, tp[10])) { - val = 35 + (vp56_rac_get_prob(c, 180) << 4); - val += (vp56_rac_get_prob(c, 157) << 3); - val += (vp56_rac_get_prob(c, 141) << 2); - val += (vp56_rac_get_prob(c, 134) << 1); - val += vp56_rac_get_prob(c, 130); - } else { - val = 67; - if (!is8bitsperpixel) { - if (bpp == 12) { - val += vp56_rac_get_prob(c, 255) << 17; - val += vp56_rac_get_prob(c, 255) << 16; - } - val += (vp56_rac_get_prob(c, 255) << 15); - val += (vp56_rac_get_prob(c, 255) << 14); - } - val += (vp56_rac_get_prob(c, 254) << 13); - val += (vp56_rac_get_prob(c, 254) << 12); - val += (vp56_rac_get_prob(c, 254) << 11); - val += (vp56_rac_get_prob(c, 252) << 10); - val += (vp56_rac_get_prob(c, 249) << 9); - val += (vp56_rac_get_prob(c, 243) << 8); - val += (vp56_rac_get_prob(c, 230) << 7); - val += (vp56_rac_get_prob(c, 196) << 6); - val += (vp56_rac_get_prob(c, 177) << 5); - val += (vp56_rac_get_prob(c, 153) << 4); - val += (vp56_rac_get_prob(c, 140) << 3); - val += (vp56_rac_get_prob(c, 133) << 2); - val += (vp56_rac_get_prob(c, 130) << 1); - val += vp56_rac_get_prob(c, 129); - } - } - } -#define STORE_COEF(c, i, v) do { \ - if (is8bitsperpixel) { \ - c[i] = v; \ - } else { \ - AV_WN32A(&c[i * 2], v); \ - } \ -} while (0) - if (!--band_left) - band_left = band_counts[++band]; - if (is_tx32x32) - STORE_COEF(coef, rc, ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2); - else - STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * qmul[!!i]); - nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; - tp = p[band][nnz]; - } while (++i < n_coeffs); - - return i; -} - -static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->bpp, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, - unsigned (*cnt)[6][3], unsigned (*eob)[6][2], - uint8_t (*p)[6][11], int nnz, const int16_t *scan, - const int16_t (*nb)[2], const int16_t *band_counts, - const int16_t *qmul) -{ - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->bpp, cnt, eob, p, - nnz, scan, nb, band_counts, qmul); -} - -static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpixel) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra]; - int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1; - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int n, pl, x, y, res; - int16_t (*qmul)[2] = s->s.h.segmentation.feat[b->seg_id].qmul; - int tx = 4 * s->s.h.lossless + b->tx; - const int16_t * const *yscans = vp9_scans[tx]; - const int16_t (* const *ynbs)[2] = vp9_scans_nb[tx]; - const int16_t *uvscan = vp9_scans[b->uvtx][DCT_DCT]; - const int16_t (*uvnb)[2] = vp9_scans_nb[b->uvtx][DCT_DCT]; - uint8_t *a = &s->above_y_nnz_ctx[col * 2]; - uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1]; - static const int16_t band_counts[4][8] = { - { 1, 2, 3, 4, 3, 16 - 13 }, - { 1, 2, 3, 4, 11, 64 - 21 }, - { 1, 2, 3, 4, 11, 256 - 21 }, - { 1, 2, 3, 4, 11, 1024 - 21 }, - }; - const int16_t *y_band_counts = band_counts[b->tx]; - const int16_t *uv_band_counts = band_counts[b->uvtx]; - int bytesperpixel = is8bitsperpixel ? 1 : 2; - int total_coeff = 0; - -#define MERGE(la, end, step, rd) \ - for (n = 0; n < end; n += step) \ - la[n] = !!rd(&la[n]) -#define MERGE_CTX(step, rd) \ - do { \ - MERGE(l, end_y, step, rd); \ - MERGE(a, end_x, step, rd); \ - } while (0) - -#define DECODE_Y_COEF_LOOP(step, mode_index, v) \ - for (n = 0, y = 0; y < end_y; y += step) { \ - for (x = 0; x < end_x; x += step, n += step * step) { \ - enum TxfmType txtp = vp9_intra_txfm_type[b->mode[mode_index]]; \ - res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \ - c, e, p, a[x] + l[y], yscans[txtp], \ - ynbs[txtp], y_band_counts, qmul[0]); \ - a[x] = l[y] = !!res; \ - total_coeff |= !!res; \ - if (step >= 4) { \ - AV_WN16A(&s->eob[n], res); \ - } else { \ - s->eob[n] = res; \ - } \ - } \ - } - -#define SPLAT(la, end, step, cond) \ - if (step == 2) { \ - for (n = 1; n < end; n += step) \ - la[n] = la[n - 1]; \ - } else if (step == 4) { \ - if (cond) { \ - for (n = 0; n < end; n += step) \ - AV_WN32A(&la[n], la[n] * 0x01010101); \ - } else { \ - for (n = 0; n < end; n += step) \ - memset(&la[n + 1], la[n], FFMIN(end - n - 1, 3)); \ - } \ - } else /* step == 8 */ { \ - if (cond) { \ - if (HAVE_FAST_64BIT) { \ - for (n = 0; n < end; n += step) \ - AV_WN64A(&la[n], la[n] * 0x0101010101010101ULL); \ - } else { \ - for (n = 0; n < end; n += step) { \ - uint32_t v32 = la[n] * 0x01010101; \ - AV_WN32A(&la[n], v32); \ - AV_WN32A(&la[n + 4], v32); \ - } \ - } \ - } else { \ - for (n = 0; n < end; n += step) \ - memset(&la[n + 1], la[n], FFMIN(end - n - 1, 7)); \ - } \ - } -#define SPLAT_CTX(step) \ - do { \ - SPLAT(a, end_x, step, end_x == w4); \ - SPLAT(l, end_y, step, end_y == h4); \ - } while (0) - - /* y tokens */ - switch (b->tx) { - case TX_4X4: - DECODE_Y_COEF_LOOP(1, b->bs > BS_8x8 ? n : 0,); - break; - case TX_8X8: - MERGE_CTX(2, AV_RN16A); - DECODE_Y_COEF_LOOP(2, 0,); - SPLAT_CTX(2); - break; - case TX_16X16: - MERGE_CTX(4, AV_RN32A); - DECODE_Y_COEF_LOOP(4, 0,); - SPLAT_CTX(4); - break; - case TX_32X32: - MERGE_CTX(8, AV_RN64A); - DECODE_Y_COEF_LOOP(8, 0, 32); - SPLAT_CTX(8); - break; - } - -#define DECODE_UV_COEF_LOOP(step, v) \ - for (n = 0, y = 0; y < end_y; y += step) { \ - for (x = 0; x < end_x; x += step, n += step * step) { \ - res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->uvblock[pl] + 16 * n * bytesperpixel, \ - 16 * step * step, c, e, p, a[x] + l[y], \ - uvscan, uvnb, uv_band_counts, qmul[1]); \ - a[x] = l[y] = !!res; \ - total_coeff |= !!res; \ - if (step >= 4) { \ - AV_WN16A(&s->uveob[pl][n], res); \ - } else { \ - s->uveob[pl][n] = res; \ - } \ - } \ - } - - p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; - c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra]; - e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra]; - w4 >>= s->ss_h; - end_x >>= s->ss_h; - h4 >>= s->ss_v; - end_y >>= s->ss_v; - for (pl = 0; pl < 2; pl++) { - a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h]; - l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; - switch (b->uvtx) { - case TX_4X4: - DECODE_UV_COEF_LOOP(1,); - break; - case TX_8X8: - MERGE_CTX(2, AV_RN16A); - DECODE_UV_COEF_LOOP(2,); - SPLAT_CTX(2); - break; - case TX_16X16: - MERGE_CTX(4, AV_RN32A); - DECODE_UV_COEF_LOOP(4,); - SPLAT_CTX(4); - break; - case TX_32X32: - MERGE_CTX(8, AV_RN64A); - DECODE_UV_COEF_LOOP(8, 32); - SPLAT_CTX(8); - break; - } - } - - return total_coeff; -} - -static int decode_coeffs_8bpp(AVCodecContext *ctx) -{ - return decode_coeffs(ctx, 1); -} - -static int decode_coeffs_16bpp(AVCodecContext *ctx) -{ - return decode_coeffs(ctx, 0); -} - -static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, - uint8_t *dst_edge, ptrdiff_t stride_edge, - uint8_t *dst_inner, ptrdiff_t stride_inner, - uint8_t *l, int col, int x, int w, - int row, int y, enum TxfmMode tx, - int p, int ss_h, int ss_v, int bytesperpixel) -{ - int have_top = row > 0 || y > 0; - int have_left = col > s->tile_col_start || x > 0; - int have_right = x < w - 1; - int bpp = s->bpp; - static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { - [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, - { DC_127_PRED, VERT_PRED } }, - [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_PRED, HOR_PRED } }, - [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, - { LEFT_DC_PRED, DC_PRED } }, - [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, - { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, - [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, - { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, - [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, - { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, - [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, - { HOR_DOWN_PRED, HOR_DOWN_PRED } }, - [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, - { DC_127_PRED, VERT_LEFT_PRED } }, - [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, - { HOR_UP_PRED, HOR_UP_PRED } }, - [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, - { HOR_PRED, TM_VP8_PRED } }, - }; - static const struct { - uint8_t needs_left:1; - uint8_t needs_top:1; - uint8_t needs_topleft:1; - uint8_t needs_topright:1; - uint8_t invert_left:1; - } edges[N_INTRA_PRED_MODES] = { - [VERT_PRED] = { .needs_top = 1 }, - [HOR_PRED] = { .needs_left = 1 }, - [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, - [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, - [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, - [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 }, - [LEFT_DC_PRED] = { .needs_left = 1 }, - [TOP_DC_PRED] = { .needs_top = 1 }, - [DC_128_PRED] = { 0 }, - [DC_127_PRED] = { 0 }, - [DC_129_PRED] = { 0 } - }; - - av_assert2(mode >= 0 && mode < 10); - mode = mode_conv[mode][have_left][have_top]; - if (edges[mode].needs_top) { - uint8_t *top, *topleft; - int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; - int n_px_need_tr = 0; - - if (tx == TX_4X4 && edges[mode].needs_topright && have_right) - n_px_need_tr = 4; - - // if top of sb64-row, use s->intra_pred_data[] instead of - // dst[-stride] for intra prediction (it contains pre- instead of - // post-loopfilter data) - if (have_top) { - top = !(row & 7) && !y ? - s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : - y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; - if (have_left) - topleft = !(row & 7) && !y ? - s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : - y == 0 || x == 0 ? &dst_edge[-stride_edge] : - &dst_inner[-stride_inner]; - } - - if (have_top && - (!edges[mode].needs_topleft || (have_left && top == topleft)) && - (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && - n_px_need + n_px_need_tr <= n_px_have) { - *a = top; - } else { - if (have_top) { - if (n_px_need <= n_px_have) { - memcpy(*a, top, n_px_need * bytesperpixel); - } else { -#define memset_bpp(c, i1, v, i2, num) do { \ - if (bytesperpixel == 1) { \ - memset(&(c)[(i1)], (v)[(i2)], (num)); \ - } else { \ - int n, val = AV_RN16A(&(v)[(i2) * 2]); \ - for (n = 0; n < (num); n++) { \ - AV_WN16A(&(c)[((i1) + n) * 2], val); \ - } \ - } \ -} while (0) - memcpy(*a, top, n_px_have * bytesperpixel); - memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have); - } - } else { -#define memset_val(c, val, num) do { \ - if (bytesperpixel == 1) { \ - memset((c), (val), (num)); \ - } else { \ - int n; \ - for (n = 0; n < (num); n++) { \ - AV_WN16A(&(c)[n * 2], (val)); \ - } \ - } \ -} while (0) - memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need); - } - if (edges[mode].needs_topleft) { - if (have_left && have_top) { -#define assign_bpp(c, i1, v, i2) do { \ - if (bytesperpixel == 1) { \ - (c)[(i1)] = (v)[(i2)]; \ - } else { \ - AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \ - } \ -} while (0) - assign_bpp(*a, -1, topleft, -1); - } else { -#define assign_val(c, i, v) do { \ - if (bytesperpixel == 1) { \ - (c)[(i)] = (v); \ - } else { \ - AV_WN16A(&(c)[(i) * 2], (v)); \ - } \ -} while (0) - assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1)); - } - } - if (tx == TX_4X4 && edges[mode].needs_topright) { - if (have_top && have_right && - n_px_need + n_px_need_tr <= n_px_have) { - memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); - } else { - memset_bpp(*a, 4, *a, 3, 4); - } - } - } - } - if (edges[mode].needs_left) { - if (have_left) { - int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; - uint8_t *dst = x == 0 ? dst_edge : dst_inner; - ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; - - if (edges[mode].invert_left) { - if (n_px_need <= n_px_have) { - for (i = 0; i < n_px_need; i++) - assign_bpp(l, i, &dst[i * stride], -1); - } else { - for (i = 0; i < n_px_have; i++) - assign_bpp(l, i, &dst[i * stride], -1); - memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have); - } - } else { - if (n_px_need <= n_px_have) { - for (i = 0; i < n_px_need; i++) - assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); - } else { - for (i = 0; i < n_px_have; i++) - assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); - memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have); - } - } - } else { - memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx); - } - } - - return mode; -} - -static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, - ptrdiff_t uv_off, int bytesperpixel) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; - int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; - LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); - LOCAL_ALIGNED_32(uint8_t, l, [64]); - - for (n = 0, y = 0; y < end_y; y += step1d) { - uint8_t *ptr = dst, *ptr_r = dst_r; - for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, - ptr_r += 4 * step1d * bytesperpixel, n += step) { - int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? - y * 2 + x : 0]; - uint8_t *a = &a_buf[32]; - enum TxfmType txtp = vp9_intra_txfm_type[mode]; - int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; - - mode = check_intra_mode(s, mode, &a, ptr_r, - s->s.frames[CUR_FRAME].tf.f->linesize[0], - ptr, s->y_stride, l, - col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); - s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); - if (eob) - s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); - } - dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; - dst += 4 * step1d * s->y_stride; - } - - // U/V - w4 >>= s->ss_h; - end_x >>= s->ss_h; - end_y >>= s->ss_v; - step = 1 << (b->uvtx * 2); - for (p = 0; p < 2; p++) { - dst = s->dst[1 + p]; - dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; - for (n = 0, y = 0; y < end_y; y += uvstep1d) { - uint8_t *ptr = dst, *ptr_r = dst_r; - for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, - ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { - int mode = b->uvmode; - uint8_t *a = &a_buf[32]; - int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; - - mode = check_intra_mode(s, mode, &a, ptr_r, - s->s.frames[CUR_FRAME].tf.f->linesize[1], - ptr, s->uv_stride, l, col, x, w4, row, y, - b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); - s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); - if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); - } - dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; - dst += 4 * uvstep1d * s->uv_stride; - } - } -} - -static void intra_recon_8bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) -{ - intra_recon(ctx, y_off, uv_off, 1); -} - -static void intra_recon_16bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) -{ - intra_recon(ctx, y_off, uv_off, 2); -} - -static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h, int bytesperpixel) -{ - int mx = mv->x, my = mv->y, th; - - y += my >> 3; - x += mx >> 3; - ref += y * ref_stride + x * bytesperpixel; - mx &= 7; - my &= 7; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + bh + 4 * !!my + 7) >> 6; - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, - 160, ref_stride, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - ref_stride = 160; - } - mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); -} - -static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h, int bytesperpixel) -{ - int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; - - y += my >> 4; - x += mx >> 4; - ref_u += y * src_stride_u + x * bytesperpixel; - ref_v += y * src_stride_v + x * bytesperpixel; - mx &= 15; - my &= 15; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - if (x < !!mx * 3 || y < !!my * 3 || - x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, - 160, src_stride_u, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); - - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, - 160, src_stride_v, - bw + !!mx * 7, bh + !!my * 7, - x - !!mx * 3, y - !!my * 3, w, h); - ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; - mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); - } else { - mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); - mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); - } -} - -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ - px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ - mv, bw, bh, w, h, bytesperpixel) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, bw, bh, w, h, bytesperpixel) -#define SCALED 0 -#define FN(x) x##_8bpp -#define BYTES_PER_PIXEL 1 -#include "vp9_mc_template.c" -#undef FN -#undef BYTES_PER_PIXEL -#define FN(x) x##_16bpp -#define BYTES_PER_PIXEL 2 -#include "vp9_mc_template.c" -#undef mc_luma_dir -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, - int px, int py, int pw, int ph, - int bw, int bh, int w, int h, int bytesperpixel, - const uint16_t *scale, const uint8_t *step) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { -#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) - int mx, my; - int refbw_m1, refbh_m1; - int th; - VP56mv mv; - - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - // BUG libvpx seems to scale the two components separately. This introduces - // rounding errors but we have to reproduce them to be exactly compatible - // with the output from libvpx... - mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); - my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); - - y = my >> 4; - x = mx >> 4; - ref += y * ref_stride + x * bytesperpixel; - mx &= 15; - my &= 15; - refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; - refbh_m1 = ((bh - 1) * step[1] + my) >> 4; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + refbh_m1 + 4 + 7) >> 6; - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref - 3 * ref_stride - 3 * bytesperpixel, - 288, ref_stride, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - ref_stride = 288; - } - smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); - } -} - -static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, - int px, int py, int pw, int ph, - int bw, int bh, int w, int h, int bytesperpixel, - const uint16_t *scale, const uint8_t *step) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, - ref_v, src_stride_v, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { - int mx, my; - int refbw_m1, refbh_m1; - int th; - VP56mv mv; - - if (s->ss_h) { - // BUG https://code.google.com/p/webm/issues/detail?id=820 - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); - mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); - } else { - mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); - mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); - } - if (s->ss_v) { - // BUG https://code.google.com/p/webm/issues/detail?id=820 - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); - my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); - } else { - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); - } -#undef scale_mv - y = my >> 4; - x = mx >> 4; - ref_u += y * src_stride_u + x * bytesperpixel; - ref_v += y * src_stride_v + x * bytesperpixel; - mx &= 15; - my &= 15; - refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; - refbh_m1 = ((bh - 1) * step[1] + my) >> 4; - // FIXME bilinear filter only needs 0/1 pixels, not 3/4 - // we use +7 because the last 7 pixels of each sbrow can be changed in - // the longest loopfilter of the next sbrow - th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); - ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); - if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_u - 3 * src_stride_u - 3 * bytesperpixel, - 288, src_stride_u, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); - - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, - ref_v - 3 * src_stride_v - 3 * bytesperpixel, - 288, src_stride_v, - refbw_m1 + 8, refbh_m1 + 8, - x - 3, y - 3, w, h); - ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; - smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); - } else { - smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); - smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); - } - } -} - -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ - px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ - mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ - s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ - row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ - s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define SCALED 1 -#define FN(x) x##_scaled_8bpp -#define BYTES_PER_PIXEL 1 -#include "vp9_mc_template.c" -#undef FN -#undef BYTES_PER_PIXEL -#define FN(x) x##_scaled_16bpp -#define BYTES_PER_PIXEL 2 -#include "vp9_mc_template.c" -#undef mc_luma_dir -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; - - if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { - if (bytesperpixel == 1) { - inter_pred_scaled_8bpp(ctx); - } else { - inter_pred_scaled_16bpp(ctx); - } - } else { - if (bytesperpixel == 1) { - inter_pred_8bpp(ctx); - } else { - inter_pred_16bpp(ctx); - } - } - if (!b->skip) { - /* mostly copied intra_recon() */ - - int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; - int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); - int end_x = FFMIN(2 * (s->cols - col), w4); - int end_y = FFMIN(2 * (s->rows - row), h4); - int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0]; - - // y itxfm add - for (n = 0, y = 0; y < end_y; y += step1d) { - uint8_t *ptr = dst; - for (x = 0; x < end_x; x += step1d, - ptr += 4 * step1d * bytesperpixel, n += step) { - int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; - - if (eob) - s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); - } - dst += 4 * s->y_stride * step1d; - } - - // uv itxfm add - end_x >>= s->ss_h; - end_y >>= s->ss_v; - step = 1 << (b->uvtx * 2); - for (p = 0; p < 2; p++) { - dst = s->dst[p + 1]; - for (n = 0, y = 0; y < end_y; y += uvstep1d) { - uint8_t *ptr = dst; - for (x = 0; x < end_x; x += uvstep1d, - ptr += 4 * uvstep1d * bytesperpixel, n += step) { - int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; - - if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); - } - dst += 4 * uvstep1d * s->uv_stride; - } - } - } -} - -static void inter_recon_8bpp(AVCodecContext *ctx) -{ - inter_recon(ctx, 1); -} - -static void inter_recon_16bpp(AVCodecContext *ctx) -{ - inter_recon(ctx, 2); -} - -static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, - int row_and_7, int col_and_7, - int w, int h, int col_end, int row_end, - enum TxfmMode tx, int skip_inter) -{ - static const unsigned wide_filter_col_mask[2] = { 0x11, 0x01 }; - static const unsigned wide_filter_row_mask[2] = { 0x03, 0x07 }; - - // FIXME I'm pretty sure all loops can be replaced by a single LUT if - // we make VP9Filter.mask uint64_t (i.e. row/col all single variable) - // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then - // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7) - - // the intended behaviour of the vp9 loopfilter is to work on 8-pixel - // edges. This means that for UV, we work on two subsampled blocks at - // a time, and we only use the topleft block's mode information to set - // things like block strength. Thus, for any block size smaller than - // 16x16, ignore the odd portion of the block. - if (tx == TX_4X4 && (ss_v | ss_h)) { - if (h == ss_v) { - if (row_and_7 & 1) - return; - if (!row_end) - h += 1; - } - if (w == ss_h) { - if (col_and_7 & 1) - return; - if (!col_end) - w += 1; - } - } - - if (tx == TX_4X4 && !skip_inter) { - int t = 1 << col_and_7, m_col = (t << w) - t, y; - // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide - int m_row_8 = m_col & wide_filter_col_mask[ss_h], m_row_4 = m_col - m_row_8; - - for (y = row_and_7; y < h + row_and_7; y++) { - int col_mask_id = 2 - !(y & wide_filter_row_mask[ss_v]); - - mask[0][y][1] |= m_row_8; - mask[0][y][2] |= m_row_4; - // for odd lines, if the odd col is not being filtered, - // skip odd row also: - // .---. <-- a - // | | - // |___| <-- b - // ^ ^ - // c d - // - // if a/c are even row/col and b/d are odd, and d is skipped, - // e.g. right edge of size-66x66.webm, then skip b also (bug) - if ((ss_h & ss_v) && (col_end & 1) && (y & 1)) { - mask[1][y][col_mask_id] |= (t << (w - 1)) - t; - } else { - mask[1][y][col_mask_id] |= m_col; - } - if (!ss_h) - mask[0][y][3] |= m_col; - if (!ss_v) { - if (ss_h && (col_end & 1)) - mask[1][y][3] |= (t << (w - 1)) - t; - else - mask[1][y][3] |= m_col; - } - } - } else { - int y, t = 1 << col_and_7, m_col = (t << w) - t; - - if (!skip_inter) { - int mask_id = (tx == TX_8X8); - static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; - int l2 = tx + ss_h - 1, step1d; - int m_row = m_col & masks[l2]; - - // at odd UV col/row edges tx16/tx32 loopfilter edges, force - // 8wd loopfilter to prevent going off the visible edge. - if (ss_h && tx > TX_8X8 && (w ^ (w - 1)) == 1) { - int m_row_16 = ((t << (w - 1)) - t) & masks[l2]; - int m_row_8 = m_row - m_row_16; - - for (y = row_and_7; y < h + row_and_7; y++) { - mask[0][y][0] |= m_row_16; - mask[0][y][1] |= m_row_8; - } - } else { - for (y = row_and_7; y < h + row_and_7; y++) - mask[0][y][mask_id] |= m_row; - } - - l2 = tx + ss_v - 1; - step1d = 1 << l2; - if (ss_v && tx > TX_8X8 && (h ^ (h - 1)) == 1) { - for (y = row_and_7; y < h + row_and_7 - 1; y += step1d) - mask[1][y][0] |= m_col; - if (y - row_and_7 == h - 1) - mask[1][y][1] |= m_col; - } else { - for (y = row_and_7; y < h + row_and_7; y += step1d) - mask[1][y][mask_id] |= m_col; - } - } else if (tx != TX_4X4) { - int mask_id; - - mask_id = (tx == TX_8X8) || (h == ss_v); - mask[1][row_and_7][mask_id] |= m_col; - mask_id = (tx == TX_8X8) || (w == ss_h); - for (y = row_and_7; y < h + row_and_7; y++) - mask[0][y][mask_id] |= t; - } else { - int t8 = t & wide_filter_col_mask[ss_h], t4 = t - t8; - - for (y = row_and_7; y < h + row_and_7; y++) { - mask[0][y][2] |= t4; - mask[0][y][1] |= t8; - } - mask[1][row_and_7][2 - !(row_and_7 & wide_filter_row_mask[ss_v])] |= m_col; - } - } -} - -static void decode_b(AVCodecContext *ctx, int row, int col, - struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, - enum BlockLevel bl, enum BlockPartition bp) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - enum BlockSize bs = bl * 3 + bp; - int bytesperpixel = s->bytesperpixel; - int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl; - int emu[2]; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - - s->row = row; - s->row7 = row & 7; - s->col = col; - s->col7 = col & 7; - s->min_mv.x = -(128 + col * 64); - s->min_mv.y = -(128 + row * 64); - s->max_mv.x = 128 + (s->cols - col - w4) * 64; - s->max_mv.y = 128 + (s->rows - row - h4) * 64; - if (s->pass < 2) { - b->bs = bs; - b->bl = bl; - b->bp = bp; - decode_mode(ctx); - b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || - (s->ss_v && h4 * 2 == (1 << b->tx))); - - if (!b->skip) { - int has_coeffs; - - if (bytesperpixel == 1) { - has_coeffs = decode_coeffs_8bpp(ctx); - } else { - has_coeffs = decode_coeffs_16bpp(ctx); - } - if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { - b->skip = 1; - memset(&s->above_skip_ctx[col], 1, w4); - memset(&s->left_skip_ctx[s->row7], 1, h4); - } - } else { - int row7 = s->row7; - -#define SPLAT_ZERO_CTX(v, n) \ - switch (n) { \ - case 1: v = 0; break; \ - case 2: AV_ZERO16(&v); break; \ - case 4: AV_ZERO32(&v); break; \ - case 8: AV_ZERO64(&v); break; \ - case 16: AV_ZERO128(&v); break; \ - } -#define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \ - do { \ - SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \ - if (s->ss_##dir2) { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \ - } else { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \ - } \ - } while (0) - - switch (w4) { - case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break; - case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break; - case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break; - case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break; - } - switch (h4) { - case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break; - case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break; - case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break; - case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break; - } - } - - if (s->pass == 1) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); - - return; - } - } - - // emulated overhangs if the stride of the target buffer can't hold. This - // makes it possible to support emu-edge and so on even if we have large block - // overhangs - emu[0] = (col + w4) * 8 * bytesperpixel > f->linesize[0] || - (row + h4) > s->rows; - emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || - (row + h4) > s->rows; - if (emu[0]) { - s->dst[0] = s->tmp_y; - s->y_stride = 128; - } else { - s->dst[0] = f->data[0] + yoff; - s->y_stride = f->linesize[0]; - } - if (emu[1]) { - s->dst[1] = s->tmp_uv[0]; - s->dst[2] = s->tmp_uv[1]; - s->uv_stride = 128; - } else { - s->dst[1] = f->data[1] + uvoff; - s->dst[2] = f->data[2] + uvoff; - s->uv_stride = f->linesize[1]; - } - if (b->intra) { - if (s->bpp > 8) { - intra_recon_16bpp(ctx, yoff, uvoff); - } else { - intra_recon_8bpp(ctx, yoff, uvoff); - } - } else { - if (s->bpp > 8) { - inter_recon_16bpp(ctx); - } else { - inter_recon_8bpp(ctx); - } - } - if (emu[0]) { - int w = FFMIN(s->cols - col, w4) * 8, h = FFMIN(s->rows - row, h4) * 8, n, o = 0; - - for (n = 0; o < w; n++) { - int bw = 64 >> n; - - av_assert2(n <= 4); - if (w & bw) { - s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o * bytesperpixel, f->linesize[0], - s->tmp_y + o * bytesperpixel, 128, h, 0, 0); - o += bw; - } - } - } - if (emu[1]) { - int w = FFMIN(s->cols - col, w4) * 8 >> s->ss_h; - int h = FFMIN(s->rows - row, h4) * 8 >> s->ss_v, n, o = 0; - - for (n = s->ss_h; o < w; n++) { - int bw = 64 >> n; - - av_assert2(n <= 4); - if (w & bw) { - s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o * bytesperpixel, f->linesize[1], - s->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); - s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], - s->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); - o += bw; - } - } - } - - // pick filter level and find edges to apply filter to - if (s->s.h.filter.level && - (lvl = s->s.h.segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1] - [b->mode[3] != ZEROMV]) > 0) { - int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4); - int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7; - - setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl); - mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter); - if (s->ss_h || s->ss_v) - mask_edges(lflvl->mask[1], s->ss_h, s->ss_v, row7, col7, x_end, y_end, - s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0, - s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0, - b->uvtx, skip_inter); - - if (!s->filter_lut.lim_lut[lvl]) { - int sharp = s->s.h.filter.sharpness; - int limit = lvl; - - if (sharp > 0) { - limit >>= (sharp + 3) >> 2; - limit = FFMIN(limit, 9 - sharp); - } - limit = FFMAX(limit, 1); - - s->filter_lut.lim_lut[lvl] = limit; - s->filter_lut.mblim_lut[lvl] = 2 * (lvl + 2) + limit; - } - } - - if (s->pass == 2) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); - } -} - -static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, - ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) -{ - VP9Context *s = ctx->priv_data; - int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | - (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); - const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? vp9_default_kf_partition_probs[bl][c] : - s->prob.p.partition[bl][c]; - enum BlockPartition bp; - ptrdiff_t hbs = 4 >> bl; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; - int bytesperpixel = s->bytesperpixel; - - if (bl == BL_8X8) { - bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p); - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - } else if (col + hbs < s->cols) { // FIXME why not <=? - if (row + hbs < s->rows) { // FIXME why not <=? - bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p); - switch (bp) { - case PARTITION_NONE: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - break; - case PARTITION_H: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); - break; - case PARTITION_V: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - yoff += hbs * 8 * bytesperpixel; - uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); - break; - case PARTITION_SPLIT: - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row + hbs, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - break; - default: - av_assert0(0); - } - } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) { - bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - } else { - bp = PARTITION_H; - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - } - } else if (row + hbs < s->rows) { // FIXME why not <=? - if (vp56_rac_get_prob_branchy(&s->c, p[2])) { - bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - } else { - bp = PARTITION_V; - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); - } - } else { - bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - } - s->counts.partition[bl][c][bp]++; -} - -static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, - ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) -{ - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - ptrdiff_t hbs = 4 >> bl; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; - int bytesperpixel = s->bytesperpixel; - - if (bl == BL_8X8) { - av_assert2(b->bl == BL_8X8); - decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); - } else if (s->b->bl == bl) { - decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); - if (b->bp == PARTITION_H && row + hbs < s->rows) { - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); - } else if (b->bp == PARTITION_V && col + hbs < s->cols) { - yoff += hbs * 8 * bytesperpixel; - uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); - } - } else { - decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - if (col + hbs < s->cols) { // FIXME why not <=? - if (row + hbs < s->rows) { - decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb_mem(ctx, row + hbs, col + hbs, lflvl, - yoff + 8 * hbs * bytesperpixel, - uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); - } else { - yoff += hbs * 8 * bytesperpixel; - uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); - } - } else if (row + hbs < s->rows) { - yoff += hbs * 8 * y_stride; - uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + vp9_report_tile_progress(s, row >> 3, 1); } } + return 0; } -static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v, - uint8_t *lvl, uint8_t (*mask)[4], - uint8_t *dst, ptrdiff_t ls) +static av_always_inline +int loopfilter_proc(AVCodecContext *avctx) { - int y, x, bytesperpixel = s->bytesperpixel; - - // filter edges between columns (e.g. block1 | block2) - for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) { - uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v]; - unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3]; - unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3]; - unsigned hm = hm1 | hm2 | hm13 | hm23; - - for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) { - if (col || x > 1) { - if (hm1 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hmask1[0] & x) { - if (hmask2[0] & x) { - av_assert2(l[8 << ss_v] == L); - s->dsp.loop_filter_16[0](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H); - } - } else if (hm2 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[!!(hmask1[1] & x)] - [!!(hmask2[1] & x)] - [0](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[!!(hmask1[1] & x)] - [0](ptr, ls, E, I, H); - } - } else if (hm2 & x) { - int L = l[8 << ss_v], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[!!(hmask2[1] & x)] - [0](ptr + 8 * ls, ls, E, I, H); - } - } - if (ss_h) { - if (x & 0xAA) - l += 2; - } else { - if (hm13 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hm23 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H); - } else { - s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H); - } - } else if (hm23 & x) { - int L = l[8 << ss_v], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H); - } - l++; - } - } - } -} + VP9Context *s = avctx->priv_data; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + VP9Filter *lflvl_ptr; + int bytesperpixel = s->bytesperpixel, col, i; + AVFrame *f; -static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v, - uint8_t *lvl, uint8_t (*mask)[4], - uint8_t *dst, ptrdiff_t ls) -{ - int y, x, bytesperpixel = s->bytesperpixel; - - // block1 - // filter edges between rows (e.g. ------) - // block2 - for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) { - uint8_t *ptr = dst, *l = lvl, *vmask = mask[y]; - unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3]; - - for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) { - if (row || y) { - if (vm & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (vmask[0] & x) { - if (vmask[0] & (x << (1 + ss_h))) { - av_assert2(l[1 + ss_h] == L); - s->dsp.loop_filter_16[1](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H); - } - } else if (vm & (x << (1 + ss_h))) { - L = l[1 + ss_h]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[!!(vmask[1] & x)] - [!!(vmask[1] & (x << (1 + ss_h)))] - [1](ptr, ls, E, I, H); - } else { - s->dsp.loop_filter_8[!!(vmask[1] & x)] - [1](ptr, ls, E, I, H); - } - } else if (vm & (x << (1 + ss_h))) { - int L = l[1 + ss_h], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; - s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))] - [1](ptr + 8 * bytesperpixel, ls, E, I, H); - } - } - if (!ss_v) { - if (vm3 & x) { - int L = *l, H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (vm3 & (x << (1 + ss_h))) { - L = l[1 + ss_h]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.lim_lut[L] << 8; - s->dsp.loop_filter_mix2[0][0][1](ptr + ls * 4, ls, E, I, H); - } else { - s->dsp.loop_filter_8[0][1](ptr + ls * 4, ls, E, I, H); - } - } else if (vm3 & (x << (1 + ss_h))) { - int L = l[1 + ss_h], H = L >> 4; - int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + for (i = 0; i < s->sb_rows; i++) { + vp9_await_tile_progress(s, i, s->s.h.tiling.tile_cols); - s->dsp.loop_filter_8[0][1](ptr + ls * 4 + 8 * bytesperpixel, ls, E, I, H); - } + if (s->s.h.filter.level) { + yoff = (ls_y * 64)*i; + uvoff = (ls_uv * 64 >> s->ss_v)*i; + lflvl_ptr = s->lflvl+s->sb_cols*i; + for (col = 0; col < s->cols; + col += 8, yoff += 64 * bytesperpixel, + uvoff += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, i << 3, col, + yoff, uvoff); } } - if (ss_v) { - if (y & 1) - lvl += 16; - } else { - lvl += 8; - } - } -} - -static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl, - int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) -{ - VP9Context *s = ctx->priv_data; - AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - uint8_t *dst = f->data[0] + yoff; - ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1]; - uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v]; - int p; - - // FIXME in how far can we interleave the v/h loopfilter calls? E.g. - // if you think of them as acting on a 8x8 block max, we can interleave - // each v/h within the single x loop, but that only works if we work on - // 8 pixel blocks, and we won't always do that (we want at least 16px - // to use SSE2 optimizations, perhaps 32 for AVX2) - - filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y); - filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y); - - for (p = 0; p < 2; p++) { - dst = f->data[1 + p] + uvoff; - filter_plane_cols(s, col, s->ss_h, s->ss_v, lflvl->level, uv_masks[0], dst, ls_uv); - filter_plane_rows(s, row, s->ss_h, s->ss_v, lflvl->level, uv_masks[1], dst, ls_uv); - } -} - -static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) -{ - int sb_start = ( idx * n) >> log2_n; - int sb_end = ((idx + 1) * n) >> log2_n; - *start = FFMIN(sb_start, n) << 3; - *end = FFMIN(sb_end, n) << 3; -} - -static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1, - int max_count, int update_factor) -{ - unsigned ct = ct0 + ct1, p2, p1; - - if (!ct) - return; - - update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count); - p1 = *p; - p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct; - p2 = av_clip(p2, 1, 255); - - // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8 - *p = p1 + (((p2 - p1) * update_factor + 128) >> 8); -} - -static void adapt_probs(VP9Context *s) -{ - int i, j, k, l, m; - prob_context *p = &s->prob_ctx[s->s.h.framectxid].p; - int uf = (s->s.h.keyframe || s->s.h.intraonly || !s->last_keyframe) ? 112 : 128; - - // coefficients - for (i = 0; i < 4; i++) - for (j = 0; j < 2; j++) - for (k = 0; k < 2; k++) - for (l = 0; l < 6; l++) - for (m = 0; m < 6; m++) { - uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m]; - unsigned *e = s->counts.eob[i][j][k][l][m]; - unsigned *c = s->counts.coef[i][j][k][l][m]; - - if (l == 0 && m >= 3) // dc only has 3 pt - break; - - adapt_prob(&pp[0], e[0], e[1], 24, uf); - adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf); - adapt_prob(&pp[2], c[1], c[2], 24, uf); - } - - if (s->s.h.keyframe || s->s.h.intraonly) { - memcpy(p->skip, s->prob.p.skip, sizeof(p->skip)); - memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p)); - memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p)); - memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p)); - return; - } - - // skip flag - for (i = 0; i < 3; i++) - adapt_prob(&p->skip[i], s->counts.skip[i][0], s->counts.skip[i][1], 20, 128); - - // intra/inter flag - for (i = 0; i < 4; i++) - adapt_prob(&p->intra[i], s->counts.intra[i][0], s->counts.intra[i][1], 20, 128); - - // comppred flag - if (s->s.h.comppredmode == PRED_SWITCHABLE) { - for (i = 0; i < 5; i++) - adapt_prob(&p->comp[i], s->counts.comp[i][0], s->counts.comp[i][1], 20, 128); - } - - // reference frames - if (s->s.h.comppredmode != PRED_SINGLEREF) { - for (i = 0; i < 5; i++) - adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], - s->counts.comp_ref[i][1], 20, 128); - } - - if (s->s.h.comppredmode != PRED_COMPREF) { - for (i = 0; i < 5; i++) { - uint8_t *pp = p->single_ref[i]; - unsigned (*c)[2] = s->counts.single_ref[i]; - - adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); - adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); - } - } - - // block partitioning - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) { - uint8_t *pp = p->partition[i][j]; - unsigned *c = s->counts.partition[i][j]; - - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - } - - // tx size - if (s->s.h.txfmmode == TX_SWITCHABLE) { - for (i = 0; i < 2; i++) { - unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; - - adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], s->counts.tx8p[i][1], 20, 128); - adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); - adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); - adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); - adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128); - adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128); - } - } - - // interpolation filter - if (s->s.h.filtermode == FILTER_SWITCHABLE) { - for (i = 0; i < 4; i++) { - uint8_t *pp = p->filter[i]; - unsigned *c = s->counts.filter[i]; - - adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); - adapt_prob(&pp[1], c[1], c[2], 20, 128); - } - } - - // inter modes - for (i = 0; i < 7; i++) { - uint8_t *pp = p->mv_mode[i]; - unsigned *c = s->counts.mv_mode[i]; - - adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128); - adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128); - adapt_prob(&pp[2], c[1], c[3], 20, 128); - } - - // mv joints - { - uint8_t *pp = p->mv_joint; - unsigned *c = s->counts.mv_joint; - - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - } - - // mv components - for (i = 0; i < 2; i++) { - uint8_t *pp; - unsigned *c, (*c2)[2], sum; - - adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0], - s->counts.mv_comp[i].sign[1], 20, 128); - - pp = p->mv_comp[i].classes; - c = s->counts.mv_comp[i].classes; - sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10]; - adapt_prob(&pp[0], c[0], sum, 20, 128); - sum -= c[1]; - adapt_prob(&pp[1], c[1], sum, 20, 128); - sum -= c[2] + c[3]; - adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128); - adapt_prob(&pp[3], c[2], c[3], 20, 128); - sum -= c[4] + c[5]; - adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128); - adapt_prob(&pp[5], c[4], c[5], 20, 128); - sum -= c[6]; - adapt_prob(&pp[6], c[6], sum, 20, 128); - adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128); - adapt_prob(&pp[8], c[7], c[8], 20, 128); - adapt_prob(&pp[9], c[9], c[10], 20, 128); - - adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0], - s->counts.mv_comp[i].class0[1], 20, 128); - pp = p->mv_comp[i].bits; - c2 = s->counts.mv_comp[i].bits; - for (j = 0; j < 10; j++) - adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128); - - for (j = 0; j < 2; j++) { - pp = p->mv_comp[i].class0_fp[j]; - c = s->counts.mv_comp[i].class0_fp[j]; - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - } - pp = p->mv_comp[i].fp; - c = s->counts.mv_comp[i].fp; - adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); - adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); - adapt_prob(&pp[2], c[2], c[3], 20, 128); - - if (s->s.h.highprecisionmvs) { - adapt_prob(&p->mv_comp[i].class0_hp, s->counts.mv_comp[i].class0_hp[0], - s->counts.mv_comp[i].class0_hp[1], 20, 128); - adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0], - s->counts.mv_comp[i].hp[1], 20, 128); - } - } - - // y intra modes - for (i = 0; i < 4; i++) { - uint8_t *pp = p->y_mode[i]; - unsigned *c = s->counts.y_mode[i], sum, s2; - - sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; - adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); - sum -= c[TM_VP8_PRED]; - adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); - sum -= c[VERT_PRED]; - adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); - s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; - sum -= s2; - adapt_prob(&pp[3], s2, sum, 20, 128); - s2 -= c[HOR_PRED]; - adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); - adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); - sum -= c[DIAG_DOWN_LEFT_PRED]; - adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); - sum -= c[VERT_LEFT_PRED]; - adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); - adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); - } - - // uv intra modes - for (i = 0; i < 10; i++) { - uint8_t *pp = p->uv_mode[i]; - unsigned *c = s->counts.uv_mode[i], sum, s2; - - sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; - adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); - sum -= c[TM_VP8_PRED]; - adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); - sum -= c[VERT_PRED]; - adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); - s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; - sum -= s2; - adapt_prob(&pp[3], s2, sum, 20, 128); - s2 -= c[HOR_PRED]; - adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); - adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128); - sum -= c[DIAG_DOWN_LEFT_PRED]; - adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); - sum -= c[VERT_LEFT_PRED]; - adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); - adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); - } -} - -static void free_buffers(VP9Context *s) -{ - av_freep(&s->intra_pred_data[0]); - av_freep(&s->b_base); - av_freep(&s->block_base); -} - -static av_cold int vp9_decode_free(AVCodecContext *ctx) -{ - VP9Context *s = ctx->priv_data; - int i; - - for (i = 0; i < 3; i++) { - if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[i]); - av_frame_free(&s->s.frames[i].tf.f); - } - for (i = 0; i < 8; i++) { - if (s->s.refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->s.refs[i]); - av_frame_free(&s->s.refs[i].f); - if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); - av_frame_free(&s->next_refs[i].f); } - free_buffers(s); - av_freep(&s->c_b); - s->c_b_size = 0; - return 0; } +#endif - -static int vp9_decode_frame(AVCodecContext *ctx, void *frame, +static int vp9_decode_frame(AVCodecContext *avctx, void *frame, int *got_frame, AVPacket *pkt) { const uint8_t *data = pkt->data; int size = pkt->size; - VP9Context *s = ctx->priv_data; - int res, tile_row, tile_col, i, ref, row, col; + VP9Context *s = avctx->priv_data; + int ret, i, j, ref; int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map); - ptrdiff_t yoff, uvoff, ls_y, ls_uv; AVFrame *f; - int bytesperpixel; - if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) { - return res; - } else if (res == 0) { + if ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) { + return ret; + } else if (ret == 0) { if (!s->s.refs[ref].f->buf[0]) { - av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); + av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); return AVERROR_INVALIDDATA; } - if ((res = av_frame_ref(frame, s->s.refs[ref].f)) < 0) - return res; + if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0) + return ret; ((AVFrame *)frame)->pts = pkt->pts; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS @@ -4000,73 +1480,70 @@ FF_ENABLE_DEPRECATION_WARNINGS ((AVFrame *)frame)->pkt_dts = pkt->dts; for (i = 0; i < 8; i++) { if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.refs[i].f->buf[0] && - (res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) - return res; + (ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) + return ret; } *got_frame = 1; return pkt->size; } - data += res; - size -= res; + data += ret; + size -= ret; if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) { if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) - return res; + (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) + return ret; } if (s->s.frames[REF_FRAME_MVPAIR].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_MVPAIR]); if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) - return res; + (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) + return ret; if (s->s.frames[CUR_FRAME].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[CUR_FRAME]); - if ((res = vp9_alloc_frame(ctx, &s->s.frames[CUR_FRAME])) < 0) - return res; + vp9_frame_unref(avctx, &s->s.frames[CUR_FRAME]); + if ((ret = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0) + return ret; f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; f->pict_type = (s->s.h.keyframe || s->s.h.intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - ls_y = f->linesize[0]; - ls_uv =f->linesize[1]; if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] && (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width || s->s.frames[REF_FRAME_MVPAIR].tf.f->height != s->s.frames[CUR_FRAME].tf.f->height)) { - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); } // ref frame setup for (i = 0; i < 8; i++) { if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.h.refreshrefmask & (1 << i)) { - res = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); + ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); } else if (s->s.refs[i].f->buf[0]) { - res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]); - } - if (res < 0) - return res; - } - - if (ctx->hwaccel) { - res = ctx->hwaccel->start_frame(ctx, NULL, 0); - if (res < 0) - return res; - res = ctx->hwaccel->decode_slice(ctx, pkt->data, pkt->size); - if (res < 0) - return res; - res = ctx->hwaccel->end_frame(ctx); - if (res < 0) - return res; + ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]); + } + if (ret < 0) + return ret; + } + + if (avctx->hwaccel) { + ret = avctx->hwaccel->start_frame(avctx, NULL, 0); + if (ret < 0) + return ret; + ret = avctx->hwaccel->decode_slice(avctx, pkt->data, pkt->size); + if (ret < 0) + return ret; + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) + return ret; goto finish; } // main tile decode loop - bytesperpixel = s->bytesperpixel; memset(s->above_partition_ctx, 0, s->cols); memset(s->above_skip_ctx, 0, s->cols); if (s->s.h.keyframe || s->s.h.intraonly) { @@ -4079,11 +1556,11 @@ FF_ENABLE_DEPRECATION_WARNINGS memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h); memset(s->above_segpred_ctx, 0, s->cols); s->pass = s->s.frames[CUR_FRAME].uses_2pass = - ctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; - if ((res = update_block_buffers(ctx)) < 0) { - av_log(ctx, AV_LOG_ERROR, + avctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; + if ((ret = update_block_buffers(avctx)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate block buffers\n"); - return res; + return ret; } if (s->s.h.refreshctx && s->s.h.parallelmode) { int j, k, l, m; @@ -4099,25 +1576,36 @@ FF_ENABLE_DEPRECATION_WARNINGS break; } s->prob_ctx[s->s.h.framectxid].p = s->prob.p; - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); } else if (!s->s.h.refreshctx) { - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); + } + +#if HAVE_THREADS + if (avctx->active_thread_type & FF_THREAD_SLICE) { + for (i = 0; i < s->sb_rows; i++) + atomic_store(&s->entries[i], 0); } +#endif do { - yoff = uvoff = 0; - s->b = s->b_base; - s->block = s->block_base; - s->uvblock[0] = s->uvblock_base[0]; - s->uvblock[1] = s->uvblock_base[1]; - s->eob = s->eob_base; - s->uveob[0] = s->uveob_base[0]; - s->uveob[1] = s->uveob_base[1]; - - for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { - set_tile_offset(&s->tile_row_start, &s->tile_row_end, - tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); - if (s->pass != 2) { + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].b = s->td[i].b_base; + s->td[i].block = s->td[i].block_base; + s->td[i].uvblock[0] = s->td[i].uvblock_base[0]; + s->td[i].uvblock[1] = s->td[i].uvblock_base[1]; + s->td[i].eob = s->td[i].eob_base; + s->td[i].uveob[0] = s->td[i].uveob_base[0]; + s->td[i].uveob[1] = s->td[i].uveob_base[1]; + } + +#if HAVE_THREADS + if (avctx->active_thread_type == FF_THREAD_SLICE) { + int tile_row, tile_col; + + av_assert1(!s->pass); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { int64_t tile_size; @@ -4129,107 +1617,38 @@ FF_ENABLE_DEPRECATION_WARNINGS data += 4; size -= 4; } - if (tile_size > size) { - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + if (tile_size > size) return AVERROR_INVALIDDATA; - } - ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); - if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + ret = ff_vp56_init_range_decoder(&s->td[tile_col].c_b[tile_row], data, tile_size); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&s->td[tile_col].c_b[tile_row], 128)) // marker bit return AVERROR_INVALIDDATA; - } data += tile_size; size -= tile_size; } } - for (row = s->tile_row_start; row < s->tile_row_end; - row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { - struct VP9Filter *lflvl_ptr = s->lflvl; - ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; - - for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { - set_tile_offset(&s->tile_col_start, &s->tile_col_end, - tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); - - if (s->pass != 2) { - memset(s->left_partition_ctx, 0, 8); - memset(s->left_skip_ctx, 0, 8); - if (s->s.h.keyframe || s->s.h.intraonly) { - memset(s->left_mode_ctx, DC_PRED, 16); - } else { - memset(s->left_mode_ctx, NEARESTMV, 8); - } - memset(s->left_y_nnz_ctx, 0, 16); - memset(s->left_uv_nnz_ctx, 0, 32); - memset(s->left_segpred_ctx, 0, 8); - - memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c)); - } - - for (col = s->tile_col_start; - col < s->tile_col_end; - col += 8, yoff2 += 64 * bytesperpixel, - uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - // FIXME integrate with lf code (i.e. zero after each - // use, similar to invtxfm coefficients, or similar) - if (s->pass != 1) { - memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); - } - - if (s->pass == 2) { - decode_sb_mem(ctx, row, col, lflvl_ptr, - yoff2, uvoff2, BL_64X64); - } else { - decode_sb(ctx, row, col, lflvl_ptr, - yoff2, uvoff2, BL_64X64); - } - } - if (s->pass != 2) { - memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); - } - } - - if (s->pass == 1) { - continue; - } - - // backup pre-loopfilter reconstruction data for intra - // prediction of next row of sb64s - if (row + 8 < s->rows) { - memcpy(s->intra_pred_data[0], - f->data[0] + yoff + 63 * ls_y, - 8 * s->cols * bytesperpixel); - memcpy(s->intra_pred_data[1], - f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, - 8 * s->cols * bytesperpixel >> s->ss_h); - memcpy(s->intra_pred_data[2], - f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, - 8 * s->cols * bytesperpixel >> s->ss_h); - } - - // loopfilter one row - if (s->s.h.filter.level) { - yoff2 = yoff; - uvoff2 = uvoff; - lflvl_ptr = s->lflvl; - for (col = 0; col < s->cols; - col += 8, yoff2 += 64 * bytesperpixel, - uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2); - } - } - - // FIXME maybe we can make this more finegrained by running the - // loopfilter per-block instead of after each sbrow - // In fact that would also make intra pred left preparation easier? - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0); + ff_slice_thread_execute_with_mainfunc(avctx, decode_tiles_mt, loopfilter_proc, s->td, NULL, s->s.h.tiling.tile_cols); + } else +#endif + { + ret = decode_tiles(avctx, data, size); + if (ret < 0) { + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return ret; } } + // Sum all counts fields into td[0].counts for tile threading + if (avctx->active_thread_type == FF_THREAD_SLICE) + for (i = 1; i < s->s.h.tiling.tile_cols; i++) + for (j = 0; j < sizeof(s->td[i].counts) / sizeof(unsigned); j++) + ((unsigned *)&s->td[0].counts)[j] += ((unsigned *)&s->td[i].counts)[j]; + if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { - adapt_probs(s); - ff_thread_finish_setup(ctx); + ff_vp9_adapt_probs(s); + ff_thread_finish_setup(avctx); } } while (s->pass++ == 1); ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); @@ -4238,42 +1657,42 @@ finish: // ref frame setup for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); if (s->next_refs[i].f->buf[0] && - (res = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) - return res; + (ret = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) + return ret; } if (!s->s.h.invisible) { - if ((res = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0) - return res; + if ((ret = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0) + return ret; *got_frame = 1; } return pkt->size; } -static void vp9_decode_flush(AVCodecContext *ctx) +static void vp9_decode_flush(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) - vp9_unref_frame(ctx, &s->s.frames[i]); + vp9_frame_unref(avctx, &s->s.frames[i]); for (i = 0; i < 8; i++) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); } -static int init_frames(AVCodecContext *ctx) +static int init_frames(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) { s->s.frames[i].tf.f = av_frame_alloc(); if (!s->s.frames[i].tf.f) { - vp9_decode_free(ctx); - av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); + vp9_decode_free(avctx); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); return AVERROR(ENOMEM); } } @@ -4281,8 +1700,8 @@ static int init_frames(AVCodecContext *ctx) s->s.refs[i].f = av_frame_alloc(); s->next_refs[i].f = av_frame_alloc(); if (!s->s.refs[i].f || !s->next_refs[i].f) { - vp9_decode_free(ctx); - av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); + vp9_decode_free(avctx); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); return AVERROR(ENOMEM); } } @@ -4290,15 +1709,15 @@ static int init_frames(AVCodecContext *ctx) return 0; } -static av_cold int vp9_decode_init(AVCodecContext *ctx) +static av_cold int vp9_decode_init(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; - ctx->internal->allocate_progress = 1; + avctx->internal->allocate_progress = 1; s->last_bpp = 0; s->s.h.filter.sharpness = -1; - return init_frames(ctx); + return init_frames(avctx); } #if HAVE_THREADS @@ -4309,23 +1728,23 @@ static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx) static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { - int i, res; + int i, ret; VP9Context *s = dst->priv_data, *ssrc = src->priv_data; for (i = 0; i < 3; i++) { if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(dst, &s->s.frames[i]); + vp9_frame_unref(dst, &s->s.frames[i]); if (ssrc->s.frames[i].tf.f->buf[0]) { - if ((res = vp9_ref_frame(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) - return res; + if ((ret = vp9_frame_ref(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) + return ret; } } for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) ff_thread_release_buffer(dst, &s->s.refs[i]); if (ssrc->next_refs[i].f->buf[0]) { - if ((res = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0) - return res; + if ((ret = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0) + return ret; } } @@ -4341,7 +1760,7 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo s->gf_fmt = ssrc->gf_fmt; s->w = ssrc->w; s->h = ssrc->h; - s->bpp = ssrc->bpp; + s->s.h.bpp = ssrc->s.h.bpp; s->bpp_index = ssrc->bpp_index; s->pix_fmt = ssrc->pix_fmt; memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx)); @@ -4362,7 +1781,8 @@ AVCodec ff_vp9_decoder = { .init = vp9_decode_init, .close = vp9_decode_free, .decode = vp9_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, + .caps_internal = FF_CODEC_CAP_SLICE_THREAD_HAS_MF, .flush = vp9_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), diff --git a/media/ffvpx/libavcodec/vp9.h b/media/ffvpx/libavcodec/vp9.h index df5bd4d85..c8d07ad98 100644 --- a/media/ffvpx/libavcodec/vp9.h +++ b/media/ffvpx/libavcodec/vp9.h @@ -24,42 +24,6 @@ #ifndef AVCODEC_VP9_H #define AVCODEC_VP9_H -#include - -#include "thread.h" -#include "vp56.h" - -enum BlockLevel { - BL_64X64, - BL_32X32, - BL_16X16, - BL_8X8, -}; - -enum BlockPartition { - PARTITION_NONE, // [ ] <-. - PARTITION_H, // [-] | - PARTITION_V, // [|] | - PARTITION_SPLIT, // [+] --' -}; - -enum BlockSize { - BS_64x64, - BS_64x32, - BS_32x64, - BS_32x32, - BS_32x16, - BS_16x32, - BS_16x16, - BS_16x8, - BS_8x16, - BS_8x8, - BS_8x4, - BS_4x8, - BS_4x4, - N_BS_SIZES, -}; - enum TxfmMode { TX_4X4, TX_8X8, @@ -97,115 +61,13 @@ enum IntraPredMode { N_INTRA_PRED_MODES }; -enum InterPredMode { - NEARESTMV = 10, - NEARMV = 11, - ZEROMV = 12, - NEWMV = 13, -}; - enum FilterMode { FILTER_8TAP_SMOOTH, FILTER_8TAP_REGULAR, FILTER_8TAP_SHARP, FILTER_BILINEAR, - FILTER_SWITCHABLE, + N_FILTERS, + FILTER_SWITCHABLE = N_FILTERS, }; -enum CompPredMode { - PRED_SINGLEREF, - PRED_COMPREF, - PRED_SWITCHABLE, -}; - -struct VP9mvrefPair { - VP56mv mv[2]; - int8_t ref[2]; -}; - -typedef struct VP9Frame { - ThreadFrame tf; - AVBufferRef *extradata; - uint8_t *segmentation_map; - struct VP9mvrefPair *mv; - int uses_2pass; - - AVBufferRef *hwaccel_priv_buf; - void *hwaccel_picture_private; -} VP9Frame; - -typedef struct VP9BitstreamHeader { - // bitstream header - uint8_t profile; - uint8_t keyframe; - uint8_t invisible; - uint8_t errorres; - uint8_t intraonly; - uint8_t resetctx; - uint8_t refreshrefmask; - uint8_t highprecisionmvs; - enum FilterMode filtermode; - uint8_t allowcompinter; - uint8_t refreshctx; - uint8_t parallelmode; - uint8_t framectxid; - uint8_t use_last_frame_mvs; - uint8_t refidx[3]; - uint8_t signbias[3]; - uint8_t fixcompref; - uint8_t varcompref[2]; - struct { - uint8_t level; - int8_t sharpness; - } filter; - struct { - uint8_t enabled; - uint8_t updated; - int8_t mode[2]; - int8_t ref[4]; - } lf_delta; - 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; - uint8_t absolute_vals; - uint8_t update_map; - uint8_t prob[7]; - uint8_t pred_prob[3]; - struct { - uint8_t q_enabled; - uint8_t lf_enabled; - uint8_t ref_enabled; - uint8_t skip_enabled; - uint8_t ref_val; - int16_t q_val; - int8_t lf_val; - int16_t qmul[2][2]; - uint8_t lflvl[4][2]; - } feat[MAX_SEGMENT]; - } segmentation; - enum TxfmMode txfmmode; - enum CompPredMode comppredmode; - struct { - unsigned log2_tile_cols, log2_tile_rows; - unsigned tile_cols, tile_rows; - } tiling; - - int uncompressed_header_size; - int compressed_header_size; -} VP9BitstreamHeader; - -typedef struct VP9SharedContext { - VP9BitstreamHeader h; - - ThreadFrame refs[8]; -#define CUR_FRAME 0 -#define REF_FRAME_MVPAIR 1 -#define REF_FRAME_SEGMAP 2 - VP9Frame frames[3]; -} VP9SharedContext; - #endif /* AVCODEC_VP9_H */ diff --git a/media/ffvpx/libavcodec/vp9_mc_template.c b/media/ffvpx/libavcodec/vp9_mc_template.c index 38d9a6da9..31e692f36 100644 --- a/media/ffvpx/libavcodec/vp9_mc_template.c +++ b/media/ffvpx/libavcodec/vp9_mc_template.c @@ -27,19 +27,19 @@ (VP56mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4), \ .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4) } -static void FN(inter_pred)(AVCodecContext *ctx) +static void FN(inter_pred)(VP9TileData *td) { static const uint8_t bwlog_tab[2][N_BS_SIZES] = { { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, }; - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; ThreadFrame *tref1 = &s->s.refs[s->s.h.refidx[b->ref[0]]], *tref2; AVFrame *ref1 = tref1->f, *ref2; int w1 = ref1->width, h1 = ref1->height, w2, h2; - ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride; + ptrdiff_t ls_y = td->y_stride, ls_uv = td->uv_stride; int bytesperpixel = BYTES_PER_PIXEL; if (b->comp) { @@ -55,26 +55,26 @@ static void FN(inter_pred)(AVCodecContext *ctx) #if SCALED == 0 if (b->bs == BS_8x4) { - mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 8, 4, w1, h1, 0); - mc_luma_dir(s, mc[3][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0],,,,, 8, 4, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; if (s->ss_v) { h1 = (h1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << (3 - s->ss_h), @@ -87,8 +87,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << (3 - s->ss_h), @@ -96,26 +96,26 @@ static void FN(inter_pred)(AVCodecContext *ctx) } if (b->comp) { - mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 8, 4, w2, h2, 1); - mc_luma_dir(s, mc[3][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1],,,,, 8, 4, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; if (s->ss_v) { h2 = (h2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << (3 - s->ss_h), @@ -128,8 +128,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << (3 - s->ss_h), @@ -137,32 +137,32 @@ static void FN(inter_pred)(AVCodecContext *ctx) } } } else if (b->bs == BS_4x8) { - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 4, 8, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0],,,,, 4, 8, w1, h1, 0); h1 = (h1 + s->ss_v) >> s->ss_v; if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 3, &b->mv[0][0],,,,, 4, 8 >> s->ss_v, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), (col << 3) + 4, @@ -170,32 +170,32 @@ static void FN(inter_pred)(AVCodecContext *ctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 4, 8, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1],,,,, 4, 8, w2, h2, 1); h2 = (h2 + s->ss_v) >> s->ss_v; if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 3, &b->mv[0][1],,,,, 4, 8 >> s->ss_v, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), (col << 3) + 4, @@ -205,25 +205,27 @@ static void FN(inter_pred)(AVCodecContext *ctx) } else #endif { +#if SCALED == 0 av_assert2(b->bs == BS_4x4); +#endif // FIXME if two horizontally adjacent blocks have the same MV, // do a w8 instead of a w4 call - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, 8, 8, 4, 4, w1, h1, 0); @@ -233,24 +235,24 @@ static void FN(inter_pred)(AVCodecContext *ctx) w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0], b->mv[2][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w1, h1, 0); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w1, h1, 0); uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, (col << 3) + 4, @@ -260,8 +262,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 2, @@ -270,35 +272,35 @@ static void FN(inter_pred)(AVCodecContext *ctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, (col << 3) + 4, @@ -307,18 +309,18 @@ static void FN(inter_pred)(AVCodecContext *ctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, 8, 8, 4, 4, w2, h2, 1); if (s->ss_v) { @@ -327,24 +329,24 @@ static void FN(inter_pred)(AVCodecContext *ctx) w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1], b->mv[2][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w2, h2, 1); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w2, h2, 1); uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, (col << 3) + 4, @@ -354,8 +356,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 2, @@ -364,35 +366,35 @@ static void FN(inter_pred)(AVCodecContext *ctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, (col << 3) + 4, @@ -403,29 +405,31 @@ static void FN(inter_pred)(AVCodecContext *ctx) } } else { int bwl = bwlog_tab[0][b->bs]; - int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4; - int uvbw = bwh_tab[s->ss_h][b->bs][0] * 4, uvbh = bwh_tab[s->ss_v][b->bs][1] * 4; + int bw = ff_vp9_bwh_tab[0][b->bs][0] * 4; + int bh = ff_vp9_bwh_tab[0][b->bs][1] * 4; + int uvbw = ff_vp9_bwh_tab[s->ss_h][b->bs][0] * 4; + int uvbh = ff_vp9_bwh_tab[s->ss_v][b->bs][1] * 4; - mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, bw, bh, bw, bh, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; h1 = (h1 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << (3 - s->ss_h), &b->mv[0][0], 0, 0, uvbw, uvbh, uvbw, uvbh, w1, h1, 0); if (b->comp) { - mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, bw, bh, bw, bh, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; h2 = (h2 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << (3 - s->ss_h), diff --git a/media/ffvpx/libavcodec/vp9block.c b/media/ffvpx/libavcodec/vp9block.c new file mode 100644 index 000000000..1c3f7a722 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9block.c @@ -0,0 +1,1449 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avassert.h" + +#include "avcodec.h" +#include "internal.h" +#include "videodsp.h" +#include "vp56.h" +#include "vp9.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, + ptrdiff_t stride, int v) +{ + switch (w) { + case 1: + do { + *ptr = v; + ptr += stride; + } while (--h); + break; + case 2: { + int v16 = v * 0x0101; + do { + AV_WN16A(ptr, v16); + ptr += stride; + } while (--h); + break; + } + case 4: { + uint32_t v32 = v * 0x01010101; + do { + AV_WN32A(ptr, v32); + ptr += stride; + } while (--h); + break; + } + case 8: { +#if HAVE_FAST_64BIT + uint64_t v64 = v * 0x0101010101010101ULL; + do { + AV_WN64A(ptr, v64); + ptr += stride; + } while (--h); +#else + uint32_t v32 = v * 0x01010101; + do { + AV_WN32A(ptr, v32); + AV_WN32A(ptr + 4, v32); + ptr += stride; + } while (--h); +#endif + break; + } + } +} + +static void decode_mode(VP9TileData *td) +{ + static const uint8_t left_ctx[N_BS_SIZES] = { + 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf + }; + static const uint8_t above_ctx[N_BS_SIZES] = { + 0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf + }; + static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = { + TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, + TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 + }; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; + enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; + int bw4 = ff_vp9_bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); + int bh4 = ff_vp9_bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; + int have_a = row > 0, have_l = col > td->tile_col_start; + int vref, filter_id; + + if (!s->s.h.segmentation.enabled) { + b->seg_id = 0; + } else if (s->s.h.keyframe || s->s.h.intraonly) { + b->seg_id = !s->s.h.segmentation.update_map ? 0 : + vp8_rac_get_tree(td->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); + } else if (!s->s.h.segmentation.update_map || + (s->s.h.segmentation.temporal && + vp56_rac_get_prob_branchy(td->c, + s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + + td->left_segpred_ctx[row7]]))) { + if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { + int pred = 8, x; + uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; + + if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass) + ff_thread_await_progress(&s->s.frames[REF_FRAME_SEGMAP].tf, row >> 3, 0); + for (y = 0; y < h4; y++) { + int idx_base = (y + row) * 8 * s->sb_cols + col; + for (x = 0; x < w4; x++) + pred = FFMIN(pred, refsegmap[idx_base + x]); + } + av_assert1(pred < 8); + b->seg_id = pred; + } else { + b->seg_id = 0; + } + + memset(&s->above_segpred_ctx[col], 1, w4); + memset(&td->left_segpred_ctx[row7], 1, h4); + } else { + b->seg_id = vp8_rac_get_tree(td->c, ff_vp9_segmentation_tree, + s->s.h.segmentation.prob); + + memset(&s->above_segpred_ctx[col], 0, w4); + memset(&td->left_segpred_ctx[row7], 0, h4); + } + if (s->s.h.segmentation.enabled && + (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { + setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col], + bw4, bh4, 8 * s->sb_cols, b->seg_id); + } + + b->skip = s->s.h.segmentation.enabled && + s->s.h.segmentation.feat[b->seg_id].skip_enabled; + if (!b->skip) { + int c = td->left_skip_ctx[row7] + s->above_skip_ctx[col]; + b->skip = vp56_rac_get_prob(td->c, s->prob.p.skip[c]); + td->counts.skip[c][b->skip]++; + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + b->intra = 1; + } else if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { + b->intra = !s->s.h.segmentation.feat[b->seg_id].ref_val; + } else { + int c, bit; + + if (have_a && have_l) { + c = s->above_intra_ctx[col] + td->left_intra_ctx[row7]; + c += (c == 2); + } else { + c = have_a ? 2 * s->above_intra_ctx[col] : + have_l ? 2 * td->left_intra_ctx[row7] : 0; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.intra[c]); + td->counts.intra[c][bit]++; + b->intra = !bit; + } + + if ((b->intra || !b->skip) && s->s.h.txfmmode == TX_SWITCHABLE) { + int c; + if (have_a) { + if (have_l) { + c = (s->above_skip_ctx[col] ? max_tx : + s->above_txfm_ctx[col]) + + (td->left_skip_ctx[row7] ? max_tx : + td->left_txfm_ctx[row7]) > max_tx; + } else { + c = s->above_skip_ctx[col] ? 1 : + (s->above_txfm_ctx[col] * 2 > max_tx); + } + } else if (have_l) { + c = td->left_skip_ctx[row7] ? 1 : + (td->left_txfm_ctx[row7] * 2 > max_tx); + } else { + c = 1; + } + switch (max_tx) { + case TX_32X32: + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][0]); + if (b->tx) { + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][1]); + if (b->tx == 2) + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][2]); + } + td->counts.tx32p[c][b->tx]++; + break; + case TX_16X16: + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx16p[c][0]); + if (b->tx) + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx16p[c][1]); + td->counts.tx16p[c][b->tx]++; + break; + case TX_8X8: + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx8p[c]); + td->counts.tx8p[c][b->tx]++; + break; + case TX_4X4: + b->tx = TX_4X4; + break; + } + } else { + b->tx = FFMIN(max_tx, s->s.h.txfmmode); + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + uint8_t *a = &s->above_mode_ctx[col * 2]; + uint8_t *l = &td->left_mode_ctx[(row7) << 1]; + + b->comp = 0; + if (b->bs > BS_8x8) { + // FIXME the memory storage intermediates here aren't really + // necessary, they're just there to make the code slightly + // simpler for now + b->mode[0] = + a[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); + l[0] = + a[1] = b->mode[1]; + } else { + l[0] = + a[1] = + b->mode[1] = b->mode[0]; + } + if (b->bs != BS_4x8) { + b->mode[2] = + a[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); + l[1] = + a[1] = b->mode[3]; + } else { + l[1] = + a[1] = + b->mode[3] = b->mode[2]; + } + } else { + b->mode[2] = b->mode[0]; + l[1] = + a[1] = + b->mode[3] = b->mode[1]; + } + } else { + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[*a][*l]); + b->mode[3] = + b->mode[2] = + b->mode[1] = b->mode[0]; + // FIXME this can probably be optimized + memset(a, b->mode[0], ff_vp9_bwh_tab[0][b->bs][0]); + memset(l, b->mode[0], ff_vp9_bwh_tab[0][b->bs][1]); + } + b->uvmode = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_uvmode_probs[b->mode[3]]); + } else if (b->intra) { + b->comp = 0; + if (b->bs > BS_8x8) { + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->counts.y_mode[0][b->mode[0]]++; + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->counts.y_mode[0][b->mode[1]]++; + } else { + b->mode[1] = b->mode[0]; + } + if (b->bs != BS_4x8) { + b->mode[2] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->counts.y_mode[0][b->mode[2]]++; + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->counts.y_mode[0][b->mode[3]]++; + } else { + b->mode[3] = b->mode[2]; + } + } else { + b->mode[2] = b->mode[0]; + b->mode[3] = b->mode[1]; + } + } else { + static const uint8_t size_group[10] = { + 3, 3, 3, 3, 2, 2, 2, 1, 1, 1 + }; + int sz = size_group[b->bs]; + + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[sz]); + b->mode[1] = + b->mode[2] = + b->mode[3] = b->mode[0]; + td->counts.y_mode[sz][b->mode[3]]++; + } + b->uvmode = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.uv_mode[b->mode[3]]); + td->counts.uv_mode[b->mode[3]][b->uvmode]++; + } else { + static const uint8_t inter_mode_ctx_lut[14][14] = { + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 }, + }; + + if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { + av_assert2(s->s.h.segmentation.feat[b->seg_id].ref_val != 0); + b->comp = 0; + b->ref[0] = s->s.h.segmentation.feat[b->seg_id].ref_val - 1; + } else { + // read comp_pred flag + if (s->s.h.comppredmode != PRED_SWITCHABLE) { + b->comp = s->s.h.comppredmode == PRED_COMPREF; + } else { + int c; + + // FIXME add intra as ref=0xff (or -1) to make these easier? + if (have_a) { + if (have_l) { + if (s->above_comp_ctx[col] && td->left_comp_ctx[row7]) { + c = 4; + } else if (s->above_comp_ctx[col]) { + c = 2 + (td->left_intra_ctx[row7] || + td->left_ref_ctx[row7] == s->s.h.fixcompref); + } else if (td->left_comp_ctx[row7]) { + c = 2 + (s->above_intra_ctx[col] || + s->above_ref_ctx[col] == s->s.h.fixcompref); + } else { + c = (!s->above_intra_ctx[col] && + s->above_ref_ctx[col] == s->s.h.fixcompref) ^ + (!td->left_intra_ctx[row7] && + td->left_ref_ctx[row & 7] == s->s.h.fixcompref); + } + } else { + c = s->above_comp_ctx[col] ? 3 : + (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); + } + } else if (have_l) { + c = td->left_comp_ctx[row7] ? 3 : + (!td->left_intra_ctx[row7] && td->left_ref_ctx[row7] == s->s.h.fixcompref); + } else { + c = 1; + } + b->comp = vp56_rac_get_prob(td->c, s->prob.p.comp[c]); + td->counts.comp[c][b->comp]++; + } + + // read actual references + // FIXME probably cache a few variables here to prevent repetitive + // memory accesses below + if (b->comp) { /* two references */ + int fix_idx = s->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; + + b->ref[fix_idx] = s->s.h.fixcompref; + // FIXME can this codeblob be replaced by some sort of LUT? + if (have_a) { + if (have_l) { + if (s->above_intra_ctx[col]) { + if (td->left_intra_ctx[row7]) { + c = 2; + } else { + c = 1 + 2 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } + } else if (td->left_intra_ctx[row7]) { + c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } else { + int refl = td->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; + + if (refl == refa && refa == s->s.h.varcompref[1]) { + c = 0; + } else if (!td->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { + if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || + (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { + c = 4; + } else { + c = (refa == refl) ? 3 : 1; + } + } else if (!td->left_comp_ctx[row7]) { + if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { + c = 1; + } else { + c = (refl == s->s.h.varcompref[1] && + refa != s->s.h.varcompref[1]) ? 2 : 4; + } + } else if (!s->above_comp_ctx[col]) { + if (refl == s->s.h.varcompref[1] && refa != s->s.h.varcompref[1]) { + c = 1; + } else { + c = (refa == s->s.h.varcompref[1] && + refl != s->s.h.varcompref[1]) ? 2 : 4; + } + } else { + c = (refl == refa) ? 4 : 2; + } + } + } else { + if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 4 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } else { + c = 3 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } + } + } else if (have_l) { + if (td->left_intra_ctx[row7]) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 4 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } else { + c = 3 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.comp_ref[c]); + b->ref[var_idx] = s->s.h.varcompref[bit]; + td->counts.comp_ref[c][bit]++; + } else /* single reference */ { + int bit, c; + + if (have_a && !s->above_intra_ctx[col]) { + if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_comp_ctx[row7]) { + if (s->above_comp_ctx[col]) { + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7] || + !s->above_ref_ctx[col]); + } else { + c = (3 * !s->above_ref_ctx[col]) + + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); + } + } else if (s->above_comp_ctx[col]) { + c = (3 * !td->left_ref_ctx[row7]) + + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); + } else { + c = 2 * !td->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; + } + } else if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 1 + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); + } else { + c = 4 * (!s->above_ref_ctx[col]); + } + } else if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); + } else { + c = 4 * (!td->left_ref_ctx[row7]); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.single_ref[c][0]); + td->counts.single_ref[c][0][bit]++; + if (!bit) { + b->ref[0] = 0; + } else { + // FIXME can this codeblob be replaced by some sort of LUT? + if (have_a) { + if (have_l) { + if (td->left_intra_ctx[row7]) { + if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->above_ref_ctx[col] == 1); + } else if (!s->above_ref_ctx[col]) { + c = 3; + } else { + c = 4 * (s->above_ref_ctx[col] == 1); + } + } else if (s->above_intra_ctx[col]) { + if (td->left_intra_ctx[row7]) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + td->left_ref_ctx[row7] == 1); + } else if (!td->left_ref_ctx[row7]) { + c = 3; + } else { + c = 4 * (td->left_ref_ctx[row7] == 1); + } + } else if (s->above_comp_ctx[col]) { + if (td->left_comp_ctx[row7]) { + if (td->left_ref_ctx[row7] == s->above_ref_ctx[col]) { + c = 3 * (s->s.h.fixcompref == 1 || + td->left_ref_ctx[row7] == 1); + } else { + c = 2; + } + } else if (!td->left_ref_ctx[row7]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->above_ref_ctx[col] == 1); + } else { + c = 3 * (td->left_ref_ctx[row7] == 1) + + (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); + } + } else if (td->left_comp_ctx[row7]) { + if (!s->above_ref_ctx[col]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + td->left_ref_ctx[row7] == 1); + } else { + c = 3 * (s->above_ref_ctx[col] == 1) + + (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); + } + } else if (!s->above_ref_ctx[col]) { + if (!td->left_ref_ctx[row7]) { + c = 3; + } else { + c = 4 * (td->left_ref_ctx[row7] == 1); + } + } else if (!td->left_ref_ctx[row7]) { + c = 4 * (s->above_ref_ctx[col] == 1); + } else { + c = 2 * (td->left_ref_ctx[row7] == 1) + + 2 * (s->above_ref_ctx[col] == 1); + } + } else { + if (s->above_intra_ctx[col] || + (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 3 * (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); + } else { + c = 4 * (s->above_ref_ctx[col] == 1); + } + } + } else if (have_l) { + if (td->left_intra_ctx[row7] || + (!td->left_comp_ctx[row7] && !td->left_ref_ctx[row7])) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 3 * (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); + } else { + c = 4 * (td->left_ref_ctx[row7] == 1); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.single_ref[c][1]); + td->counts.single_ref[c][1][bit]++; + b->ref[0] = 1 + bit; + } + } + } + + if (b->bs <= BS_8x8) { + if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled) { + b->mode[0] = + b->mode[1] = + b->mode[2] = + b->mode[3] = ZEROMV; + } else { + static const uint8_t off[10] = { + 3, 0, 0, 1, 0, 0, 0, 0, 0, 0 + }; + + // FIXME this needs to use the LUT tables from find_ref_mvs + // because not all are -1,0/0,-1 + int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]] + [td->left_mode_ctx[row7 + off[b->bs]]]; + + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + b->mode[1] = + b->mode[2] = + b->mode[3] = b->mode[0]; + td->counts.mv_mode[c][b->mode[0] - 10]++; + } + } + + if (s->s.h.filtermode == FILTER_SWITCHABLE) { + int c; + + if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { + if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = s->above_filter_ctx[col] == td->left_filter_ctx[row7] ? + td->left_filter_ctx[row7] : 3; + } else { + c = s->above_filter_ctx[col]; + } + } else if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = td->left_filter_ctx[row7]; + } else { + c = 3; + } + + filter_id = vp8_rac_get_tree(td->c, ff_vp9_filter_tree, + s->prob.p.filter[c]); + td->counts.filter[c][filter_id]++; + b->filter = ff_vp9_filter_lut[filter_id]; + } else { + b->filter = s->s.h.filtermode; + } + + if (b->bs > BS_8x8) { + int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][td->left_mode_ctx[row7]]; + + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[0] - 10]++; + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], 0); + + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[1] - 10]++; + ff_vp9_fill_mv(td, b->mv[1], b->mode[1], 1); + } else { + b->mode[1] = b->mode[0]; + AV_COPY32(&b->mv[1][0], &b->mv[0][0]); + AV_COPY32(&b->mv[1][1], &b->mv[0][1]); + } + + if (b->bs != BS_4x8) { + b->mode[2] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[2] - 10]++; + ff_vp9_fill_mv(td, b->mv[2], b->mode[2], 2); + + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[3] - 10]++; + ff_vp9_fill_mv(td, b->mv[3], b->mode[3], 3); + } else { + b->mode[3] = b->mode[2]; + AV_COPY32(&b->mv[3][0], &b->mv[2][0]); + AV_COPY32(&b->mv[3][1], &b->mv[2][1]); + } + } else { + b->mode[2] = b->mode[0]; + AV_COPY32(&b->mv[2][0], &b->mv[0][0]); + AV_COPY32(&b->mv[2][1], &b->mv[0][1]); + b->mode[3] = b->mode[1]; + AV_COPY32(&b->mv[3][0], &b->mv[1][0]); + AV_COPY32(&b->mv[3][1], &b->mv[1][1]); + } + } else { + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], -1); + AV_COPY32(&b->mv[1][0], &b->mv[0][0]); + AV_COPY32(&b->mv[2][0], &b->mv[0][0]); + AV_COPY32(&b->mv[3][0], &b->mv[0][0]); + AV_COPY32(&b->mv[1][1], &b->mv[0][1]); + AV_COPY32(&b->mv[2][1], &b->mv[0][1]); + AV_COPY32(&b->mv[3][1], &b->mv[0][1]); + } + + vref = b->ref[b->comp ? s->s.h.signbias[s->s.h.varcompref[0]] : 0]; + } + +#if HAVE_FAST_64BIT +#define SPLAT_CTX(var, val, n) \ + switch (n) { \ + case 1: var = val; break; \ + case 2: AV_WN16A(&var, val * 0x0101); break; \ + case 4: AV_WN32A(&var, val * 0x01010101); break; \ + case 8: AV_WN64A(&var, val * 0x0101010101010101ULL); break; \ + case 16: { \ + uint64_t v64 = val * 0x0101010101010101ULL; \ + AV_WN64A( &var, v64); \ + AV_WN64A(&((uint8_t *) &var)[8], v64); \ + break; \ + } \ + } +#else +#define SPLAT_CTX(var, val, n) \ + switch (n) { \ + case 1: var = val; break; \ + case 2: AV_WN16A(&var, val * 0x0101); break; \ + case 4: AV_WN32A(&var, val * 0x01010101); break; \ + case 8: { \ + uint32_t v32 = val * 0x01010101; \ + AV_WN32A( &var, v32); \ + AV_WN32A(&((uint8_t *) &var)[4], v32); \ + break; \ + } \ + case 16: { \ + uint32_t v32 = val * 0x01010101; \ + AV_WN32A( &var, v32); \ + AV_WN32A(&((uint8_t *) &var)[4], v32); \ + AV_WN32A(&((uint8_t *) &var)[8], v32); \ + AV_WN32A(&((uint8_t *) &var)[12], v32); \ + break; \ + } \ + } +#endif + + switch (ff_vp9_bwh_tab[1][b->bs][0]) { +#define SET_CTXS(perf, dir, off, n) \ + do { \ + SPLAT_CTX(perf->dir##_skip_ctx[off], b->skip, n); \ + SPLAT_CTX(perf->dir##_txfm_ctx[off], b->tx, n); \ + SPLAT_CTX(perf->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ + if (!s->s.h.keyframe && !s->s.h.intraonly) { \ + SPLAT_CTX(perf->dir##_intra_ctx[off], b->intra, n); \ + SPLAT_CTX(perf->dir##_comp_ctx[off], b->comp, n); \ + SPLAT_CTX(perf->dir##_mode_ctx[off], b->mode[3], n); \ + if (!b->intra) { \ + SPLAT_CTX(perf->dir##_ref_ctx[off], vref, n); \ + if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ + SPLAT_CTX(perf->dir##_filter_ctx[off], filter_id, n); \ + } \ + } \ + } \ + } while (0) + case 1: SET_CTXS(s, above, col, 1); break; + case 2: SET_CTXS(s, above, col, 2); break; + case 4: SET_CTXS(s, above, col, 4); break; + case 8: SET_CTXS(s, above, col, 8); break; + } + switch (ff_vp9_bwh_tab[1][b->bs][1]) { + case 1: SET_CTXS(td, left, row7, 1); break; + case 2: SET_CTXS(td, left, row7, 2); break; + case 4: SET_CTXS(td, left, row7, 4); break; + case 8: SET_CTXS(td, left, row7, 8); break; + } +#undef SPLAT_CTX +#undef SET_CTXS + + if (!s->s.h.keyframe && !s->s.h.intraonly) { + if (b->bs > BS_8x8) { + int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); + + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][0], mv0); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][1], mv1); + AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]); + AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]); + AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0); + AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1); + } else { + int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); + + for (n = 0; n < w4 * 2; n++) { + AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0); + AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1); + } + for (n = 0; n < h4 * 2; n++) { + AV_WN32A(&td->left_mv_ctx[row7 * 2 + n][0], mv0); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + n][1], mv1); + } + } + } + + // FIXME kinda ugly + for (y = 0; y < h4; y++) { + int x, o = (row + y) * s->sb_cols * 8 + col; + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o]; + + if (b->intra) { + for (x = 0; x < w4; x++) { + mv[x].ref[0] = + mv[x].ref[1] = -1; + } + } else if (b->comp) { + for (x = 0; x < w4; x++) { + mv[x].ref[0] = b->ref[0]; + mv[x].ref[1] = b->ref[1]; + AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); + AV_COPY32(&mv[x].mv[1], &b->mv[3][1]); + } + } else { + for (x = 0; x < w4; x++) { + mv[x].ref[0] = b->ref[0]; + mv[x].ref[1] = -1; + AV_COPY32(&mv[x].mv[0], &b->mv[3][0]); + } + } + } +} + +// FIXME merge cnt/eob arguments? +static av_always_inline int +decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs, + int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3], + unsigned (*eob)[6][2], uint8_t (*p)[6][11], + int nnz, const int16_t *scan, const int16_t (*nb)[2], + const int16_t *band_counts, int16_t *qmul) +{ + int i = 0, band = 0, band_left = band_counts[band]; + const uint8_t *tp = p[0][nnz]; + uint8_t cache[1024]; + + do { + int val, rc; + + val = vp56_rac_get_prob_branchy(c, tp[0]); // eob + eob[band][nnz][val]++; + if (!val) + break; + +skip_eob: + if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero + cnt[band][nnz][0]++; + if (!--band_left) + band_left = band_counts[++band]; + cache[scan[i]] = 0; + nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; + tp = p[band][nnz]; + if (++i == n_coeffs) + break; //invalid input; blocks should end with EOB + goto skip_eob; + } + + rc = scan[i]; + if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one + cnt[band][nnz][1]++; + val = 1; + cache[rc] = 1; + } else { + cnt[band][nnz][2]++; + if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4 + if (!vp56_rac_get_prob_branchy(c, tp[4])) { + cache[rc] = val = 2; + } else { + val = 3 + vp56_rac_get_prob(c, tp[5]); + cache[rc] = 3; + } + } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2 + cache[rc] = 4; + if (!vp56_rac_get_prob_branchy(c, tp[7])) { + val = vp56_rac_get_prob(c, 159) + 5; + } else { + val = (vp56_rac_get_prob(c, 165) << 1) + 7; + val += vp56_rac_get_prob(c, 145); + } + } else { // cat 3-6 + cache[rc] = 5; + if (!vp56_rac_get_prob_branchy(c, tp[8])) { + if (!vp56_rac_get_prob_branchy(c, tp[9])) { + val = 11 + (vp56_rac_get_prob(c, 173) << 2); + val += (vp56_rac_get_prob(c, 148) << 1); + val += vp56_rac_get_prob(c, 140); + } else { + val = 19 + (vp56_rac_get_prob(c, 176) << 3); + val += (vp56_rac_get_prob(c, 155) << 2); + val += (vp56_rac_get_prob(c, 140) << 1); + val += vp56_rac_get_prob(c, 135); + } + } else if (!vp56_rac_get_prob_branchy(c, tp[10])) { + val = (vp56_rac_get_prob(c, 180) << 4) + 35; + val += (vp56_rac_get_prob(c, 157) << 3); + val += (vp56_rac_get_prob(c, 141) << 2); + val += (vp56_rac_get_prob(c, 134) << 1); + val += vp56_rac_get_prob(c, 130); + } else { + val = 67; + if (!is8bitsperpixel) { + if (bpp == 12) { + val += vp56_rac_get_prob(c, 255) << 17; + val += vp56_rac_get_prob(c, 255) << 16; + } + val += (vp56_rac_get_prob(c, 255) << 15); + val += (vp56_rac_get_prob(c, 255) << 14); + } + val += (vp56_rac_get_prob(c, 254) << 13); + val += (vp56_rac_get_prob(c, 254) << 12); + val += (vp56_rac_get_prob(c, 254) << 11); + val += (vp56_rac_get_prob(c, 252) << 10); + val += (vp56_rac_get_prob(c, 249) << 9); + val += (vp56_rac_get_prob(c, 243) << 8); + val += (vp56_rac_get_prob(c, 230) << 7); + val += (vp56_rac_get_prob(c, 196) << 6); + val += (vp56_rac_get_prob(c, 177) << 5); + val += (vp56_rac_get_prob(c, 153) << 4); + val += (vp56_rac_get_prob(c, 140) << 3); + val += (vp56_rac_get_prob(c, 133) << 2); + val += (vp56_rac_get_prob(c, 130) << 1); + val += vp56_rac_get_prob(c, 129); + } + } + } +#define STORE_COEF(c, i, v) do { \ + if (is8bitsperpixel) { \ + c[i] = v; \ + } else { \ + AV_WN32A(&c[i * 2], v); \ + } \ +} while (0) + if (!--band_left) + band_left = band_counts[++band]; + if (is_tx32x32) + STORE_COEF(coef, rc, (int)((vp8_rac_get(c) ? -val : val) * (unsigned)qmul[!!i]) / 2); + else + STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * (unsigned)qmul[!!i]); + nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1; + tp = p[band][nnz]; + } while (++i < n_coeffs); + + return i; +} + +static int decode_coeffs_b_8bpp(VP9TileData *td, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b32_8bpp(VP9TileData *td, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b_16bpp(VP9TileData *td, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 0, 0, td->s->s.h.bpp, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b32_16bpp(VP9TileData *td, int16_t *coef, int n_coeffs, + unsigned (*cnt)[6][3], unsigned (*eob)[6][2], + uint8_t (*p)[6][11], int nnz, const int16_t *scan, + const int16_t (*nb)[2], const int16_t *band_counts, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 1, 0, td->s->s.h.bpp, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static av_always_inline int decode_coeffs(VP9TileData *td, int is8bitsperpixel) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; + uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*c)[6][3] = td->counts.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*e)[6][2] = td->counts.eob[b->tx][0 /* y */][!b->intra]; + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1; + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int n, pl, x, y, ret; + int16_t (*qmul)[2] = s->s.h.segmentation.feat[b->seg_id].qmul; + int tx = 4 * s->s.h.lossless + b->tx; + const int16_t * const *yscans = ff_vp9_scans[tx]; + const int16_t (* const * ynbs)[2] = ff_vp9_scans_nb[tx]; + const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT]; + const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT]; + uint8_t *a = &s->above_y_nnz_ctx[col * 2]; + uint8_t *l = &td->left_y_nnz_ctx[(row & 7) << 1]; + static const int16_t band_counts[4][8] = { + { 1, 2, 3, 4, 3, 16 - 13 }, + { 1, 2, 3, 4, 11, 64 - 21 }, + { 1, 2, 3, 4, 11, 256 - 21 }, + { 1, 2, 3, 4, 11, 1024 - 21 }, + }; + const int16_t *y_band_counts = band_counts[b->tx]; + const int16_t *uv_band_counts = band_counts[b->uvtx]; + int bytesperpixel = is8bitsperpixel ? 1 : 2; + int total_coeff = 0; + +#define MERGE(la, end, step, rd) \ + for (n = 0; n < end; n += step) \ + la[n] = !!rd(&la[n]) +#define MERGE_CTX(step, rd) \ + do { \ + MERGE(l, end_y, step, rd); \ + MERGE(a, end_x, step, rd); \ + } while (0) + +#define DECODE_Y_COEF_LOOP(step, mode_index, v) \ + for (n = 0, y = 0; y < end_y; y += step) { \ + for (x = 0; x < end_x; x += step, n += step * step) { \ + enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[mode_index]]; \ + ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + (td, td->block + 16 * n * bytesperpixel, 16 * step * step, \ + c, e, p, a[x] + l[y], yscans[txtp], \ + ynbs[txtp], y_band_counts, qmul[0]); \ + a[x] = l[y] = !!ret; \ + total_coeff |= !!ret; \ + if (step >= 4) { \ + AV_WN16A(&td->eob[n], ret); \ + } else { \ + td->eob[n] = ret; \ + } \ + } \ + } + +#define SPLAT(la, end, step, cond) \ + if (step == 2) { \ + for (n = 1; n < end; n += step) \ + la[n] = la[n - 1]; \ + } else if (step == 4) { \ + if (cond) { \ + for (n = 0; n < end; n += step) \ + AV_WN32A(&la[n], la[n] * 0x01010101); \ + } else { \ + for (n = 0; n < end; n += step) \ + memset(&la[n + 1], la[n], FFMIN(end - n - 1, 3)); \ + } \ + } else /* step == 8 */ { \ + if (cond) { \ + if (HAVE_FAST_64BIT) { \ + for (n = 0; n < end; n += step) \ + AV_WN64A(&la[n], la[n] * 0x0101010101010101ULL); \ + } else { \ + for (n = 0; n < end; n += step) { \ + uint32_t v32 = la[n] * 0x01010101; \ + AV_WN32A(&la[n], v32); \ + AV_WN32A(&la[n + 4], v32); \ + } \ + } \ + } else { \ + for (n = 0; n < end; n += step) \ + memset(&la[n + 1], la[n], FFMIN(end - n - 1, 7)); \ + } \ + } +#define SPLAT_CTX(step) \ + do { \ + SPLAT(a, end_x, step, end_x == w4); \ + SPLAT(l, end_y, step, end_y == h4); \ + } while (0) + + /* y tokens */ + switch (b->tx) { + case TX_4X4: + DECODE_Y_COEF_LOOP(1, b->bs > BS_8x8 ? n : 0,); + break; + case TX_8X8: + MERGE_CTX(2, AV_RN16A); + DECODE_Y_COEF_LOOP(2, 0,); + SPLAT_CTX(2); + break; + case TX_16X16: + MERGE_CTX(4, AV_RN32A); + DECODE_Y_COEF_LOOP(4, 0,); + SPLAT_CTX(4); + break; + case TX_32X32: + MERGE_CTX(8, AV_RN64A); + DECODE_Y_COEF_LOOP(8, 0, 32); + SPLAT_CTX(8); + break; + } + +#define DECODE_UV_COEF_LOOP(step, v) \ + for (n = 0, y = 0; y < end_y; y += step) { \ + for (x = 0; x < end_x; x += step, n += step * step) { \ + ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + (td, td->uvblock[pl] + 16 * n * bytesperpixel, \ + 16 * step * step, c, e, p, a[x] + l[y], \ + uvscan, uvnb, uv_band_counts, qmul[1]); \ + a[x] = l[y] = !!ret; \ + total_coeff |= !!ret; \ + if (step >= 4) { \ + AV_WN16A(&td->uveob[pl][n], ret); \ + } else { \ + td->uveob[pl][n] = ret; \ + } \ + } \ + } + + p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; + c = td->counts.coef[b->uvtx][1 /* uv */][!b->intra]; + e = td->counts.eob[b->uvtx][1 /* uv */][!b->intra]; + w4 >>= s->ss_h; + end_x >>= s->ss_h; + h4 >>= s->ss_v; + end_y >>= s->ss_v; + for (pl = 0; pl < 2; pl++) { + a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h]; + l = &td->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; + switch (b->uvtx) { + case TX_4X4: + DECODE_UV_COEF_LOOP(1,); + break; + case TX_8X8: + MERGE_CTX(2, AV_RN16A); + DECODE_UV_COEF_LOOP(2,); + SPLAT_CTX(2); + break; + case TX_16X16: + MERGE_CTX(4, AV_RN32A); + DECODE_UV_COEF_LOOP(4,); + SPLAT_CTX(4); + break; + case TX_32X32: + MERGE_CTX(8, AV_RN64A); + DECODE_UV_COEF_LOOP(8, 32); + SPLAT_CTX(8); + break; + } + } + + return total_coeff; +} + +static int decode_coeffs_8bpp(VP9TileData *td) +{ + return decode_coeffs(td, 1); +} + +static int decode_coeffs_16bpp(VP9TileData *td) +{ + return decode_coeffs(td, 0); +} + +static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, + int row_and_7, int col_and_7, + int w, int h, int col_end, int row_end, + enum TxfmMode tx, int skip_inter) +{ + static const unsigned wide_filter_col_mask[2] = { 0x11, 0x01 }; + static const unsigned wide_filter_row_mask[2] = { 0x03, 0x07 }; + + // FIXME I'm pretty sure all loops can be replaced by a single LUT if + // we make VP9Filter.mask uint64_t (i.e. row/col all single variable) + // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then + // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7) + + // the intended behaviour of the vp9 loopfilter is to work on 8-pixel + // edges. This means that for UV, we work on two subsampled blocks at + // a time, and we only use the topleft block's mode information to set + // things like block strength. Thus, for any block size smaller than + // 16x16, ignore the odd portion of the block. + if (tx == TX_4X4 && (ss_v | ss_h)) { + if (h == ss_v) { + if (row_and_7 & 1) + return; + if (!row_end) + h += 1; + } + if (w == ss_h) { + if (col_and_7 & 1) + return; + if (!col_end) + w += 1; + } + } + + if (tx == TX_4X4 && !skip_inter) { + int t = 1 << col_and_7, m_col = (t << w) - t, y; + // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide + int m_row_8 = m_col & wide_filter_col_mask[ss_h], m_row_4 = m_col - m_row_8; + + for (y = row_and_7; y < h + row_and_7; y++) { + int col_mask_id = 2 - !(y & wide_filter_row_mask[ss_v]); + + mask[0][y][1] |= m_row_8; + mask[0][y][2] |= m_row_4; + // for odd lines, if the odd col is not being filtered, + // skip odd row also: + // .---. <-- a + // | | + // |___| <-- b + // ^ ^ + // c d + // + // if a/c are even row/col and b/d are odd, and d is skipped, + // e.g. right edge of size-66x66.webm, then skip b also (bug) + if ((ss_h & ss_v) && (col_end & 1) && (y & 1)) { + mask[1][y][col_mask_id] |= (t << (w - 1)) - t; + } else { + mask[1][y][col_mask_id] |= m_col; + } + if (!ss_h) + mask[0][y][3] |= m_col; + if (!ss_v) { + if (ss_h && (col_end & 1)) + mask[1][y][3] |= (t << (w - 1)) - t; + else + mask[1][y][3] |= m_col; + } + } + } else { + int y, t = 1 << col_and_7, m_col = (t << w) - t; + + if (!skip_inter) { + int mask_id = (tx == TX_8X8); + int l2 = tx + ss_h - 1, step1d; + static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; + int m_row = m_col & masks[l2]; + + // at odd UV col/row edges tx16/tx32 loopfilter edges, force + // 8wd loopfilter to prevent going off the visible edge. + if (ss_h && tx > TX_8X8 && (w ^ (w - 1)) == 1) { + int m_row_16 = ((t << (w - 1)) - t) & masks[l2]; + int m_row_8 = m_row - m_row_16; + + for (y = row_and_7; y < h + row_and_7; y++) { + mask[0][y][0] |= m_row_16; + mask[0][y][1] |= m_row_8; + } + } else { + for (y = row_and_7; y < h + row_and_7; y++) + mask[0][y][mask_id] |= m_row; + } + + l2 = tx + ss_v - 1; + step1d = 1 << l2; + if (ss_v && tx > TX_8X8 && (h ^ (h - 1)) == 1) { + for (y = row_and_7; y < h + row_and_7 - 1; y += step1d) + mask[1][y][0] |= m_col; + if (y - row_and_7 == h - 1) + mask[1][y][1] |= m_col; + } else { + for (y = row_and_7; y < h + row_and_7; y += step1d) + mask[1][y][mask_id] |= m_col; + } + } else if (tx != TX_4X4) { + int mask_id; + + mask_id = (tx == TX_8X8) || (h == ss_v); + mask[1][row_and_7][mask_id] |= m_col; + mask_id = (tx == TX_8X8) || (w == ss_h); + for (y = row_and_7; y < h + row_and_7; y++) + mask[0][y][mask_id] |= t; + } else { + int t8 = t & wide_filter_col_mask[ss_h], t4 = t - t8; + + for (y = row_and_7; y < h + row_and_7; y++) { + mask[0][y][2] |= t4; + mask[0][y][1] |= t8; + } + mask[1][row_and_7][2 - !(row_and_7 & wide_filter_row_mask[ss_v])] |= m_col; + } + } +} + +void ff_vp9_decode_block(VP9TileData *td, int row, int col, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + enum BlockSize bs = bl * 3 + bp; + int bytesperpixel = s->bytesperpixel; + int w4 = ff_vp9_bwh_tab[1][bs][0], h4 = ff_vp9_bwh_tab[1][bs][1], lvl; + int emu[2]; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + + td->row = row; + td->row7 = row & 7; + td->col = col; + td->col7 = col & 7; + + td->min_mv.x = -(128 + col * 64); + td->min_mv.y = -(128 + row * 64); + td->max_mv.x = 128 + (s->cols - col - w4) * 64; + td->max_mv.y = 128 + (s->rows - row - h4) * 64; + + if (s->pass < 2) { + b->bs = bs; + b->bl = bl; + b->bp = bp; + decode_mode(td); + b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || + (s->ss_v && h4 * 2 == (1 << b->tx))); + + if (!b->skip) { + int has_coeffs; + + if (bytesperpixel == 1) { + has_coeffs = decode_coeffs_8bpp(td); + } else { + has_coeffs = decode_coeffs_16bpp(td); + } + if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { + b->skip = 1; + memset(&s->above_skip_ctx[col], 1, w4); + memset(&td->left_skip_ctx[td->row7], 1, h4); + } + } else { + int row7 = td->row7; + +#define SPLAT_ZERO_CTX(v, n) \ + switch (n) { \ + case 1: v = 0; break; \ + case 2: AV_ZERO16(&v); break; \ + case 4: AV_ZERO32(&v); break; \ + case 8: AV_ZERO64(&v); break; \ + case 16: AV_ZERO128(&v); break; \ + } +#define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \ + do { \ + SPLAT_ZERO_CTX(dir##_y_##var[off * 2], n * 2); \ + if (s->ss_##dir2) { \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off], n); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off], n); \ + } else { \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off * 2], n * 2); \ + } \ + } while (0) + + switch (w4) { + case 1: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 1, h); break; + case 2: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 2, h); break; + case 4: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 4, h); break; + case 8: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 8, h); break; + } + switch (h4) { + case 1: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 1, v); break; + case 2: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 2, v); break; + case 4: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 4, v); break; + case 8: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 8, v); break; + } + } + + if (s->pass == 1) { + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + + return; + } + } + + // emulated overhangs if the stride of the target buffer can't hold. This + // makes it possible to support emu-edge and so on even if we have large block + // overhangs + emu[0] = (col + w4) * 8 * bytesperpixel > f->linesize[0] || + (row + h4) > s->rows; + emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || + (row + h4) > s->rows; + if (emu[0]) { + td->dst[0] = td->tmp_y; + td->y_stride = 128; + } else { + td->dst[0] = f->data[0] + yoff; + td->y_stride = f->linesize[0]; + } + if (emu[1]) { + td->dst[1] = td->tmp_uv[0]; + td->dst[2] = td->tmp_uv[1]; + td->uv_stride = 128; + } else { + td->dst[1] = f->data[1] + uvoff; + td->dst[2] = f->data[2] + uvoff; + td->uv_stride = f->linesize[1]; + } + if (b->intra) { + if (s->s.h.bpp > 8) { + ff_vp9_intra_recon_16bpp(td, yoff, uvoff); + } else { + ff_vp9_intra_recon_8bpp(td, yoff, uvoff); + } + } else { + if (s->s.h.bpp > 8) { + ff_vp9_inter_recon_16bpp(td); + } else { + ff_vp9_inter_recon_8bpp(td); + } + } + if (emu[0]) { + int w = FFMIN(s->cols - col, w4) * 8, h = FFMIN(s->rows - row, h4) * 8, n, o = 0; + + for (n = 0; o < w; n++) { + int bw = 64 >> n; + + av_assert2(n <= 4); + if (w & bw) { + s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o * bytesperpixel, f->linesize[0], + td->tmp_y + o * bytesperpixel, 128, h, 0, 0); + o += bw; + } + } + } + if (emu[1]) { + int w = FFMIN(s->cols - col, w4) * 8 >> s->ss_h; + int h = FFMIN(s->rows - row, h4) * 8 >> s->ss_v, n, o = 0; + + for (n = s->ss_h; o < w; n++) { + int bw = 64 >> n; + + av_assert2(n <= 4); + if (w & bw) { + s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o * bytesperpixel, f->linesize[1], + td->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); + s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], + td->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); + o += bw; + } + } + } + + // pick filter level and find edges to apply filter to + if (s->s.h.filter.level && + (lvl = s->s.h.segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1] + [b->mode[3] != ZEROMV]) > 0) { + int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4); + int skip_inter = !b->intra && b->skip, col7 = td->col7, row7 = td->row7; + + setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl); + mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter); + if (s->ss_h || s->ss_v) + mask_edges(lflvl->mask[1], s->ss_h, s->ss_v, row7, col7, x_end, y_end, + s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0, + s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0, + b->uvtx, skip_inter); + } + + if (s->pass == 2) { + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + } +} diff --git a/media/ffvpx/libavcodec/vp9data.c b/media/ffvpx/libavcodec/vp9data.c new file mode 100644 index 000000000..7af8a97b1 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9data.c @@ -0,0 +1,2247 @@ +/* + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "vp9.h" +#include "vp9data.h" + +const uint8_t ff_vp9_bwh_tab[2][N_BS_SIZES][2] = { + { + { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 }, + { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, + }, { + { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 }, + { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, + } +}; + +const int8_t ff_vp9_partition_tree[3][2] = { + { -PARTITION_NONE, 1 }, // '0' + { -PARTITION_H, 2 }, // '10' + { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' +}; + +const uint8_t ff_vp9_default_kf_partition_probs[4][4][3] = { + { /* 64x64 -> 32x32 */ + { 174, 35, 49 } /* a/l both not split */, + { 68, 11, 27 } /* a split, l not split */, + { 57, 15, 9 } /* l split, a not split */, + { 12, 3, 3 } /* a/l both split */ + }, { /* 32x32 -> 16x16 */ + { 150, 40, 39 } /* a/l both not split */, + { 78, 12, 26 } /* a split, l not split */, + { 67, 33, 11 } /* l split, a not split */, + { 24, 7, 5 } /* a/l both split */, + }, { /* 16x16 -> 8x8 */ + { 149, 53, 53 } /* a/l both not split */, + { 94, 20, 48 } /* a split, l not split */, + { 83, 53, 24 } /* l split, a not split */, + { 52, 18, 18 } /* a/l both split */, + }, { /* 8x8 -> 4x4 */ + { 158, 97, 94 } /* a/l both not split */, + { 93, 24, 99 } /* a split, l not split */, + { 85, 119, 44 } /* l split, a not split */, + { 62, 59, 67 } /* a/l both split */, + }, +}; + +const int8_t ff_vp9_segmentation_tree[7][2] = { + { 1, 2 }, + { 3, 4 }, + { 5, 6 }, + { -0, -1 }, // '00x' + { -2, -3 }, // '01x' + { -4, -5 }, // '10x' + { -6, -7 }, // '11x' +}; + +const int8_t ff_vp9_intramode_tree[9][2] = { + { -DC_PRED, 1 }, // '0' + { -TM_VP8_PRED, 2 }, // '10' + { -VERT_PRED, 3 }, // '110' + { 4, 6 }, + { -HOR_PRED, 5 }, // '11100' + { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' + { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' + { -VERT_LEFT_PRED, 8 }, // '111110' + { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' +}; + +const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9] = { + { /* above = v */ + { 43, 46, 168, 134, 107, 128, 69, 142, 92 } /* left = v */, + { 44, 29, 68, 159, 201, 177, 50, 57, 77 } /* left = h */, + { 63, 36, 126, 146, 123, 158, 60, 90, 96 } /* left = dc */, + { 58, 38, 76, 114, 97, 172, 78, 133, 92 } /* left = d45 */, + { 46, 41, 76, 140, 63, 184, 69, 112, 57 } /* left = d135 */, + { 38, 32, 85, 140, 46, 112, 54, 151, 133 } /* left = d117 */, + { 39, 27, 61, 131, 110, 175, 44, 75, 136 } /* left = d153 */, + { 47, 35, 80, 100, 74, 143, 64, 163, 74 } /* left = d63 */, + { 52, 30, 74, 113, 130, 175, 51, 64, 58 } /* left = d27 */, + { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /* left = tm */ + }, { /* above = h */ + { 55, 44, 68, 166, 179, 192, 57, 57, 108 } /* left = v */, + { 42, 26, 11, 199, 241, 228, 23, 15, 85 } /* left = h */, + { 82, 26, 26, 171, 208, 204, 44, 32, 105 } /* left = dc */, + { 68, 42, 19, 131, 160, 199, 55, 52, 83 } /* left = d45 */, + { 58, 50, 25, 139, 115, 232, 39, 52, 118 } /* left = d135 */, + { 50, 35, 33, 153, 104, 162, 64, 59, 131 } /* left = d117 */, + { 44, 24, 16, 150, 177, 202, 33, 19, 156 } /* left = d153 */, + { 53, 49, 21, 110, 116, 168, 59, 80, 76 } /* left = d63 */, + { 55, 27, 12, 153, 203, 218, 26, 27, 49 } /* left = d27 */, + { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /* left = tm */ + }, { /* above = dc */ + { 92, 45, 102, 136, 116, 180, 74, 90, 100 } /* left = v */, + { 73, 32, 19, 187, 222, 215, 46, 34, 100 } /* left = h */, + { 137, 30, 42, 148, 151, 207, 70, 52, 91 } /* left = dc */, + { 91, 30, 32, 116, 121, 186, 93, 86, 94 } /* left = d45 */, + { 72, 35, 36, 149, 68, 206, 68, 63, 105 } /* left = d135 */, + { 73, 31, 28, 138, 57, 124, 55, 122, 151 } /* left = d117 */, + { 67, 23, 21, 140, 126, 197, 40, 37, 171 } /* left = d153 */, + { 74, 32, 27, 107, 86, 160, 63, 134, 102 } /* left = d63 */, + { 86, 27, 28, 128, 154, 212, 45, 43, 53 } /* left = d27 */, + { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /* left = tm */ + }, { /* above = d45 */ + { 59, 38, 83, 112, 103, 162, 98, 136, 90 } /* left = v */, + { 62, 30, 23, 158, 200, 207, 59, 57, 50 } /* left = h */, + { 103, 26, 36, 129, 132, 201, 83, 80, 93 } /* left = dc */, + { 67, 30, 29, 84, 86, 191, 102, 91, 59 } /* left = d45 */, + { 60, 32, 33, 112, 71, 220, 64, 89, 104 } /* left = d135 */, + { 53, 26, 34, 130, 56, 149, 84, 120, 103 } /* left = d117 */, + { 53, 21, 23, 133, 109, 210, 56, 77, 172 } /* left = d153 */, + { 61, 29, 29, 93, 97, 165, 83, 175, 162 } /* left = d63 */, + { 77, 19, 29, 112, 142, 228, 55, 66, 36 } /* left = d27 */, + { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /* left = tm */ + }, { /* above = d135 */ + { 53, 40, 55, 139, 69, 183, 61, 80, 110 } /* left = v */, + { 40, 29, 19, 161, 180, 207, 43, 24, 91 } /* left = h */, + { 69, 23, 29, 128, 83, 199, 46, 44, 101 } /* left = dc */, + { 60, 34, 19, 105, 61, 198, 53, 64, 89 } /* left = d45 */, + { 52, 31, 22, 158, 40, 209, 58, 62, 89 } /* left = d135 */, + { 44, 31, 29, 147, 46, 158, 56, 102, 198 } /* left = d117 */, + { 35, 19, 12, 135, 87, 209, 41, 45, 167 } /* left = d153 */, + { 51, 38, 25, 113, 58, 164, 70, 93, 97 } /* left = d63 */, + { 55, 25, 21, 118, 95, 215, 38, 39, 66 } /* left = d27 */, + { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /* left = tm */ + }, { /* above = d117 */ + { 46, 27, 80, 150, 55, 124, 55, 121, 135 } /* left = v */, + { 36, 23, 27, 165, 149, 166, 54, 64, 118 } /* left = h */, + { 64, 19, 37, 156, 66, 138, 49, 95, 133 } /* left = dc */, + { 53, 21, 36, 131, 63, 163, 60, 109, 81 } /* left = d45 */, + { 40, 26, 35, 154, 40, 185, 51, 97, 123 } /* left = d135 */, + { 35, 19, 34, 179, 19, 97, 48, 129, 124 } /* left = d117 */, + { 36, 20, 26, 136, 62, 164, 33, 77, 154 } /* left = d153 */, + { 45, 26, 28, 129, 45, 129, 49, 147, 123 } /* left = d63 */, + { 45, 18, 32, 130, 90, 157, 40, 79, 91 } /* left = d27 */, + { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /* left = tm */ + }, { /* above = d153 */ + { 56, 39, 58, 133, 117, 173, 48, 53, 187 } /* left = v */, + { 35, 21, 12, 161, 212, 207, 20, 23, 145 } /* left = h */, + { 75, 17, 22, 136, 138, 185, 32, 34, 166 } /* left = dc */, + { 56, 29, 19, 117, 109, 181, 55, 68, 112 } /* left = d45 */, + { 47, 29, 17, 153, 64, 220, 59, 51, 114 } /* left = d135 */, + { 46, 16, 24, 136, 76, 147, 41, 64, 172 } /* left = d117 */, + { 34, 17, 11, 108, 152, 187, 13, 15, 209 } /* left = d153 */, + { 55, 30, 18, 122, 79, 179, 44, 88, 116 } /* left = d63 */, + { 51, 24, 14, 115, 133, 209, 32, 26, 104 } /* left = d27 */, + { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /* left = tm */ + }, { /* above = d63 */ + { 48, 34, 86, 101, 92, 146, 78, 179, 134 } /* left = v */, + { 47, 22, 24, 138, 187, 178, 68, 69, 59 } /* left = h */, + { 78, 23, 39, 111, 117, 170, 74, 124, 94 } /* left = dc */, + { 56, 25, 33, 105, 112, 187, 95, 177, 129 } /* left = d45 */, + { 48, 31, 27, 114, 63, 183, 82, 116, 56 } /* left = d135 */, + { 43, 28, 37, 121, 63, 123, 61, 192, 169 } /* left = d117 */, + { 42, 17, 24, 109, 97, 177, 56, 76, 122 } /* left = d153 */, + { 46, 23, 32, 74, 86, 150, 67, 183, 88 } /* left = d63 */, + { 58, 18, 28, 105, 139, 182, 70, 92, 63 } /* left = d27 */, + { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /* left = tm */ + }, { /* above = d27 */ + { 62, 44, 61, 123, 105, 189, 48, 57, 64 } /* left = v */, + { 47, 25, 17, 175, 222, 220, 24, 30, 86 } /* left = h */, + { 82, 22, 32, 127, 143, 213, 39, 41, 70 } /* left = dc */, + { 68, 36, 17, 106, 102, 206, 59, 74, 74 } /* left = d45 */, + { 57, 39, 23, 151, 68, 216, 55, 63, 58 } /* left = d135 */, + { 49, 30, 35, 141, 70, 168, 82, 40, 115 } /* left = d117 */, + { 51, 25, 15, 136, 129, 202, 38, 35, 139 } /* left = d153 */, + { 59, 39, 19, 114, 75, 180, 77, 104, 42 } /* left = d63 */, + { 68, 26, 16, 111, 141, 215, 29, 28, 28 } /* left = d27 */, + { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /* left = tm */ + }, { /* above = tm */ + { 44, 78, 115, 132, 119, 173, 71, 112, 93 } /* left = v */, + { 39, 38, 21, 184, 227, 206, 42, 32, 64 } /* left = h */, + { 65, 70, 60, 155, 159, 199, 61, 60, 81 } /* left = dc */, + { 58, 47, 36, 124, 137, 193, 80, 82, 78 } /* left = d45 */, + { 49, 50, 35, 144, 95, 205, 63, 78, 59 } /* left = d135 */, + { 41, 53, 52, 148, 71, 142, 65, 128, 51 } /* left = d117 */, + { 40, 36, 28, 143, 143, 202, 40, 55, 137 } /* left = d153 */, + { 42, 44, 44, 104, 105, 164, 64, 130, 80 } /* left = d63 */, + { 52, 34, 29, 129, 183, 227, 42, 35, 43 } /* left = d27 */, + { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /* left = tm */ + } +}; + +const uint8_t ff_vp9_default_kf_uvmode_probs[10][9] = { + { 118, 15, 123, 148, 131, 101, 44, 93, 131 } /* y = v */, + { 113, 12, 23, 188, 226, 142, 26, 32, 125 } /* y = h */, + { 144, 11, 54, 157, 195, 130, 46, 58, 108 } /* y = dc */, + { 120, 11, 50, 123, 163, 135, 64, 77, 103 } /* y = d45 */, + { 113, 9, 36, 155, 111, 157, 32, 44, 161 } /* y = d135 */, + { 116, 9, 55, 176, 76, 96, 37, 61, 149 } /* y = d117 */, + { 115, 9, 28, 141, 161, 167, 21, 25, 193 } /* y = d153 */, + { 116, 12, 64, 120, 140, 125, 49, 115, 121 } /* y = d63 */, + { 120, 12, 32, 145, 195, 142, 32, 38, 86 } /* y = d27 */, + { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ +}; + +const int8_t ff_vp9_inter_mode_tree[3][2] = { + { -ZEROMV, 1 }, // '0' + { -NEARESTMV, 2 }, // '10' + { -NEARMV, -NEWMV }, // '11x' +}; + +const int8_t ff_vp9_filter_tree[2][2] = { + { -0, 1 }, // '0' + { -1, -2 }, // '1x' +}; + +const enum FilterMode ff_vp9_filter_lut[3] = { + FILTER_8TAP_REGULAR, + FILTER_8TAP_SMOOTH, + FILTER_8TAP_SHARP, +}; + +const int16_t ff_vp9_dc_qlookup[3][256] = { + { + 4, 8, 8, 9, 10, 11, 12, 12, + 13, 14, 15, 16, 17, 18, 19, 19, + 20, 21, 22, 23, 24, 25, 26, 26, + 27, 28, 29, 30, 31, 32, 32, 33, + 34, 35, 36, 37, 38, 38, 39, 40, + 41, 42, 43, 43, 44, 45, 46, 47, + 48, 48, 49, 50, 51, 52, 53, 53, + 54, 55, 56, 57, 57, 58, 59, 60, + 61, 62, 62, 63, 64, 65, 66, 66, + 67, 68, 69, 70, 70, 71, 72, 73, + 74, 74, 75, 76, 77, 78, 78, 79, + 80, 81, 81, 82, 83, 84, 85, 85, + 87, 88, 90, 92, 93, 95, 96, 98, + 99, 101, 102, 104, 105, 107, 108, 110, + 111, 113, 114, 116, 117, 118, 120, 121, + 123, 125, 127, 129, 131, 134, 136, 138, + 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 161, 164, 166, 169, 172, 174, + 177, 180, 182, 185, 187, 190, 192, 195, + 199, 202, 205, 208, 211, 214, 217, 220, + 223, 226, 230, 233, 237, 240, 243, 247, + 250, 253, 257, 261, 265, 269, 272, 276, + 280, 284, 288, 292, 296, 300, 304, 309, + 313, 317, 322, 326, 330, 335, 340, 344, + 349, 354, 359, 364, 369, 374, 379, 384, + 389, 395, 400, 406, 411, 417, 423, 429, + 435, 441, 447, 454, 461, 467, 475, 482, + 489, 497, 505, 513, 522, 530, 539, 549, + 559, 569, 579, 590, 602, 614, 626, 640, + 654, 668, 684, 700, 717, 736, 755, 775, + 796, 819, 843, 869, 896, 925, 955, 988, + 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, + }, { + 4, 9, 10, 13, 15, 17, 20, 22, + 25, 28, 31, 34, 37, 40, 43, 47, + 50, 53, 57, 60, 64, 68, 71, 75, + 78, 82, 86, 90, 93, 97, 101, 105, + 109, 113, 116, 120, 124, 128, 132, 136, + 140, 143, 147, 151, 155, 159, 163, 166, + 170, 174, 178, 182, 185, 189, 193, 197, + 200, 204, 208, 212, 215, 219, 223, 226, + 230, 233, 237, 241, 244, 248, 251, 255, + 259, 262, 266, 269, 273, 276, 280, 283, + 287, 290, 293, 297, 300, 304, 307, 310, + 314, 317, 321, 324, 327, 331, 334, 337, + 343, 350, 356, 362, 369, 375, 381, 387, + 394, 400, 406, 412, 418, 424, 430, 436, + 442, 448, 454, 460, 466, 472, 478, 484, + 490, 499, 507, 516, 525, 533, 542, 550, + 559, 567, 576, 584, 592, 601, 609, 617, + 625, 634, 644, 655, 666, 676, 687, 698, + 708, 718, 729, 739, 749, 759, 770, 782, + 795, 807, 819, 831, 844, 856, 868, 880, + 891, 906, 920, 933, 947, 961, 975, 988, + 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, + 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, + 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, + 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, + 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, + 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, + 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, + 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, + 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, + 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, + 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, + }, { + 4, 12, 18, 25, 33, 41, 50, 60, + 70, 80, 91, 103, 115, 127, 140, 153, + 166, 180, 194, 208, 222, 237, 251, 266, + 281, 296, 312, 327, 343, 358, 374, 390, + 405, 421, 437, 453, 469, 484, 500, 516, + 532, 548, 564, 580, 596, 611, 627, 643, + 659, 674, 690, 706, 721, 737, 752, 768, + 783, 798, 814, 829, 844, 859, 874, 889, + 904, 919, 934, 949, 964, 978, 993, 1008, + 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, + 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, + 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, + 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, + 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, + 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, + 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, + 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, + 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, + 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, + 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, + 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, + 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, + 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, + 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, + 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, + 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, + 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, + 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, + 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, + 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, + 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, + 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, + } +}; + +const int16_t ff_vp9_ac_qlookup[3][256] = { + { + 4, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, + 104, 106, 108, 110, 112, 114, 116, 118, + 120, 122, 124, 126, 128, 130, 132, 134, + 136, 138, 140, 142, 144, 146, 148, 150, + 152, 155, 158, 161, 164, 167, 170, 173, + 176, 179, 182, 185, 188, 191, 194, 197, + 200, 203, 207, 211, 215, 219, 223, 227, + 231, 235, 239, 243, 247, 251, 255, 260, + 265, 270, 275, 280, 285, 290, 295, 300, + 305, 311, 317, 323, 329, 335, 341, 347, + 353, 359, 366, 373, 380, 387, 394, 401, + 408, 416, 424, 432, 440, 448, 456, 465, + 474, 483, 492, 501, 510, 520, 530, 540, + 550, 560, 571, 582, 593, 604, 615, 627, + 639, 651, 663, 676, 689, 702, 715, 729, + 743, 757, 771, 786, 801, 816, 832, 848, + 864, 881, 898, 915, 933, 951, 969, 988, + 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, + 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, + 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, + 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, + }, { + 4, 9, 11, 13, 16, 18, 21, 24, + 27, 30, 33, 37, 40, 44, 48, 51, + 55, 59, 63, 67, 71, 75, 79, 83, + 88, 92, 96, 100, 105, 109, 114, 118, + 122, 127, 131, 136, 140, 145, 149, 154, + 158, 163, 168, 172, 177, 181, 186, 190, + 195, 199, 204, 208, 213, 217, 222, 226, + 231, 235, 240, 244, 249, 253, 258, 262, + 267, 271, 275, 280, 284, 289, 293, 297, + 302, 306, 311, 315, 319, 324, 328, 332, + 337, 341, 345, 349, 354, 358, 362, 367, + 371, 375, 379, 384, 388, 392, 396, 401, + 409, 417, 425, 433, 441, 449, 458, 466, + 474, 482, 490, 498, 506, 514, 523, 531, + 539, 547, 555, 563, 571, 579, 588, 596, + 604, 616, 628, 640, 652, 664, 676, 688, + 700, 713, 725, 737, 749, 761, 773, 785, + 797, 809, 825, 841, 857, 873, 889, 905, + 922, 938, 954, 970, 986, 1002, 1018, 1038, + 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, + 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, + 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, + 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, + 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, + 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, + 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, + 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, + 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, + 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, + 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, + 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, + 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, + }, { + 4, 13, 19, 27, 35, 44, 54, 64, + 75, 87, 99, 112, 126, 139, 154, 168, + 183, 199, 214, 230, 247, 263, 280, 297, + 314, 331, 349, 366, 384, 402, 420, 438, + 456, 475, 493, 511, 530, 548, 567, 586, + 604, 623, 642, 660, 679, 698, 716, 735, + 753, 772, 791, 809, 828, 846, 865, 884, + 902, 920, 939, 957, 976, 994, 1012, 1030, + 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, + 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, + 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, + 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, + 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, + 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, + 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, + 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, + 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, + 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, + 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, + 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, + 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, + 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, + 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, + 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, + 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, + 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, + 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, + 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, + 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, + 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, + 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, + 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, + } +}; + +const enum TxfmType ff_vp9_intra_txfm_type[14] = { + [VERT_PRED] = ADST_DCT, + [HOR_PRED] = DCT_ADST, + [DC_PRED] = DCT_DCT, + [DIAG_DOWN_LEFT_PRED] = DCT_DCT, + [DIAG_DOWN_RIGHT_PRED] = ADST_ADST, + [VERT_RIGHT_PRED] = ADST_DCT, + [HOR_DOWN_PRED] = DCT_ADST, + [VERT_LEFT_PRED] = ADST_DCT, + [HOR_UP_PRED] = DCT_ADST, + [TM_VP8_PRED] = ADST_ADST, + [NEARESTMV] = DCT_DCT, + [NEARMV] = DCT_DCT, + [ZEROMV] = DCT_DCT, + [NEWMV] = DCT_DCT, +}; + +const int16_t ff_vp9_default_scan_4x4[16] = { + 0, 1, 4, 5, + 2, 8, 3, 6, + 12, 9, 7, 10, + 13, 11, 14, 15, +}; + +const int16_t ff_vp9_col_scan_4x4[16] = { + 0, 1, 2, 4, + 3, 5, 6, 8, + 7, 9, 10, 12, + 13, 11, 14, 15, +}; + +const int16_t ff_vp9_row_scan_4x4[16] = { + 0, 4, 1, 8, + 5, 12, 9, 2, + 6, 13, 3, 10, + 7, 14, 11, 15, +}; + +const int16_t ff_vp9_default_scan_8x8[64] = { + 0, 1, 8, 2, 9, 16, 10, 3, + 17, 24, 18, 11, 4, 25, 32, 19, + 12, 26, 5, 33, 20, 27, 40, 13, + 34, 6, 41, 28, 21, 35, 42, 48, + 14, 7, 36, 29, 43, 56, 49, 22, + 15, 37, 50, 44, 57, 30, 23, 51, + 45, 58, 38, 31, 52, 59, 39, 46, + 53, 60, 47, 54, 61, 55, 62, 63, +}; + +const int16_t ff_vp9_col_scan_8x8[64] = { + 0, 1, 2, 8, 3, 9, 4, 10, + 16, 5, 11, 17, 12, 18, 6, 24, + 19, 13, 25, 7, 26, 20, 32, 14, + 27, 21, 33, 28, 34, 15, 22, 35, + 40, 29, 41, 36, 23, 30, 42, 37, + 48, 43, 31, 44, 49, 38, 50, 56, + 45, 39, 51, 57, 52, 46, 58, 53, + 59, 47, 60, 54, 61, 55, 62, 63, +}; + +const int16_t ff_vp9_row_scan_8x8[64] = { + 0, 8, 16, 1, 9, 24, 2, 17, + 32, 10, 25, 3, 40, 18, 11, 33, + 26, 19, 4, 48, 41, 34, 12, 27, + 56, 20, 5, 42, 35, 13, 49, 28, + 6, 21, 43, 36, 14, 50, 29, 57, + 7, 44, 22, 37, 51, 15, 58, 30, + 23, 45, 52, 38, 59, 31, 46, 53, + 39, 60, 47, 61, 54, 62, 55, 63, +}; + +const int16_t ff_vp9_default_scan_16x16[256] = { + 0, 1, 16, 2, 17, 32, 3, 18, 33, 48, 4, 34, 19, 49, 20, 5, + 35, 64, 50, 36, 65, 21, 6, 51, 80, 66, 37, 22, 52, 7, 81, 67, + 38, 82, 53, 23, 96, 68, 8, 83, 97, 54, 39, 69, 112, 24, 98, 84, + 70, 55, 9, 40, 85, 99, 113, 128, 25, 114, 100, 71, 86, 56, 10, 41, + 115, 101, 129, 116, 72, 87, 26, 130, 144, 102, 57, 11, 42, 117, 131, 145, + 88, 103, 27, 73, 132, 118, 146, 58, 160, 12, 43, 133, 147, 104, 89, 119, + 161, 74, 148, 134, 28, 162, 59, 13, 176, 120, 149, 90, 135, 105, 163, 44, + 75, 177, 164, 29, 150, 121, 136, 178, 165, 14, 106, 60, 91, 151, 45, 179, + 192, 137, 166, 122, 76, 180, 152, 30, 61, 15, 107, 167, 181, 193, 92, 208, + 46, 138, 123, 153, 194, 77, 168, 182, 31, 195, 209, 183, 108, 139, 62, 154, + 47, 196, 93, 169, 210, 197, 224, 124, 184, 211, 78, 109, 170, 155, 63, 198, + 212, 185, 225, 240, 140, 94, 199, 125, 79, 213, 226, 171, 186, 156, 214, 200, + 110, 227, 141, 95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216, + 243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232, + 189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191, + 235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255, +}; + +const int16_t ff_vp9_col_scan_16x16[256] = { + 0, 1, 2, 3, 16, 4, 17, 5, 18, 6, 19, 32, 20, 7, 33, 21, + 34, 8, 35, 22, 48, 36, 9, 49, 23, 50, 37, 10, 38, 51, 24, 64, + 52, 11, 65, 39, 25, 53, 66, 54, 40, 67, 12, 80, 26, 68, 55, 81, + 41, 69, 13, 27, 82, 56, 70, 83, 42, 14, 84, 96, 71, 28, 57, 85, + 97, 15, 72, 98, 43, 86, 58, 99, 29, 87, 100, 112, 73, 44, 101, 59, + 30, 113, 88, 114, 74, 128, 102, 45, 31, 115, 60, 103, 89, 116, 75, 129, + 117, 46, 104, 90, 61, 130, 118, 131, 132, 105, 76, 47, 119, 144, 91, 62, + 133, 106, 145, 120, 146, 134, 77, 147, 121, 92, 135, 148, 63, 107, 136, 122, + 93, 149, 160, 78, 150, 137, 108, 161, 162, 151, 123, 79, 138, 163, 152, 94, + 164, 109, 165, 153, 124, 139, 176, 166, 95, 177, 167, 110, 154, 178, 125, 179, + 140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170, + 195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172, + 158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215, + 227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244, + 231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206, + 249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255, +}; + +const int16_t ff_vp9_row_scan_16x16[256] = { + 0, 16, 32, 1, 48, 17, 64, 33, 2, 80, 18, 49, 96, 34, 3, 65, + 19, 112, 50, 81, 35, 4, 128, 66, 20, 97, 51, 82, 5, 144, 36, 67, + 113, 98, 21, 52, 160, 83, 129, 37, 68, 6, 114, 176, 99, 53, 22, 84, + 145, 38, 69, 130, 7, 115, 192, 100, 54, 23, 85, 161, 146, 131, 39, 70, + 208, 116, 8, 101, 177, 55, 86, 24, 162, 147, 132, 71, 224, 117, 40, 102, + 9, 148, 56, 87, 193, 163, 240, 133, 178, 25, 118, 72, 41, 103, 164, 10, + 149, 88, 134, 209, 179, 57, 119, 194, 26, 73, 165, 150, 104, 42, 135, 11, + 180, 120, 89, 225, 195, 58, 27, 210, 151, 181, 166, 74, 43, 105, 12, 136, + 90, 59, 241, 121, 28, 196, 167, 211, 152, 44, 182, 137, 75, 13, 226, 106, + 122, 60, 197, 91, 168, 29, 183, 153, 14, 76, 212, 138, 45, 107, 15, 198, + 92, 227, 169, 30, 123, 154, 61, 242, 184, 213, 139, 46, 77, 31, 108, 170, + 199, 185, 124, 228, 93, 155, 214, 62, 140, 243, 78, 47, 200, 109, 186, 171, + 201, 94, 63, 215, 229, 156, 79, 125, 141, 110, 216, 187, 172, 244, 202, 230, + 217, 95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233, + 203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250, + 235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255, +}; + +const int16_t ff_vp9_default_scan_32x32[1024] = { + 0, 1, 32, 2, 33, 64, 3, 34, 65, 4, 96, 35, 66, 5, 36, 97, 67, 128, 98, 68, 37, 6, 129, 99, 7, 160, 69, 38, 130, 100, 161, 131, + 39, 70, 8, 101, 162, 132, 192, 71, 40, 9, 102, 163, 133, 193, 72, 224, 103, 41, 164, 10, 194, 134, 165, 73, 104, 135, 225, 42, 195, 11, 256, 166, + 226, 196, 74, 105, 136, 43, 12, 167, 197, 227, 257, 75, 106, 137, 228, 44, 198, 168, 258, 288, 13, 229, 76, 107, 199, 138, 259, 169, 289, 45, 230, 260, + 200, 108, 14, 170, 139, 320, 290, 77, 231, 261, 46, 201, 140, 291, 109, 232, 321, 262, 171, 78, 292, 15, 322, 202, 263, 352, 172, 293, 233, 141, 323, 110, + 47, 203, 264, 234, 294, 353, 324, 16, 79, 204, 265, 295, 325, 173, 354, 142, 235, 384, 48, 296, 111, 266, 355, 326, 80, 17, 205, 236, 174, 356, 385, 327, + 143, 297, 267, 357, 386, 112, 49, 328, 298, 206, 416, 237, 358, 387, 81, 175, 18, 329, 359, 388, 299, 330, 389, 113, 417, 238, 360, 50, 207, 418, 390, 331, + 19, 448, 361, 82, 419, 391, 239, 51, 362, 420, 114, 449, 480, 421, 83, 363, 450, 422, 512, 451, 423, 115, 452, 481, 453, 482, 454, 544, 483, 455, 513, 484, + 514, 485, 515, 486, 545, 576, 487, 546, 547, 608, 577, 578, 579, 609, 610, 611, 20, 144, 268, 392, 516, 640, 21, 52, 145, 176, 269, 300, 393, 424, 517, 548, + 641, 672, 22, 53, 84, 146, 177, 208, 270, 301, 332, 394, 425, 456, 518, 549, 580, 642, 673, 704, 23, 54, 85, 116, 147, 178, 209, 240, 271, 302, 333, 364, + 395, 426, 457, 488, 519, 550, 581, 612, 643, 674, 705, 736, 55, 86, 117, 179, 210, 241, 303, 334, 365, 427, 458, 489, 551, 582, 613, 675, 706, 737, 87, 118, + 211, 242, 335, 366, 459, 490, 583, 614, 707, 738, 119, 243, 367, 491, 615, 739, 24, 148, 272, 396, 520, 644, 768, 25, 56, 149, 180, 273, 304, 397, 428, 521, + 552, 645, 676, 769, 800, 26, 57, 88, 150, 181, 212, 274, 305, 336, 398, 429, 460, 522, 553, 584, 646, 677, 708, 770, 801, 832, 27, 58, 89, 120, 151, 182, + 213, 244, 275, 306, 337, 368, 399, 430, 461, 492, 523, 554, 585, 616, 647, 678, 709, 740, 771, 802, 833, 864, 59, 90, 121, 183, 214, 245, 307, 338, 369, 431, + 462, 493, 555, 586, 617, 679, 710, 741, 803, 834, 865, 91, 122, 215, 246, 339, 370, 463, 494, 587, 618, 711, 742, 835, 866, 123, 247, 371, 495, 619, 743, 867, + 28, 152, 276, 400, 524, 648, 772, 896, 29, 60, 153, 184, 277, 308, 401, 432, 525, 556, 649, 680, 773, 804, 897, 928, 30, 61, 92, 154, 185, 216, 278, 309, + 340, 402, 433, 464, 526, 557, 588, 650, 681, 712, 774, 805, 836, 898, 929, 960, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, + 527, 558, 589, 620, 651, 682, 713, 744, 775, 806, 837, 868, 899, 930, 961, 992, 63, 94, 125, 187, 218, 249, 311, 342, 373, 435, 466, 497, 559, 590, 621, 683, + 714, 745, 807, 838, 869, 931, 962, 993, 95, 126, 219, 250, 343, 374, 467, 498, 591, 622, 715, 746, 839, 870, 963, 994, 127, 251, 375, 499, 623, 747, 871, 995, + 156, 280, 404, 528, 652, 776, 900, 157, 188, 281, 312, 405, 436, 529, 560, 653, 684, 777, 808, 901, 932, 158, 189, 220, 282, 313, 344, 406, 437, 468, 530, 561, + 592, 654, 685, 716, 778, 809, 840, 902, 933, 964, 159, 190, 221, 252, 283, 314, 345, 376, 407, 438, 469, 500, 531, 562, 593, 624, 655, 686, 717, 748, 779, 810, + 841, 872, 903, 934, 965, 996, 191, 222, 253, 315, 346, 377, 439, 470, 501, 563, 594, 625, 687, 718, 749, 811, 842, 873, 935, 966, 997, 223, 254, 347, 378, 471, + 502, 595, 626, 719, 750, 843, 874, 967, 998, 255, 379, 503, 627, 751, 875, 999, 284, 408, 532, 656, 780, 904, 285, 316, 409, 440, 533, 564, 657, 688, 781, 812, + 905, 936, 286, 317, 348, 410, 441, 472, 534, 565, 596, 658, 689, 720, 782, 813, 844, 906, 937, 968, 287, 318, 349, 380, 411, 442, 473, 504, 535, 566, 597, 628, + 659, 690, 721, 752, 783, 814, 845, 876, 907, 938, 969, 1000, 319, 350, 381, 443, 474, 505, 567, 598, 629, 691, 722, 753, 815, 846, 877, 939, 970, 1001, 351, 382, + 475, 506, 599, 630, 723, 754, 847, 878, 971, 1002, 383, 507, 631, 755, 879, 1003, 412, 536, 660, 784, 908, 413, 444, 537, 568, 661, 692, 785, 816, 909, 940, 414, + 445, 476, 538, 569, 600, 662, 693, 724, 786, 817, 848, 910, 941, 972, 415, 446, 477, 508, 539, 570, 601, 632, 663, 694, 725, 756, 787, 818, 849, 880, 911, 942, + 973, 1004, 447, 478, 509, 571, 602, 633, 695, 726, 757, 819, 850, 881, 943, 974, 1005, 479, 510, 603, 634, 727, 758, 851, 882, 975, 1006, 511, 635, 759, 883, 1007, + 540, 664, 788, 912, 541, 572, 665, 696, 789, 820, 913, 944, 542, 573, 604, 666, 697, 728, 790, 821, 852, 914, 945, 976, 543, 574, 605, 636, 667, 698, 729, 760, + 791, 822, 853, 884, 915, 946, 977, 1008, 575, 606, 637, 699, 730, 761, 823, 854, 885, 947, 978, 1009, 607, 638, 731, 762, 855, 886, 979, 1010, 639, 763, 887, 1011, + 668, 792, 916, 669, 700, 793, 824, 917, 948, 670, 701, 732, 794, 825, 856, 918, 949, 980, 671, 702, 733, 764, 795, 826, 857, 888, 919, 950, 981, 1012, 703, 734, + 765, 827, 858, 889, 951, 982, 1013, 735, 766, 859, 890, 983, 1014, 767, 891, 1015, 796, 920, 797, 828, 921, 952, 798, 829, 860, 922, 953, 984, 799, 830, 861, 892, + 923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, +}; + +const int16_t * const ff_vp9_scans[5][4] = { + { + ff_vp9_default_scan_4x4, ff_vp9_col_scan_4x4, + ff_vp9_row_scan_4x4, ff_vp9_default_scan_4x4 + }, { + ff_vp9_default_scan_8x8, ff_vp9_col_scan_8x8, + ff_vp9_row_scan_8x8, ff_vp9_default_scan_8x8 + }, { + ff_vp9_default_scan_16x16, ff_vp9_col_scan_16x16, + ff_vp9_row_scan_16x16, ff_vp9_default_scan_16x16 + }, { + ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32, + ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32 + }, { // lossless + ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4, + ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4 + } +}; + +const int16_t ff_vp9_default_scan_4x4_nb[16][2] = { + { 0, 0 }, { 0, 0 }, { 4, 1 }, { 1, 1 }, + { 4, 4 }, { 2, 2 }, { 5, 2 }, { 8, 8 }, + { 8, 5 }, { 6, 3 }, { 9, 6 }, { 12, 9 }, + { 10, 7 }, { 13, 10 }, { 14, 11 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_4x4_nb[16][2] = { + { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, + { 4, 4 }, { 5, 5 }, { 4, 4 }, { 6, 6 }, + { 8, 8 }, { 9, 9 }, { 8, 8 }, { 12, 12 }, + { 10, 10 }, { 13, 13 }, { 14, 14 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_4x4_nb[16][2] = { + { 0, 0 }, { 0, 0 }, { 4, 4 }, { 1, 1 }, + { 8, 8 }, { 5, 5 }, { 1, 1 }, { 2, 2 }, + { 9, 9 }, { 2, 2 }, { 6, 6 }, { 3, 3 }, + { 10, 10 }, { 7, 7 }, { 11, 11 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_8x8_nb[64][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 8, 1 }, + { 8, 8 }, { 9, 2 }, { 2, 2 }, { 16, 9 }, + { 16, 16 }, { 17, 10 }, { 10, 3 }, { 3, 3 }, + { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11, 4 }, + { 25, 18 }, { 4, 4 }, { 32, 25 }, { 19, 12 }, + { 26, 19 }, { 32, 32 }, { 12, 5 }, { 33, 26 }, + { 5, 5 }, { 40, 33 }, { 27, 20 }, { 20, 13 }, + { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13, 6 }, + { 6, 6 }, { 35, 28 }, { 28, 21 }, { 42, 35 }, + { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14, 7 }, + { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 }, + { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 }, + { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 }, + { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 }, + { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 }, + { 54, 47 }, { 61, 54 }, { 62, 55 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_8x8_nb[64][2] = { + { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, + { 8, 8 }, { 3, 3 }, { 9, 9 }, { 8, 8 }, + { 4, 4 }, { 10, 10 }, { 16, 16 }, { 11, 11 }, + { 17, 17 }, { 5, 5 }, { 16, 16 }, { 18, 18 }, + { 12, 12 }, { 24, 24 }, { 6, 6 }, { 25, 25 }, + { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 }, + { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 }, + { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 }, + { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 }, + { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 }, + { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 }, + { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 }, + { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 }, + { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 }, + { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 }, + { 54, 54 }, { 61, 61 }, { 62, 62 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_8x8_nb[64][2] = { + { 0, 0 }, { 8, 8 }, { 0, 0 }, { 1, 1 }, + { 16, 16 }, { 1, 1 }, { 9, 9 }, { 24, 24 }, + { 2, 2 }, { 17, 17 }, { 2, 2 }, { 32, 32 }, + { 10, 10 }, { 3, 3 }, { 25, 25 }, { 18, 18 }, + { 11, 11 }, { 3, 3 }, { 40, 40 }, { 33, 33 }, + { 26, 26 }, { 4, 4 }, { 19, 19 }, { 48, 48 }, + { 12, 12 }, { 4, 4 }, { 34, 34 }, { 27, 27 }, + { 5, 5 }, { 41, 41 }, { 20, 20 }, { 5, 5 }, + { 13, 13 }, { 35, 35 }, { 28, 28 }, { 6, 6 }, + { 42, 42 }, { 21, 21 }, { 49, 49 }, { 6, 6 }, + { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 }, + { 7, 7 }, { 50, 50 }, { 22, 22 }, { 15, 15 }, + { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 }, + { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 }, + { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 }, + { 54, 54 }, { 47, 47 }, { 55, 55 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_16x16_nb[256][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 16, 1 }, + { 16, 16 }, { 2, 2 }, { 17, 2 }, { 32, 17 }, + { 32, 32 }, { 3, 3 }, { 33, 18 }, { 18, 3 }, + { 48, 33 }, { 19, 4 }, { 4, 4 }, { 34, 19 }, + { 48, 48 }, { 49, 34 }, { 35, 20 }, { 64, 49 }, + { 20, 5 }, { 5, 5 }, { 50, 35 }, { 64, 64 }, + { 65, 50 }, { 36, 21 }, { 21, 6 }, { 51, 36 }, + { 6, 6 }, { 80, 65 }, { 66, 51 }, { 37, 22 }, + { 81, 66 }, { 52, 37 }, { 22, 7 }, { 80, 80 }, + { 67, 52 }, { 7, 7 }, { 82, 67 }, { 96, 81 }, + { 53, 38 }, { 38, 23 }, { 68, 53 }, { 96, 96 }, + { 23, 8 }, { 97, 82 }, { 83, 68 }, { 69, 54 }, + { 54, 39 }, { 8, 8 }, { 39, 24 }, { 84, 69 }, + { 98, 83 }, { 112, 97 }, { 112, 112 }, { 24, 9 }, + { 113, 98 }, { 99, 84 }, { 70, 55 }, { 85, 70 }, + { 55, 40 }, { 9, 9 }, { 40, 25 }, { 114, 99 }, + { 100, 85 }, { 128, 113 }, { 115, 100 }, { 71, 56 }, + { 86, 71 }, { 25, 10 }, { 129, 114 }, { 128, 128 }, + { 101, 86 }, { 56, 41 }, { 10, 10 }, { 41, 26 }, + { 116, 101 }, { 130, 115 }, { 144, 129 }, { 87, 72 }, + { 102, 87 }, { 26, 11 }, { 72, 57 }, { 131, 116 }, + { 117, 102 }, { 145, 130 }, { 57, 42 }, { 144, 144 }, + { 11, 11 }, { 42, 27 }, { 132, 117 }, { 146, 131 }, + { 103, 88 }, { 88, 73 }, { 118, 103 }, { 160, 145 }, + { 73, 58 }, { 147, 132 }, { 133, 118 }, { 27, 12 }, + { 161, 146 }, { 58, 43 }, { 12, 12 }, { 160, 160 }, + { 119, 104 }, { 148, 133 }, { 89, 74 }, { 134, 119 }, + { 104, 89 }, { 162, 147 }, { 43, 28 }, { 74, 59 }, + { 176, 161 }, { 163, 148 }, { 28, 13 }, { 149, 134 }, + { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 }, + { 13, 13 }, { 105, 90 }, { 59, 44 }, { 90, 75 }, + { 150, 135 }, { 44, 29 }, { 178, 163 }, { 176, 176 }, + { 136, 121 }, { 165, 150 }, { 121, 106 }, { 75, 60 }, + { 179, 164 }, { 151, 136 }, { 29, 14 }, { 60, 45 }, + { 14, 14 }, { 106, 91 }, { 166, 151 }, { 180, 165 }, + { 192, 177 }, { 91, 76 }, { 192, 192 }, { 45, 30 }, + { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 }, + { 76, 61 }, { 167, 152 }, { 181, 166 }, { 30, 15 }, + { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107, 92 }, + { 138, 123 }, { 61, 46 }, { 153, 138 }, { 46, 31 }, + { 195, 180 }, { 92, 77 }, { 168, 153 }, { 209, 194 }, + { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 }, + { 210, 195 }, { 77, 62 }, { 108, 93 }, { 169, 154 }, + { 154, 139 }, { 62, 47 }, { 197, 182 }, { 211, 196 }, + { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 }, + { 93, 78 }, { 198, 183 }, { 124, 109 }, { 78, 63 }, + { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 }, + { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109, 94 }, + { 226, 211 }, { 140, 125 }, { 94, 79 }, { 240, 225 }, + { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 }, + { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 }, + { 228, 213 }, { 110, 95 }, { 215, 200 }, { 242, 227 }, + { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 }, + { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 }, + { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 }, + { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 }, + { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 }, + { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 }, + { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 }, + { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 }, + { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 }, + { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 }, + { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 }, + { 238, 223 }, { 253, 238 }, { 254, 239 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_16x16_nb[256][2] = { + { 0, 0 }, { 1, 1 }, { 2, 2 }, { 0, 0 }, + { 3, 3 }, { 16, 16 }, { 4, 4 }, { 17, 17 }, + { 5, 5 }, { 18, 18 }, { 16, 16 }, { 19, 19 }, + { 6, 6 }, { 32, 32 }, { 20, 20 }, { 33, 33 }, + { 7, 7 }, { 34, 34 }, { 21, 21 }, { 32, 32 }, + { 35, 35 }, { 8, 8 }, { 48, 48 }, { 22, 22 }, + { 49, 49 }, { 36, 36 }, { 9, 9 }, { 37, 37 }, + { 50, 50 }, { 23, 23 }, { 48, 48 }, { 51, 51 }, + { 10, 10 }, { 64, 64 }, { 38, 38 }, { 24, 24 }, + { 52, 52 }, { 65, 65 }, { 53, 53 }, { 39, 39 }, + { 66, 66 }, { 11, 11 }, { 64, 64 }, { 25, 25 }, + { 67, 67 }, { 54, 54 }, { 80, 80 }, { 40, 40 }, + { 68, 68 }, { 12, 12 }, { 26, 26 }, { 81, 81 }, + { 55, 55 }, { 69, 69 }, { 82, 82 }, { 41, 41 }, + { 13, 13 }, { 83, 83 }, { 80, 80 }, { 70, 70 }, + { 27, 27 }, { 56, 56 }, { 84, 84 }, { 96, 96 }, + { 14, 14 }, { 71, 71 }, { 97, 97 }, { 42, 42 }, + { 85, 85 }, { 57, 57 }, { 98, 98 }, { 28, 28 }, + { 86, 86 }, { 99, 99 }, { 96, 96 }, { 72, 72 }, + { 43, 43 }, { 100, 100 }, { 58, 58 }, { 29, 29 }, + { 112, 112 }, { 87, 87 }, { 113, 113 }, { 73, 73 }, + { 112, 112 }, { 101, 101 }, { 44, 44 }, { 30, 30 }, + { 114, 114 }, { 59, 59 }, { 102, 102 }, { 88, 88 }, + { 115, 115 }, { 74, 74 }, { 128, 128 }, { 116, 116 }, + { 45, 45 }, { 103, 103 }, { 89, 89 }, { 60, 60 }, + { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 }, + { 104, 104 }, { 75, 75 }, { 46, 46 }, { 118, 118 }, + { 128, 128 }, { 90, 90 }, { 61, 61 }, { 132, 132 }, + { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 }, + { 133, 133 }, { 76, 76 }, { 146, 146 }, { 120, 120 }, + { 91, 91 }, { 134, 134 }, { 147, 147 }, { 62, 62 }, + { 106, 106 }, { 135, 135 }, { 121, 121 }, { 92, 92 }, + { 148, 148 }, { 144, 144 }, { 77, 77 }, { 149, 149 }, + { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 }, + { 150, 150 }, { 122, 122 }, { 78, 78 }, { 137, 137 }, + { 162, 162 }, { 151, 151 }, { 93, 93 }, { 163, 163 }, + { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 }, + { 138, 138 }, { 160, 160 }, { 165, 165 }, { 94, 94 }, + { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 }, + { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 }, + { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 }, + { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 }, + { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 }, + { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 }, + { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 }, + { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 }, + { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 }, + { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 }, + { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 }, + { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 }, + { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 }, + { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 }, + { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 }, + { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 }, + { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 }, + { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 }, + { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 }, + { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 }, + { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 }, + { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 }, + { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 }, + { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 }, + { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 }, + { 252, 252 }, { 253, 253 }, { 254, 254 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_16x16_nb[256][2] = { + { 0, 0 }, { 16, 16 }, { 0, 0 }, { 32, 32 }, + { 1, 1 }, { 48, 48 }, { 17, 17 }, { 1, 1 }, + { 64, 64 }, { 2, 2 }, { 33, 33 }, { 80, 80 }, + { 18, 18 }, { 2, 2 }, { 49, 49 }, { 3, 3 }, + { 96, 96 }, { 34, 34 }, { 65, 65 }, { 19, 19 }, + { 3, 3 }, { 112, 112 }, { 50, 50 }, { 4, 4 }, + { 81, 81 }, { 35, 35 }, { 66, 66 }, { 4, 4 }, + { 128, 128 }, { 20, 20 }, { 51, 51 }, { 97, 97 }, + { 82, 82 }, { 5, 5 }, { 36, 36 }, { 144, 144 }, + { 67, 67 }, { 113, 113 }, { 21, 21 }, { 52, 52 }, + { 5, 5 }, { 98, 98 }, { 160, 160 }, { 83, 83 }, + { 37, 37 }, { 6, 6 }, { 68, 68 }, { 129, 129 }, + { 22, 22 }, { 53, 53 }, { 114, 114 }, { 6, 6 }, + { 99, 99 }, { 176, 176 }, { 84, 84 }, { 38, 38 }, + { 7, 7 }, { 69, 69 }, { 145, 145 }, { 130, 130 }, + { 115, 115 }, { 23, 23 }, { 54, 54 }, { 192, 192 }, + { 100, 100 }, { 7, 7 }, { 85, 85 }, { 161, 161 }, + { 39, 39 }, { 70, 70 }, { 8, 8 }, { 146, 146 }, + { 131, 131 }, { 116, 116 }, { 55, 55 }, { 208, 208 }, + { 101, 101 }, { 24, 24 }, { 86, 86 }, { 8, 8 }, + { 132, 132 }, { 40, 40 }, { 71, 71 }, { 177, 177 }, + { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 }, + { 9, 9 }, { 102, 102 }, { 56, 56 }, { 25, 25 }, + { 87, 87 }, { 148, 148 }, { 9, 9 }, { 133, 133 }, + { 72, 72 }, { 118, 118 }, { 193, 193 }, { 163, 163 }, + { 41, 41 }, { 103, 103 }, { 178, 178 }, { 10, 10 }, + { 57, 57 }, { 149, 149 }, { 134, 134 }, { 88, 88 }, + { 26, 26 }, { 119, 119 }, { 10, 10 }, { 164, 164 }, + { 104, 104 }, { 73, 73 }, { 209, 209 }, { 179, 179 }, + { 42, 42 }, { 11, 11 }, { 194, 194 }, { 135, 135 }, + { 165, 165 }, { 150, 150 }, { 58, 58 }, { 27, 27 }, + { 89, 89 }, { 11, 11 }, { 120, 120 }, { 74, 74 }, + { 43, 43 }, { 225, 225 }, { 105, 105 }, { 12, 12 }, + { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 }, + { 28, 28 }, { 166, 166 }, { 121, 121 }, { 59, 59 }, + { 12, 12 }, { 210, 210 }, { 90, 90 }, { 106, 106 }, + { 44, 44 }, { 181, 181 }, { 75, 75 }, { 152, 152 }, + { 13, 13 }, { 167, 167 }, { 137, 137 }, { 13, 13 }, + { 60, 60 }, { 196, 196 }, { 122, 122 }, { 29, 29 }, + { 91, 91 }, { 14, 14 }, { 182, 182 }, { 76, 76 }, + { 211, 211 }, { 153, 153 }, { 14, 14 }, { 107, 107 }, + { 138, 138 }, { 45, 45 }, { 226, 226 }, { 168, 168 }, + { 197, 197 }, { 123, 123 }, { 30, 30 }, { 61, 61 }, + { 15, 15 }, { 92, 92 }, { 154, 154 }, { 183, 183 }, + { 169, 169 }, { 108, 108 }, { 212, 212 }, { 77, 77 }, + { 139, 139 }, { 198, 198 }, { 46, 46 }, { 124, 124 }, + { 227, 227 }, { 62, 62 }, { 31, 31 }, { 184, 184 }, + { 93, 93 }, { 170, 170 }, { 155, 155 }, { 185, 185 }, + { 78, 78 }, { 47, 47 }, { 199, 199 }, { 213, 213 }, + { 140, 140 }, { 63, 63 }, { 109, 109 }, { 125, 125 }, + { 94, 94 }, { 200, 200 }, { 171, 171 }, { 156, 156 }, + { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 }, + { 79, 79 }, { 141, 141 }, { 110, 110 }, { 229, 229 }, + { 95, 95 }, { 126, 126 }, { 215, 215 }, { 172, 172 }, + { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 }, + { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 }, + { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 }, + { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 }, + { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 }, + { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 }, + { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 }, + { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 }, + { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 }, + { 238, 238 }, { 223, 223 }, { 239, 239 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_32x32_nb[1024][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 32, 1 }, + { 32, 32 }, { 2, 2 }, { 33, 2 }, { 64, 33 }, + { 3, 3 }, { 64, 64 }, { 34, 3 }, { 65, 34 }, + { 4, 4 }, { 35, 4 }, { 96, 65 }, { 66, 35 }, + { 96, 96 }, { 97, 66 }, { 67, 36 }, { 36, 5 }, + { 5, 5 }, { 128, 97 }, { 98, 67 }, { 6, 6 }, + { 128, 128 }, { 68, 37 }, { 37, 6 }, { 129, 98 }, + { 99, 68 }, { 160, 129 }, { 130, 99 }, { 38, 7 }, + { 69, 38 }, { 7, 7 }, { 100, 69 }, { 161, 130 }, + { 131, 100 }, { 160, 160 }, { 70, 39 }, { 39, 8 }, + { 8, 8 }, { 101, 70 }, { 162, 131 }, { 132, 101 }, + { 192, 161 }, { 71, 40 }, { 192, 192 }, { 102, 71 }, + { 40, 9 }, { 163, 132 }, { 9, 9 }, { 193, 162 }, + { 133, 102 }, { 164, 133 }, { 72, 41 }, { 103, 72 }, + { 134, 103 }, { 224, 193 }, { 41, 10 }, { 194, 163 }, + { 10, 10 }, { 224, 224 }, { 165, 134 }, { 225, 194 }, + { 195, 164 }, { 73, 42 }, { 104, 73 }, { 135, 104 }, + { 42, 11 }, { 11, 11 }, { 166, 135 }, { 196, 165 }, + { 226, 195 }, { 256, 225 }, { 74, 43 }, { 105, 74 }, + { 136, 105 }, { 227, 196 }, { 43, 12 }, { 197, 166 }, + { 167, 136 }, { 257, 226 }, { 256, 256 }, { 12, 12 }, + { 228, 197 }, { 75, 44 }, { 106, 75 }, { 198, 167 }, + { 137, 106 }, { 258, 227 }, { 168, 137 }, { 288, 257 }, + { 44, 13 }, { 229, 198 }, { 259, 228 }, { 199, 168 }, + { 107, 76 }, { 13, 13 }, { 169, 138 }, { 138, 107 }, + { 288, 288 }, { 289, 258 }, { 76, 45 }, { 230, 199 }, + { 260, 229 }, { 45, 14 }, { 200, 169 }, { 139, 108 }, + { 290, 259 }, { 108, 77 }, { 231, 200 }, { 320, 289 }, + { 261, 230 }, { 170, 139 }, { 77, 46 }, { 291, 260 }, + { 14, 14 }, { 321, 290 }, { 201, 170 }, { 262, 231 }, + { 320, 320 }, { 171, 140 }, { 292, 261 }, { 232, 201 }, + { 140, 109 }, { 322, 291 }, { 109, 78 }, { 46, 15 }, + { 202, 171 }, { 263, 232 }, { 233, 202 }, { 293, 262 }, + { 352, 321 }, { 323, 292 }, { 15, 15 }, { 78, 47 }, + { 203, 172 }, { 264, 233 }, { 294, 263 }, { 324, 293 }, + { 172, 141 }, { 353, 322 }, { 141, 110 }, { 234, 203 }, + { 352, 352 }, { 47, 16 }, { 295, 264 }, { 110, 79 }, + { 265, 234 }, { 354, 323 }, { 325, 294 }, { 79, 48 }, + { 16, 16 }, { 204, 173 }, { 235, 204 }, { 173, 142 }, + { 355, 324 }, { 384, 353 }, { 326, 295 }, { 142, 111 }, + { 296, 265 }, { 266, 235 }, { 356, 325 }, { 385, 354 }, + { 111, 80 }, { 48, 17 }, { 327, 296 }, { 297, 266 }, + { 205, 174 }, { 384, 384 }, { 236, 205 }, { 357, 326 }, + { 386, 355 }, { 80, 49 }, { 174, 143 }, { 17, 17 }, + { 328, 297 }, { 358, 327 }, { 387, 356 }, { 298, 267 }, + { 329, 298 }, { 388, 357 }, { 112, 81 }, { 416, 385 }, + { 237, 206 }, { 359, 328 }, { 49, 18 }, { 206, 175 }, + { 417, 386 }, { 389, 358 }, { 330, 299 }, { 18, 18 }, + { 416, 416 }, { 360, 329 }, { 81, 50 }, { 418, 387 }, + { 390, 359 }, { 238, 207 }, { 50, 19 }, { 361, 330 }, + { 419, 388 }, { 113, 82 }, { 448, 417 }, { 448, 448 }, + { 420, 389 }, { 82, 51 }, { 362, 331 }, { 449, 418 }, + { 421, 390 }, { 480, 480 }, { 450, 419 }, { 422, 391 }, + { 114, 83 }, { 451, 420 }, { 480, 449 }, { 452, 421 }, + { 481, 450 }, { 453, 422 }, { 512, 512 }, { 482, 451 }, + { 454, 423 }, { 512, 481 }, { 483, 452 }, { 513, 482 }, + { 484, 453 }, { 514, 483 }, { 485, 454 }, { 544, 513 }, + { 544, 544 }, { 486, 455 }, { 545, 514 }, { 546, 515 }, + { 576, 576 }, { 576, 545 }, { 577, 546 }, { 578, 547 }, + { 608, 577 }, { 609, 578 }, { 610, 579 }, { 19, 19 }, + { 143, 112 }, { 267, 236 }, { 391, 360 }, { 515, 484 }, + { 608, 608 }, { 20, 20 }, { 51, 20 }, { 144, 113 }, + { 175, 144 }, { 268, 237 }, { 299, 268 }, { 392, 361 }, + { 423, 392 }, { 516, 485 }, { 547, 516 }, { 640, 609 }, + { 640, 640 }, { 21, 21 }, { 52, 21 }, { 83, 52 }, + { 145, 114 }, { 176, 145 }, { 207, 176 }, { 269, 238 }, + { 300, 269 }, { 331, 300 }, { 393, 362 }, { 424, 393 }, + { 455, 424 }, { 517, 486 }, { 548, 517 }, { 579, 548 }, + { 641, 610 }, { 672, 641 }, { 672, 672 }, { 22, 22 }, + { 53, 22 }, { 84, 53 }, { 115, 84 }, { 146, 115 }, + { 177, 146 }, { 208, 177 }, { 239, 208 }, { 270, 239 }, + { 301, 270 }, { 332, 301 }, { 363, 332 }, { 394, 363 }, + { 425, 394 }, { 456, 425 }, { 487, 456 }, { 518, 487 }, + { 549, 518 }, { 580, 549 }, { 611, 580 }, { 642, 611 }, + { 673, 642 }, { 704, 673 }, { 704, 704 }, { 54, 23 }, + { 85, 54 }, { 116, 85 }, { 178, 147 }, { 209, 178 }, + { 240, 209 }, { 302, 271 }, { 333, 302 }, { 364, 333 }, + { 426, 395 }, { 457, 426 }, { 488, 457 }, { 550, 519 }, + { 581, 550 }, { 612, 581 }, { 674, 643 }, { 705, 674 }, + { 736, 705 }, { 86, 55 }, { 117, 86 }, { 210, 179 }, + { 241, 210 }, { 334, 303 }, { 365, 334 }, { 458, 427 }, + { 489, 458 }, { 582, 551 }, { 613, 582 }, { 706, 675 }, + { 737, 706 }, { 118, 87 }, { 242, 211 }, { 366, 335 }, + { 490, 459 }, { 614, 583 }, { 738, 707 }, { 23, 23 }, + { 147, 116 }, { 271, 240 }, { 395, 364 }, { 519, 488 }, + { 643, 612 }, { 736, 736 }, { 24, 24 }, { 55, 24 }, + { 148, 117 }, { 179, 148 }, { 272, 241 }, { 303, 272 }, + { 396, 365 }, { 427, 396 }, { 520, 489 }, { 551, 520 }, + { 644, 613 }, { 675, 644 }, { 768, 737 }, { 768, 768 }, + { 25, 25 }, { 56, 25 }, { 87, 56 }, { 149, 118 }, + { 180, 149 }, { 211, 180 }, { 273, 242 }, { 304, 273 }, + { 335, 304 }, { 397, 366 }, { 428, 397 }, { 459, 428 }, + { 521, 490 }, { 552, 521 }, { 583, 552 }, { 645, 614 }, + { 676, 645 }, { 707, 676 }, { 769, 738 }, { 800, 769 }, + { 800, 800 }, { 26, 26 }, { 57, 26 }, { 88, 57 }, + { 119, 88 }, { 150, 119 }, { 181, 150 }, { 212, 181 }, + { 243, 212 }, { 274, 243 }, { 305, 274 }, { 336, 305 }, + { 367, 336 }, { 398, 367 }, { 429, 398 }, { 460, 429 }, + { 491, 460 }, { 522, 491 }, { 553, 522 }, { 584, 553 }, + { 615, 584 }, { 646, 615 }, { 677, 646 }, { 708, 677 }, + { 739, 708 }, { 770, 739 }, { 801, 770 }, { 832, 801 }, + { 832, 832 }, { 58, 27 }, { 89, 58 }, { 120, 89 }, + { 182, 151 }, { 213, 182 }, { 244, 213 }, { 306, 275 }, + { 337, 306 }, { 368, 337 }, { 430, 399 }, { 461, 430 }, + { 492, 461 }, { 554, 523 }, { 585, 554 }, { 616, 585 }, + { 678, 647 }, { 709, 678 }, { 740, 709 }, { 802, 771 }, + { 833, 802 }, { 864, 833 }, { 90, 59 }, { 121, 90 }, + { 214, 183 }, { 245, 214 }, { 338, 307 }, { 369, 338 }, + { 462, 431 }, { 493, 462 }, { 586, 555 }, { 617, 586 }, + { 710, 679 }, { 741, 710 }, { 834, 803 }, { 865, 834 }, + { 122, 91 }, { 246, 215 }, { 370, 339 }, { 494, 463 }, + { 618, 587 }, { 742, 711 }, { 866, 835 }, { 27, 27 }, + { 151, 120 }, { 275, 244 }, { 399, 368 }, { 523, 492 }, + { 647, 616 }, { 771, 740 }, { 864, 864 }, { 28, 28 }, + { 59, 28 }, { 152, 121 }, { 183, 152 }, { 276, 245 }, + { 307, 276 }, { 400, 369 }, { 431, 400 }, { 524, 493 }, + { 555, 524 }, { 648, 617 }, { 679, 648 }, { 772, 741 }, + { 803, 772 }, { 896, 865 }, { 896, 896 }, { 29, 29 }, + { 60, 29 }, { 91, 60 }, { 153, 122 }, { 184, 153 }, + { 215, 184 }, { 277, 246 }, { 308, 277 }, { 339, 308 }, + { 401, 370 }, { 432, 401 }, { 463, 432 }, { 525, 494 }, + { 556, 525 }, { 587, 556 }, { 649, 618 }, { 680, 649 }, + { 711, 680 }, { 773, 742 }, { 804, 773 }, { 835, 804 }, + { 897, 866 }, { 928, 897 }, { 928, 928 }, { 30, 30 }, + { 61, 30 }, { 92, 61 }, { 123, 92 }, { 154, 123 }, + { 185, 154 }, { 216, 185 }, { 247, 216 }, { 278, 247 }, + { 309, 278 }, { 340, 309 }, { 371, 340 }, { 402, 371 }, + { 433, 402 }, { 464, 433 }, { 495, 464 }, { 526, 495 }, + { 557, 526 }, { 588, 557 }, { 619, 588 }, { 650, 619 }, + { 681, 650 }, { 712, 681 }, { 743, 712 }, { 774, 743 }, + { 805, 774 }, { 836, 805 }, { 867, 836 }, { 898, 867 }, + { 929, 898 }, { 960, 929 }, { 960, 960 }, { 62, 31 }, + { 93, 62 }, { 124, 93 }, { 186, 155 }, { 217, 186 }, + { 248, 217 }, { 310, 279 }, { 341, 310 }, { 372, 341 }, + { 434, 403 }, { 465, 434 }, { 496, 465 }, { 558, 527 }, + { 589, 558 }, { 620, 589 }, { 682, 651 }, { 713, 682 }, + { 744, 713 }, { 806, 775 }, { 837, 806 }, { 868, 837 }, + { 930, 899 }, { 961, 930 }, { 992, 961 }, { 94, 63 }, + { 125, 94 }, { 218, 187 }, { 249, 218 }, { 342, 311 }, + { 373, 342 }, { 466, 435 }, { 497, 466 }, { 590, 559 }, + { 621, 590 }, { 714, 683 }, { 745, 714 }, { 838, 807 }, + { 869, 838 }, { 962, 931 }, { 993, 962 }, { 126, 95 }, + { 250, 219 }, { 374, 343 }, { 498, 467 }, { 622, 591 }, + { 746, 715 }, { 870, 839 }, { 994, 963 }, { 155, 124 }, + { 279, 248 }, { 403, 372 }, { 527, 496 }, { 651, 620 }, + { 775, 744 }, { 899, 868 }, { 156, 125 }, { 187, 156 }, + { 280, 249 }, { 311, 280 }, { 404, 373 }, { 435, 404 }, + { 528, 497 }, { 559, 528 }, { 652, 621 }, { 683, 652 }, + { 776, 745 }, { 807, 776 }, { 900, 869 }, { 931, 900 }, + { 157, 126 }, { 188, 157 }, { 219, 188 }, { 281, 250 }, + { 312, 281 }, { 343, 312 }, { 405, 374 }, { 436, 405 }, + { 467, 436 }, { 529, 498 }, { 560, 529 }, { 591, 560 }, + { 653, 622 }, { 684, 653 }, { 715, 684 }, { 777, 746 }, + { 808, 777 }, { 839, 808 }, { 901, 870 }, { 932, 901 }, + { 963, 932 }, { 158, 127 }, { 189, 158 }, { 220, 189 }, + { 251, 220 }, { 282, 251 }, { 313, 282 }, { 344, 313 }, + { 375, 344 }, { 406, 375 }, { 437, 406 }, { 468, 437 }, + { 499, 468 }, { 530, 499 }, { 561, 530 }, { 592, 561 }, + { 623, 592 }, { 654, 623 }, { 685, 654 }, { 716, 685 }, + { 747, 716 }, { 778, 747 }, { 809, 778 }, { 840, 809 }, + { 871, 840 }, { 902, 871 }, { 933, 902 }, { 964, 933 }, + { 995, 964 }, { 190, 159 }, { 221, 190 }, { 252, 221 }, + { 314, 283 }, { 345, 314 }, { 376, 345 }, { 438, 407 }, + { 469, 438 }, { 500, 469 }, { 562, 531 }, { 593, 562 }, + { 624, 593 }, { 686, 655 }, { 717, 686 }, { 748, 717 }, + { 810, 779 }, { 841, 810 }, { 872, 841 }, { 934, 903 }, + { 965, 934 }, { 996, 965 }, { 222, 191 }, { 253, 222 }, + { 346, 315 }, { 377, 346 }, { 470, 439 }, { 501, 470 }, + { 594, 563 }, { 625, 594 }, { 718, 687 }, { 749, 718 }, + { 842, 811 }, { 873, 842 }, { 966, 935 }, { 997, 966 }, + { 254, 223 }, { 378, 347 }, { 502, 471 }, { 626, 595 }, + { 750, 719 }, { 874, 843 }, { 998, 967 }, { 283, 252 }, + { 407, 376 }, { 531, 500 }, { 655, 624 }, { 779, 748 }, + { 903, 872 }, { 284, 253 }, { 315, 284 }, { 408, 377 }, + { 439, 408 }, { 532, 501 }, { 563, 532 }, { 656, 625 }, + { 687, 656 }, { 780, 749 }, { 811, 780 }, { 904, 873 }, + { 935, 904 }, { 285, 254 }, { 316, 285 }, { 347, 316 }, + { 409, 378 }, { 440, 409 }, { 471, 440 }, { 533, 502 }, + { 564, 533 }, { 595, 564 }, { 657, 626 }, { 688, 657 }, + { 719, 688 }, { 781, 750 }, { 812, 781 }, { 843, 812 }, + { 905, 874 }, { 936, 905 }, { 967, 936 }, { 286, 255 }, + { 317, 286 }, { 348, 317 }, { 379, 348 }, { 410, 379 }, + { 441, 410 }, { 472, 441 }, { 503, 472 }, { 534, 503 }, + { 565, 534 }, { 596, 565 }, { 627, 596 }, { 658, 627 }, + { 689, 658 }, { 720, 689 }, { 751, 720 }, { 782, 751 }, + { 813, 782 }, { 844, 813 }, { 875, 844 }, { 906, 875 }, + { 937, 906 }, { 968, 937 }, { 999, 968 }, { 318, 287 }, + { 349, 318 }, { 380, 349 }, { 442, 411 }, { 473, 442 }, + { 504, 473 }, { 566, 535 }, { 597, 566 }, { 628, 597 }, + { 690, 659 }, { 721, 690 }, { 752, 721 }, { 814, 783 }, + { 845, 814 }, { 876, 845 }, { 938, 907 }, { 969, 938 }, + { 1000, 969 }, { 350, 319 }, { 381, 350 }, { 474, 443 }, + { 505, 474 }, { 598, 567 }, { 629, 598 }, { 722, 691 }, + { 753, 722 }, { 846, 815 }, { 877, 846 }, { 970, 939 }, + { 1001, 970 }, { 382, 351 }, { 506, 475 }, { 630, 599 }, + { 754, 723 }, { 878, 847 }, { 1002, 971 }, { 411, 380 }, + { 535, 504 }, { 659, 628 }, { 783, 752 }, { 907, 876 }, + { 412, 381 }, { 443, 412 }, { 536, 505 }, { 567, 536 }, + { 660, 629 }, { 691, 660 }, { 784, 753 }, { 815, 784 }, + { 908, 877 }, { 939, 908 }, { 413, 382 }, { 444, 413 }, + { 475, 444 }, { 537, 506 }, { 568, 537 }, { 599, 568 }, + { 661, 630 }, { 692, 661 }, { 723, 692 }, { 785, 754 }, + { 816, 785 }, { 847, 816 }, { 909, 878 }, { 940, 909 }, + { 971, 940 }, { 414, 383 }, { 445, 414 }, { 476, 445 }, + { 507, 476 }, { 538, 507 }, { 569, 538 }, { 600, 569 }, + { 631, 600 }, { 662, 631 }, { 693, 662 }, { 724, 693 }, + { 755, 724 }, { 786, 755 }, { 817, 786 }, { 848, 817 }, + { 879, 848 }, { 910, 879 }, { 941, 910 }, { 972, 941 }, + { 1003, 972 }, { 446, 415 }, { 477, 446 }, { 508, 477 }, + { 570, 539 }, { 601, 570 }, { 632, 601 }, { 694, 663 }, + { 725, 694 }, { 756, 725 }, { 818, 787 }, { 849, 818 }, + { 880, 849 }, { 942, 911 }, { 973, 942 }, { 1004, 973 }, + { 478, 447 }, { 509, 478 }, { 602, 571 }, { 633, 602 }, + { 726, 695 }, { 757, 726 }, { 850, 819 }, { 881, 850 }, + { 974, 943 }, { 1005, 974 }, { 510, 479 }, { 634, 603 }, + { 758, 727 }, { 882, 851 }, { 1006, 975 }, { 539, 508 }, + { 663, 632 }, { 787, 756 }, { 911, 880 }, { 540, 509 }, + { 571, 540 }, { 664, 633 }, { 695, 664 }, { 788, 757 }, + { 819, 788 }, { 912, 881 }, { 943, 912 }, { 541, 510 }, + { 572, 541 }, { 603, 572 }, { 665, 634 }, { 696, 665 }, + { 727, 696 }, { 789, 758 }, { 820, 789 }, { 851, 820 }, + { 913, 882 }, { 944, 913 }, { 975, 944 }, { 542, 511 }, + { 573, 542 }, { 604, 573 }, { 635, 604 }, { 666, 635 }, + { 697, 666 }, { 728, 697 }, { 759, 728 }, { 790, 759 }, + { 821, 790 }, { 852, 821 }, { 883, 852 }, { 914, 883 }, + { 945, 914 }, { 976, 945 }, { 1007, 976 }, { 574, 543 }, + { 605, 574 }, { 636, 605 }, { 698, 667 }, { 729, 698 }, + { 760, 729 }, { 822, 791 }, { 853, 822 }, { 884, 853 }, + { 946, 915 }, { 977, 946 }, { 1008, 977 }, { 606, 575 }, + { 637, 606 }, { 730, 699 }, { 761, 730 }, { 854, 823 }, + { 885, 854 }, { 978, 947 }, { 1009, 978 }, { 638, 607 }, + { 762, 731 }, { 886, 855 }, { 1010, 979 }, { 667, 636 }, + { 791, 760 }, { 915, 884 }, { 668, 637 }, { 699, 668 }, + { 792, 761 }, { 823, 792 }, { 916, 885 }, { 947, 916 }, + { 669, 638 }, { 700, 669 }, { 731, 700 }, { 793, 762 }, + { 824, 793 }, { 855, 824 }, { 917, 886 }, { 948, 917 }, + { 979, 948 }, { 670, 639 }, { 701, 670 }, { 732, 701 }, + { 763, 732 }, { 794, 763 }, { 825, 794 }, { 856, 825 }, + { 887, 856 }, { 918, 887 }, { 949, 918 }, { 980, 949 }, + { 1011, 980 }, { 702, 671 }, { 733, 702 }, { 764, 733 }, + { 826, 795 }, { 857, 826 }, { 888, 857 }, { 950, 919 }, + { 981, 950 }, { 1012, 981 }, { 734, 703 }, { 765, 734 }, + { 858, 827 }, { 889, 858 }, { 982, 951 }, { 1013, 982 }, + { 766, 735 }, { 890, 859 }, { 1014, 983 }, { 795, 764 }, + { 919, 888 }, { 796, 765 }, { 827, 796 }, { 920, 889 }, + { 951, 920 }, { 797, 766 }, { 828, 797 }, { 859, 828 }, + { 921, 890 }, { 952, 921 }, { 983, 952 }, { 798, 767 }, + { 829, 798 }, { 860, 829 }, { 891, 860 }, { 922, 891 }, + { 953, 922 }, { 984, 953 }, { 1015, 984 }, { 830, 799 }, + { 861, 830 }, { 892, 861 }, { 954, 923 }, { 985, 954 }, + { 1016, 985 }, { 862, 831 }, { 893, 862 }, { 986, 955 }, + { 1017, 986 }, { 894, 863 }, { 1018, 987 }, { 923, 892 }, + { 924, 893 }, { 955, 924 }, { 925, 894 }, { 956, 925 }, + { 987, 956 }, { 926, 895 }, { 957, 926 }, { 988, 957 }, + { 1019, 988 }, { 958, 927 }, { 989, 958 }, { 1020, 989 }, + { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, +}; + +const int16_t (* const ff_vp9_scans_nb[5][4])[2] = { + { + ff_vp9_default_scan_4x4_nb, ff_vp9_col_scan_4x4_nb, + ff_vp9_row_scan_4x4_nb, ff_vp9_default_scan_4x4_nb + }, { + ff_vp9_default_scan_8x8_nb, ff_vp9_col_scan_8x8_nb, + ff_vp9_row_scan_8x8_nb, ff_vp9_default_scan_8x8_nb + }, { + ff_vp9_default_scan_16x16_nb, ff_vp9_col_scan_16x16_nb, + ff_vp9_row_scan_16x16_nb, ff_vp9_default_scan_16x16_nb + }, { + ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb, + ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb + }, { // lossless + ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb, + ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb + } +}; + +const uint8_t ff_vp9_model_pareto8[256][8] = { + { 6, 86, 128, 11, 87, 42, 91, 52 }, + { 3, 86, 128, 6, 86, 23, 88, 29 }, + { 6, 86, 128, 11, 87, 42, 91, 52 }, + { 9, 86, 129, 17, 88, 61, 94, 76 }, + { 12, 86, 129, 22, 88, 77, 97, 93 }, + { 15, 87, 129, 28, 89, 93, 100, 110 }, + { 17, 87, 129, 33, 90, 105, 103, 123 }, + { 20, 88, 130, 38, 91, 118, 106, 136 }, + { 23, 88, 130, 43, 91, 128, 108, 146 }, + { 26, 89, 131, 48, 92, 139, 111, 156 }, + { 28, 89, 131, 53, 93, 147, 114, 163 }, + { 31, 90, 131, 58, 94, 156, 117, 171 }, + { 34, 90, 131, 62, 94, 163, 119, 177 }, + { 37, 90, 132, 66, 95, 171, 122, 184 }, + { 39, 90, 132, 70, 96, 177, 124, 189 }, + { 42, 91, 132, 75, 97, 183, 127, 194 }, + { 44, 91, 132, 79, 97, 188, 129, 198 }, + { 47, 92, 133, 83, 98, 193, 132, 202 }, + { 49, 92, 133, 86, 99, 197, 134, 205 }, + { 52, 93, 133, 90, 100, 201, 137, 208 }, + { 54, 93, 133, 94, 100, 204, 139, 211 }, + { 57, 94, 134, 98, 101, 208, 142, 214 }, + { 59, 94, 134, 101, 102, 211, 144, 216 }, + { 62, 94, 135, 105, 103, 214, 146, 218 }, + { 64, 94, 135, 108, 103, 216, 148, 220 }, + { 66, 95, 135, 111, 104, 219, 151, 222 }, + { 68, 95, 135, 114, 105, 221, 153, 223 }, + { 71, 96, 136, 117, 106, 224, 155, 225 }, + { 73, 96, 136, 120, 106, 225, 157, 226 }, + { 76, 97, 136, 123, 107, 227, 159, 228 }, + { 78, 97, 136, 126, 108, 229, 160, 229 }, + { 80, 98, 137, 129, 109, 231, 162, 231 }, + { 82, 98, 137, 131, 109, 232, 164, 232 }, + { 84, 98, 138, 134, 110, 234, 166, 233 }, + { 86, 98, 138, 137, 111, 235, 168, 234 }, + { 89, 99, 138, 140, 112, 236, 170, 235 }, + { 91, 99, 138, 142, 112, 237, 171, 235 }, + { 93, 100, 139, 145, 113, 238, 173, 236 }, + { 95, 100, 139, 147, 114, 239, 174, 237 }, + { 97, 101, 140, 149, 115, 240, 176, 238 }, + { 99, 101, 140, 151, 115, 241, 177, 238 }, + { 101, 102, 140, 154, 116, 242, 179, 239 }, + { 103, 102, 140, 156, 117, 242, 180, 239 }, + { 105, 103, 141, 158, 118, 243, 182, 240 }, + { 107, 103, 141, 160, 118, 243, 183, 240 }, + { 109, 104, 141, 162, 119, 244, 185, 241 }, + { 111, 104, 141, 164, 119, 244, 186, 241 }, + { 113, 104, 142, 166, 120, 245, 187, 242 }, + { 114, 104, 142, 168, 121, 245, 188, 242 }, + { 116, 105, 143, 170, 122, 246, 190, 243 }, + { 118, 105, 143, 171, 122, 246, 191, 243 }, + { 120, 106, 143, 173, 123, 247, 192, 244 }, + { 121, 106, 143, 175, 124, 247, 193, 244 }, + { 123, 107, 144, 177, 125, 248, 195, 244 }, + { 125, 107, 144, 178, 125, 248, 196, 244 }, + { 127, 108, 145, 180, 126, 249, 197, 245 }, + { 128, 108, 145, 181, 127, 249, 198, 245 }, + { 130, 109, 145, 183, 128, 249, 199, 245 }, + { 132, 109, 145, 184, 128, 249, 200, 245 }, + { 134, 110, 146, 186, 129, 250, 201, 246 }, + { 135, 110, 146, 187, 130, 250, 202, 246 }, + { 137, 111, 147, 189, 131, 251, 203, 246 }, + { 138, 111, 147, 190, 131, 251, 204, 246 }, + { 140, 112, 147, 192, 132, 251, 205, 247 }, + { 141, 112, 147, 193, 132, 251, 206, 247 }, + { 143, 113, 148, 194, 133, 251, 207, 247 }, + { 144, 113, 148, 195, 134, 251, 207, 247 }, + { 146, 114, 149, 197, 135, 252, 208, 248 }, + { 147, 114, 149, 198, 135, 252, 209, 248 }, + { 149, 115, 149, 199, 136, 252, 210, 248 }, + { 150, 115, 149, 200, 137, 252, 210, 248 }, + { 152, 115, 150, 201, 138, 252, 211, 248 }, + { 153, 115, 150, 202, 138, 252, 212, 248 }, + { 155, 116, 151, 204, 139, 253, 213, 249 }, + { 156, 116, 151, 205, 139, 253, 213, 249 }, + { 158, 117, 151, 206, 140, 253, 214, 249 }, + { 159, 117, 151, 207, 141, 253, 215, 249 }, + { 161, 118, 152, 208, 142, 253, 216, 249 }, + { 162, 118, 152, 209, 142, 253, 216, 249 }, + { 163, 119, 153, 210, 143, 253, 217, 249 }, + { 164, 119, 153, 211, 143, 253, 217, 249 }, + { 166, 120, 153, 212, 144, 254, 218, 250 }, + { 167, 120, 153, 212, 145, 254, 219, 250 }, + { 168, 121, 154, 213, 146, 254, 220, 250 }, + { 169, 121, 154, 214, 146, 254, 220, 250 }, + { 171, 122, 155, 215, 147, 254, 221, 250 }, + { 172, 122, 155, 216, 147, 254, 221, 250 }, + { 173, 123, 155, 217, 148, 254, 222, 250 }, + { 174, 123, 155, 217, 149, 254, 222, 250 }, + { 176, 124, 156, 218, 150, 254, 223, 250 }, + { 177, 124, 156, 219, 150, 254, 223, 250 }, + { 178, 125, 157, 220, 151, 254, 224, 251 }, + { 179, 125, 157, 220, 151, 254, 224, 251 }, + { 180, 126, 157, 221, 152, 254, 225, 251 }, + { 181, 126, 157, 221, 152, 254, 225, 251 }, + { 183, 127, 158, 222, 153, 254, 226, 251 }, + { 184, 127, 158, 223, 154, 254, 226, 251 }, + { 185, 128, 159, 224, 155, 255, 227, 251 }, + { 186, 128, 159, 224, 155, 255, 227, 251 }, + { 187, 129, 160, 225, 156, 255, 228, 251 }, + { 188, 130, 160, 225, 156, 255, 228, 251 }, + { 189, 131, 160, 226, 157, 255, 228, 251 }, + { 190, 131, 160, 226, 158, 255, 228, 251 }, + { 191, 132, 161, 227, 159, 255, 229, 251 }, + { 192, 132, 161, 227, 159, 255, 229, 251 }, + { 193, 133, 162, 228, 160, 255, 230, 252 }, + { 194, 133, 162, 229, 160, 255, 230, 252 }, + { 195, 134, 163, 230, 161, 255, 231, 252 }, + { 196, 134, 163, 230, 161, 255, 231, 252 }, + { 197, 135, 163, 231, 162, 255, 231, 252 }, + { 198, 135, 163, 231, 162, 255, 231, 252 }, + { 199, 136, 164, 232, 163, 255, 232, 252 }, + { 200, 136, 164, 232, 164, 255, 232, 252 }, + { 201, 137, 165, 233, 165, 255, 233, 252 }, + { 201, 137, 165, 233, 165, 255, 233, 252 }, + { 202, 138, 166, 233, 166, 255, 233, 252 }, + { 203, 138, 166, 233, 166, 255, 233, 252 }, + { 204, 139, 166, 234, 167, 255, 234, 252 }, + { 205, 139, 166, 234, 167, 255, 234, 252 }, + { 206, 140, 167, 235, 168, 255, 235, 252 }, + { 206, 140, 167, 235, 168, 255, 235, 252 }, + { 207, 141, 168, 236, 169, 255, 235, 252 }, + { 208, 141, 168, 236, 170, 255, 235, 252 }, + { 209, 142, 169, 237, 171, 255, 236, 252 }, + { 209, 143, 169, 237, 171, 255, 236, 252 }, + { 210, 144, 169, 237, 172, 255, 236, 252 }, + { 211, 144, 169, 237, 172, 255, 236, 252 }, + { 212, 145, 170, 238, 173, 255, 237, 252 }, + { 213, 145, 170, 238, 173, 255, 237, 252 }, + { 214, 146, 171, 239, 174, 255, 237, 253 }, + { 214, 146, 171, 239, 174, 255, 237, 253 }, + { 215, 147, 172, 240, 175, 255, 238, 253 }, + { 215, 147, 172, 240, 175, 255, 238, 253 }, + { 216, 148, 173, 240, 176, 255, 238, 253 }, + { 217, 148, 173, 240, 176, 255, 238, 253 }, + { 218, 149, 173, 241, 177, 255, 239, 253 }, + { 218, 149, 173, 241, 178, 255, 239, 253 }, + { 219, 150, 174, 241, 179, 255, 239, 253 }, + { 219, 151, 174, 241, 179, 255, 239, 253 }, + { 220, 152, 175, 242, 180, 255, 240, 253 }, + { 221, 152, 175, 242, 180, 255, 240, 253 }, + { 222, 153, 176, 242, 181, 255, 240, 253 }, + { 222, 153, 176, 242, 181, 255, 240, 253 }, + { 223, 154, 177, 243, 182, 255, 240, 253 }, + { 223, 154, 177, 243, 182, 255, 240, 253 }, + { 224, 155, 178, 244, 183, 255, 241, 253 }, + { 224, 155, 178, 244, 183, 255, 241, 253 }, + { 225, 156, 178, 244, 184, 255, 241, 253 }, + { 225, 157, 178, 244, 184, 255, 241, 253 }, + { 226, 158, 179, 244, 185, 255, 242, 253 }, + { 227, 158, 179, 244, 185, 255, 242, 253 }, + { 228, 159, 180, 245, 186, 255, 242, 253 }, + { 228, 159, 180, 245, 186, 255, 242, 253 }, + { 229, 160, 181, 245, 187, 255, 242, 253 }, + { 229, 160, 181, 245, 187, 255, 242, 253 }, + { 230, 161, 182, 246, 188, 255, 243, 253 }, + { 230, 162, 182, 246, 188, 255, 243, 253 }, + { 231, 163, 183, 246, 189, 255, 243, 253 }, + { 231, 163, 183, 246, 189, 255, 243, 253 }, + { 232, 164, 184, 247, 190, 255, 243, 253 }, + { 232, 164, 184, 247, 190, 255, 243, 253 }, + { 233, 165, 185, 247, 191, 255, 244, 253 }, + { 233, 165, 185, 247, 191, 255, 244, 253 }, + { 234, 166, 185, 247, 192, 255, 244, 253 }, + { 234, 167, 185, 247, 192, 255, 244, 253 }, + { 235, 168, 186, 248, 193, 255, 244, 253 }, + { 235, 168, 186, 248, 193, 255, 244, 253 }, + { 236, 169, 187, 248, 194, 255, 244, 253 }, + { 236, 169, 187, 248, 194, 255, 244, 253 }, + { 236, 170, 188, 248, 195, 255, 245, 253 }, + { 236, 170, 188, 248, 195, 255, 245, 253 }, + { 237, 171, 189, 249, 196, 255, 245, 254 }, + { 237, 172, 189, 249, 196, 255, 245, 254 }, + { 238, 173, 190, 249, 197, 255, 245, 254 }, + { 238, 173, 190, 249, 197, 255, 245, 254 }, + { 239, 174, 191, 249, 198, 255, 245, 254 }, + { 239, 174, 191, 249, 198, 255, 245, 254 }, + { 240, 175, 192, 249, 199, 255, 246, 254 }, + { 240, 176, 192, 249, 199, 255, 246, 254 }, + { 240, 177, 193, 250, 200, 255, 246, 254 }, + { 240, 177, 193, 250, 200, 255, 246, 254 }, + { 241, 178, 194, 250, 201, 255, 246, 254 }, + { 241, 178, 194, 250, 201, 255, 246, 254 }, + { 242, 179, 195, 250, 202, 255, 246, 254 }, + { 242, 180, 195, 250, 202, 255, 246, 254 }, + { 242, 181, 196, 250, 203, 255, 247, 254 }, + { 242, 181, 196, 250, 203, 255, 247, 254 }, + { 243, 182, 197, 251, 204, 255, 247, 254 }, + { 243, 183, 197, 251, 204, 255, 247, 254 }, + { 244, 184, 198, 251, 205, 255, 247, 254 }, + { 244, 184, 198, 251, 205, 255, 247, 254 }, + { 244, 185, 199, 251, 206, 255, 247, 254 }, + { 244, 185, 199, 251, 206, 255, 247, 254 }, + { 245, 186, 200, 251, 207, 255, 247, 254 }, + { 245, 187, 200, 251, 207, 255, 247, 254 }, + { 246, 188, 201, 252, 207, 255, 248, 254 }, + { 246, 188, 201, 252, 207, 255, 248, 254 }, + { 246, 189, 202, 252, 208, 255, 248, 254 }, + { 246, 190, 202, 252, 208, 255, 248, 254 }, + { 247, 191, 203, 252, 209, 255, 248, 254 }, + { 247, 191, 203, 252, 209, 255, 248, 254 }, + { 247, 192, 204, 252, 210, 255, 248, 254 }, + { 247, 193, 204, 252, 210, 255, 248, 254 }, + { 248, 194, 205, 252, 211, 255, 248, 254 }, + { 248, 194, 205, 252, 211, 255, 248, 254 }, + { 248, 195, 206, 252, 212, 255, 249, 254 }, + { 248, 196, 206, 252, 212, 255, 249, 254 }, + { 249, 197, 207, 253, 213, 255, 249, 254 }, + { 249, 197, 207, 253, 213, 255, 249, 254 }, + { 249, 198, 208, 253, 214, 255, 249, 254 }, + { 249, 199, 209, 253, 214, 255, 249, 254 }, + { 250, 200, 210, 253, 215, 255, 249, 254 }, + { 250, 200, 210, 253, 215, 255, 249, 254 }, + { 250, 201, 211, 253, 215, 255, 249, 254 }, + { 250, 202, 211, 253, 215, 255, 249, 254 }, + { 250, 203, 212, 253, 216, 255, 249, 254 }, + { 250, 203, 212, 253, 216, 255, 249, 254 }, + { 251, 204, 213, 253, 217, 255, 250, 254 }, + { 251, 205, 213, 253, 217, 255, 250, 254 }, + { 251, 206, 214, 254, 218, 255, 250, 254 }, + { 251, 206, 215, 254, 218, 255, 250, 254 }, + { 252, 207, 216, 254, 219, 255, 250, 254 }, + { 252, 208, 216, 254, 219, 255, 250, 254 }, + { 252, 209, 217, 254, 220, 255, 250, 254 }, + { 252, 210, 217, 254, 220, 255, 250, 254 }, + { 252, 211, 218, 254, 221, 255, 250, 254 }, + { 252, 212, 218, 254, 221, 255, 250, 254 }, + { 253, 213, 219, 254, 222, 255, 250, 254 }, + { 253, 213, 220, 254, 222, 255, 250, 254 }, + { 253, 214, 221, 254, 223, 255, 250, 254 }, + { 253, 215, 221, 254, 223, 255, 250, 254 }, + { 253, 216, 222, 254, 224, 255, 251, 254 }, + { 253, 217, 223, 254, 224, 255, 251, 254 }, + { 253, 218, 224, 254, 225, 255, 251, 254 }, + { 253, 219, 224, 254, 225, 255, 251, 254 }, + { 254, 220, 225, 254, 225, 255, 251, 254 }, + { 254, 221, 226, 254, 225, 255, 251, 254 }, + { 254, 222, 227, 255, 226, 255, 251, 254 }, + { 254, 223, 227, 255, 226, 255, 251, 254 }, + { 254, 224, 228, 255, 227, 255, 251, 254 }, + { 254, 225, 229, 255, 227, 255, 251, 254 }, + { 254, 226, 230, 255, 228, 255, 251, 254 }, + { 254, 227, 230, 255, 229, 255, 251, 254 }, + { 255, 228, 231, 255, 230, 255, 251, 254 }, + { 255, 229, 232, 255, 230, 255, 251, 254 }, + { 255, 230, 233, 255, 231, 255, 252, 254 }, + { 255, 231, 234, 255, 231, 255, 252, 254 }, + { 255, 232, 235, 255, 232, 255, 252, 254 }, + { 255, 233, 236, 255, 232, 255, 252, 254 }, + { 255, 235, 237, 255, 233, 255, 252, 254 }, + { 255, 236, 238, 255, 234, 255, 252, 254 }, + { 255, 238, 240, 255, 235, 255, 252, 255 }, + { 255, 239, 241, 255, 235, 255, 252, 254 }, + { 255, 241, 243, 255, 236, 255, 252, 254 }, + { 255, 243, 245, 255, 237, 255, 252, 254 }, + { 255, 246, 247, 255, 239, 255, 253, 255 }, +}; + +const ProbContext ff_vp9_default_probs = { + { /* y_mode */ + { 65, 32, 18, 144, 162, 194, 41, 51, 98 } /* bsize < 8x8 */, + { 132, 68, 18, 165, 217, 196, 45, 40, 78 } /* bsize < 16x16 */, + { 173, 80, 19, 176, 240, 193, 64, 35, 46 } /* bsize < 32x32 */, + { 221, 135, 38, 194, 248, 121, 96, 85, 29 } /* bsize >= 32x32 */ + }, { /* uv_mode */ + { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */, + { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */, + { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */, + { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */, + { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */, + { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */, + { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */, + { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */, + { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d27 */, + { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */ + }, { /* filter */ + { 235, 162, }, + { 36, 255, }, + { 34, 3, }, + { 149, 144, }, + }, { /* mv_mode */ + { 2, 173, 34 }, // 0 = both zero mv + { 7, 145, 85 }, // 1 = one zero mv + one a predicted mv + { 7, 166, 63 }, // 2 = two predicted mvs + { 7, 94, 66 }, // 3 = one predicted/zero and one new mv + { 8, 64, 46 }, // 4 = two new mvs + { 17, 81, 31 }, // 5 = one intra neighbor + x + { 25, 29, 30 }, // 6 = two intra neighbors + }, { /* intra */ + 9, 102, 187, 225 + }, { /* comp */ + 239, 183, 119, 96, 41 + }, { /* single_ref */ + { 33, 16 }, + { 77, 74 }, + { 142, 142 }, + { 172, 170 }, + { 238, 247 } + }, { /* comp_ref */ + 50, 126, 123, 221, 226 + }, { /* tx32p */ + { 3, 136, 37, }, + { 5, 52, 13, }, + }, { /* tx16p */ + { 20, 152, }, + { 15, 101, }, + }, { /* tx8p */ + 100, 66 + }, { /* skip */ + 192, 128, 64 + }, { /* mv_joint */ + 32, 64, 96 + }, { + { /* mv vertical component */ + 128, /* sign */ + { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ + 216, /* class0 */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ + { /* class0_fp */ + { 128, 128, 64 }, + { 96, 112, 64 } + }, + { 64, 96, 64 }, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + }, { /* mv horizontal component */ + 128, /* sign */ + { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */ + 208, /* class0 */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ + { /* class0_fp */ + { 128, 128, 64 }, + { 96, 112, 64 } + }, + { 64, 96, 64 }, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + } + }, { /* partition */ + { /* 64x64 -> 32x32 */ + { 222, 34, 30 } /* a/l both not split */, + { 72, 16, 44 } /* a split, l not split */, + { 58, 32, 12 } /* l split, a not split */, + { 10, 7, 6 } /* a/l both split */, + }, { /* 32x32 -> 16x16 */ + { 177, 58, 59 } /* a/l both not split */, + { 68, 26, 63 } /* a split, l not split */, + { 52, 79, 25 } /* l split, a not split */, + { 17, 14, 12 } /* a/l both split */, + }, { /* 16x16 -> 8x8 */ + { 174, 73, 87 } /* a/l both not split */, + { 92, 41, 83 } /* a split, l not split */, + { 82, 99, 50 } /* l split, a not split */, + { 53, 39, 39 } /* a/l both split */, + }, { /* 8x8 -> 4x4 */ + { 199, 122, 141 } /* a/l both not split */, + { 147, 63, 159 } /* a split, l not split */, + { 148, 133, 118 } /* l split, a not split */, + { 121, 104, 114 } /* a/l both split */, + } + }, +}; + +const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3] = { + { /* tx = 4x4 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 195, 29, 183 }, + { 84, 49, 136 }, + { 8, 42, 71 } + }, { /* Coeff Band 1 */ + { 31, 107, 169 }, + { 35, 99, 159 }, + { 17, 82, 140 }, + { 8, 66, 114 }, + { 2, 44, 76 }, + { 1, 19, 32 } + }, { /* Coeff Band 2 */ + { 40, 132, 201 }, + { 29, 114, 187 }, + { 13, 91, 157 }, + { 7, 75, 127 }, + { 3, 58, 95 }, + { 1, 28, 47 } + }, { /* Coeff Band 3 */ + { 69, 142, 221 }, + { 42, 122, 201 }, + { 15, 91, 159 }, + { 6, 67, 121 }, + { 1, 42, 77 }, + { 1, 17, 31 } + }, { /* Coeff Band 4 */ + { 102, 148, 228 }, + { 67, 117, 204 }, + { 17, 82, 154 }, + { 6, 59, 114 }, + { 2, 39, 75 }, + { 1, 15, 29 } + }, { /* Coeff Band 5 */ + { 156, 57, 233 }, + { 119, 57, 212 }, + { 58, 48, 163 }, + { 29, 40, 124 }, + { 12, 30, 81 }, + { 3, 12, 31 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 191, 107, 226 }, + { 124, 117, 204 }, + { 25, 99, 155 } + }, { /* Coeff Band 1 */ + { 29, 148, 210 }, + { 37, 126, 194 }, + { 8, 93, 157 }, + { 2, 68, 118 }, + { 1, 39, 69 }, + { 1, 17, 33 } + }, { /* Coeff Band 2 */ + { 41, 151, 213 }, + { 27, 123, 193 }, + { 3, 82, 144 }, + { 1, 58, 105 }, + { 1, 32, 60 }, + { 1, 13, 26 } + }, { /* Coeff Band 3 */ + { 59, 159, 220 }, + { 23, 126, 198 }, + { 4, 88, 151 }, + { 1, 66, 114 }, + { 1, 38, 71 }, + { 1, 18, 34 } + }, { /* Coeff Band 4 */ + { 114, 136, 232 }, + { 51, 114, 207 }, + { 11, 83, 155 }, + { 3, 56, 105 }, + { 1, 33, 65 }, + { 1, 17, 34 } + }, { /* Coeff Band 5 */ + { 149, 65, 234 }, + { 121, 57, 215 }, + { 61, 49, 166 }, + { 28, 36, 114 }, + { 12, 25, 76 }, + { 3, 16, 42 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 214, 49, 220 }, + { 132, 63, 188 }, + { 42, 65, 137 } + }, { /* Coeff Band 1 */ + { 85, 137, 221 }, + { 104, 131, 216 }, + { 49, 111, 192 }, + { 21, 87, 155 }, + { 2, 49, 87 }, + { 1, 16, 28 } + }, { /* Coeff Band 2 */ + { 89, 163, 230 }, + { 90, 137, 220 }, + { 29, 100, 183 }, + { 10, 70, 135 }, + { 2, 42, 81 }, + { 1, 17, 33 } + }, { /* Coeff Band 3 */ + { 108, 167, 237 }, + { 55, 133, 222 }, + { 15, 97, 179 }, + { 4, 72, 135 }, + { 1, 45, 85 }, + { 1, 19, 38 } + }, { /* Coeff Band 4 */ + { 124, 146, 240 }, + { 66, 124, 224 }, + { 17, 88, 175 }, + { 4, 58, 122 }, + { 1, 36, 75 }, + { 1, 18, 37 } + }, { /* Coeff Band 5 */ + { 141, 79, 241 }, + { 126, 70, 227 }, + { 66, 58, 182 }, + { 30, 44, 136 }, + { 12, 34, 96 }, + { 2, 20, 47 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 229, 99, 249 }, + { 143, 111, 235 }, + { 46, 109, 192 } + }, { /* Coeff Band 1 */ + { 82, 158, 236 }, + { 94, 146, 224 }, + { 25, 117, 191 }, + { 9, 87, 149 }, + { 3, 56, 99 }, + { 1, 33, 57 } + }, { /* Coeff Band 2 */ + { 83, 167, 237 }, + { 68, 145, 222 }, + { 10, 103, 177 }, + { 2, 72, 131 }, + { 1, 41, 79 }, + { 1, 20, 39 } + }, { /* Coeff Band 3 */ + { 99, 167, 239 }, + { 47, 141, 224 }, + { 10, 104, 178 }, + { 2, 73, 133 }, + { 1, 44, 85 }, + { 1, 22, 47 } + }, { /* Coeff Band 4 */ + { 127, 145, 243 }, + { 71, 129, 228 }, + { 17, 93, 177 }, + { 3, 61, 124 }, + { 1, 41, 84 }, + { 1, 21, 52 } + }, { /* Coeff Band 5 */ + { 157, 78, 244 }, + { 140, 72, 231 }, + { 69, 58, 184 }, + { 31, 44, 137 }, + { 14, 38, 105 }, + { 8, 23, 61 } + } + } + } + }, { /* tx = 8x8 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 125, 34, 187 }, + { 52, 41, 133 }, + { 6, 31, 56 } + }, { /* Coeff Band 1 */ + { 37, 109, 153 }, + { 51, 102, 147 }, + { 23, 87, 128 }, + { 8, 67, 101 }, + { 1, 41, 63 }, + { 1, 19, 29 } + }, { /* Coeff Band 2 */ + { 31, 154, 185 }, + { 17, 127, 175 }, + { 6, 96, 145 }, + { 2, 73, 114 }, + { 1, 51, 82 }, + { 1, 28, 45 } + }, { /* Coeff Band 3 */ + { 23, 163, 200 }, + { 10, 131, 185 }, + { 2, 93, 148 }, + { 1, 67, 111 }, + { 1, 41, 69 }, + { 1, 14, 24 } + }, { /* Coeff Band 4 */ + { 29, 176, 217 }, + { 12, 145, 201 }, + { 3, 101, 156 }, + { 1, 69, 111 }, + { 1, 39, 63 }, + { 1, 14, 23 } + }, { /* Coeff Band 5 */ + { 57, 192, 233 }, + { 25, 154, 215 }, + { 6, 109, 167 }, + { 3, 78, 118 }, + { 1, 48, 69 }, + { 1, 21, 29 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 202, 105, 245 }, + { 108, 106, 216 }, + { 18, 90, 144 } + }, { /* Coeff Band 1 */ + { 33, 172, 219 }, + { 64, 149, 206 }, + { 14, 117, 177 }, + { 5, 90, 141 }, + { 2, 61, 95 }, + { 1, 37, 57 } + }, { /* Coeff Band 2 */ + { 33, 179, 220 }, + { 11, 140, 198 }, + { 1, 89, 148 }, + { 1, 60, 104 }, + { 1, 33, 57 }, + { 1, 12, 21 } + }, { /* Coeff Band 3 */ + { 30, 181, 221 }, + { 8, 141, 198 }, + { 1, 87, 145 }, + { 1, 58, 100 }, + { 1, 31, 55 }, + { 1, 12, 20 } + }, { /* Coeff Band 4 */ + { 32, 186, 224 }, + { 7, 142, 198 }, + { 1, 86, 143 }, + { 1, 58, 100 }, + { 1, 31, 55 }, + { 1, 12, 22 } + }, { /* Coeff Band 5 */ + { 57, 192, 227 }, + { 20, 143, 204 }, + { 3, 96, 154 }, + { 1, 68, 112 }, + { 1, 42, 69 }, + { 1, 19, 32 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 212, 35, 215 }, + { 113, 47, 169 }, + { 29, 48, 105 } + }, { /* Coeff Band 1 */ + { 74, 129, 203 }, + { 106, 120, 203 }, + { 49, 107, 178 }, + { 19, 84, 144 }, + { 4, 50, 84 }, + { 1, 15, 25 } + }, { /* Coeff Band 2 */ + { 71, 172, 217 }, + { 44, 141, 209 }, + { 15, 102, 173 }, + { 6, 76, 133 }, + { 2, 51, 89 }, + { 1, 24, 42 } + }, { /* Coeff Band 3 */ + { 64, 185, 231 }, + { 31, 148, 216 }, + { 8, 103, 175 }, + { 3, 74, 131 }, + { 1, 46, 81 }, + { 1, 18, 30 } + }, { /* Coeff Band 4 */ + { 65, 196, 235 }, + { 25, 157, 221 }, + { 5, 105, 174 }, + { 1, 67, 120 }, + { 1, 38, 69 }, + { 1, 15, 30 } + }, { /* Coeff Band 5 */ + { 65, 204, 238 }, + { 30, 156, 224 }, + { 7, 107, 177 }, + { 2, 70, 124 }, + { 1, 42, 73 }, + { 1, 18, 34 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 225, 86, 251 }, + { 144, 104, 235 }, + { 42, 99, 181 } + }, { /* Coeff Band 1 */ + { 85, 175, 239 }, + { 112, 165, 229 }, + { 29, 136, 200 }, + { 12, 103, 162 }, + { 6, 77, 123 }, + { 2, 53, 84 } + }, { /* Coeff Band 2 */ + { 75, 183, 239 }, + { 30, 155, 221 }, + { 3, 106, 171 }, + { 1, 74, 128 }, + { 1, 44, 76 }, + { 1, 17, 28 } + }, { /* Coeff Band 3 */ + { 73, 185, 240 }, + { 27, 159, 222 }, + { 2, 107, 172 }, + { 1, 75, 127 }, + { 1, 42, 73 }, + { 1, 17, 29 } + }, { /* Coeff Band 4 */ + { 62, 190, 238 }, + { 21, 159, 222 }, + { 2, 107, 172 }, + { 1, 72, 122 }, + { 1, 40, 71 }, + { 1, 18, 32 } + }, { /* Coeff Band 5 */ + { 61, 199, 240 }, + { 27, 161, 226 }, + { 4, 113, 180 }, + { 1, 76, 129 }, + { 1, 46, 80 }, + { 1, 23, 41 } + } + } + } + }, { /* tx = 16x16 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 7, 27, 153 }, + { 5, 30, 95 }, + { 1, 16, 30 } + }, { /* Coeff Band 1 */ + { 50, 75, 127 }, + { 57, 75, 124 }, + { 27, 67, 108 }, + { 10, 54, 86 }, + { 1, 33, 52 }, + { 1, 12, 18 } + }, { /* Coeff Band 2 */ + { 43, 125, 151 }, + { 26, 108, 148 }, + { 7, 83, 122 }, + { 2, 59, 89 }, + { 1, 38, 60 }, + { 1, 17, 27 } + }, { /* Coeff Band 3 */ + { 23, 144, 163 }, + { 13, 112, 154 }, + { 2, 75, 117 }, + { 1, 50, 81 }, + { 1, 31, 51 }, + { 1, 14, 23 } + }, { /* Coeff Band 4 */ + { 18, 162, 185 }, + { 6, 123, 171 }, + { 1, 78, 125 }, + { 1, 51, 86 }, + { 1, 31, 54 }, + { 1, 14, 23 } + }, { /* Coeff Band 5 */ + { 15, 199, 227 }, + { 3, 150, 204 }, + { 1, 91, 146 }, + { 1, 55, 95 }, + { 1, 30, 53 }, + { 1, 11, 20 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 19, 55, 240 }, + { 19, 59, 196 }, + { 3, 52, 105 } + }, { /* Coeff Band 1 */ + { 41, 166, 207 }, + { 104, 153, 199 }, + { 31, 123, 181 }, + { 14, 101, 152 }, + { 5, 72, 106 }, + { 1, 36, 52 } + }, { /* Coeff Band 2 */ + { 35, 176, 211 }, + { 12, 131, 190 }, + { 2, 88, 144 }, + { 1, 60, 101 }, + { 1, 36, 60 }, + { 1, 16, 28 } + }, { /* Coeff Band 3 */ + { 28, 183, 213 }, + { 8, 134, 191 }, + { 1, 86, 142 }, + { 1, 56, 96 }, + { 1, 30, 53 }, + { 1, 12, 20 } + }, { /* Coeff Band 4 */ + { 20, 190, 215 }, + { 4, 135, 192 }, + { 1, 84, 139 }, + { 1, 53, 91 }, + { 1, 28, 49 }, + { 1, 11, 20 } + }, { /* Coeff Band 5 */ + { 13, 196, 216 }, + { 2, 137, 192 }, + { 1, 86, 143 }, + { 1, 57, 99 }, + { 1, 32, 56 }, + { 1, 13, 24 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 211, 29, 217 }, + { 96, 47, 156 }, + { 22, 43, 87 } + }, { /* Coeff Band 1 */ + { 78, 120, 193 }, + { 111, 116, 186 }, + { 46, 102, 164 }, + { 15, 80, 128 }, + { 2, 49, 76 }, + { 1, 18, 28 } + }, { /* Coeff Band 2 */ + { 71, 161, 203 }, + { 42, 132, 192 }, + { 10, 98, 150 }, + { 3, 69, 109 }, + { 1, 44, 70 }, + { 1, 18, 29 } + }, { /* Coeff Band 3 */ + { 57, 186, 211 }, + { 30, 140, 196 }, + { 4, 93, 146 }, + { 1, 62, 102 }, + { 1, 38, 65 }, + { 1, 16, 27 } + }, { /* Coeff Band 4 */ + { 47, 199, 217 }, + { 14, 145, 196 }, + { 1, 88, 142 }, + { 1, 57, 98 }, + { 1, 36, 62 }, + { 1, 15, 26 } + }, { /* Coeff Band 5 */ + { 26, 219, 229 }, + { 5, 155, 207 }, + { 1, 94, 151 }, + { 1, 60, 104 }, + { 1, 36, 62 }, + { 1, 16, 28 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 233, 29, 248 }, + { 146, 47, 220 }, + { 43, 52, 140 } + }, { /* Coeff Band 1 */ + { 100, 163, 232 }, + { 179, 161, 222 }, + { 63, 142, 204 }, + { 37, 113, 174 }, + { 26, 89, 137 }, + { 18, 68, 97 } + }, { /* Coeff Band 2 */ + { 85, 181, 230 }, + { 32, 146, 209 }, + { 7, 100, 164 }, + { 3, 71, 121 }, + { 1, 45, 77 }, + { 1, 18, 30 } + }, { /* Coeff Band 3 */ + { 65, 187, 230 }, + { 20, 148, 207 }, + { 2, 97, 159 }, + { 1, 68, 116 }, + { 1, 40, 70 }, + { 1, 14, 29 } + }, { /* Coeff Band 4 */ + { 40, 194, 227 }, + { 8, 147, 204 }, + { 1, 94, 155 }, + { 1, 65, 112 }, + { 1, 39, 66 }, + { 1, 14, 26 } + }, { /* Coeff Band 5 */ + { 16, 208, 228 }, + { 3, 151, 207 }, + { 1, 98, 160 }, + { 1, 67, 117 }, + { 1, 41, 74 }, + { 1, 17, 31 } + } + } + } + }, { /* tx = 32x32 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 17, 38, 140 }, + { 7, 34, 80 }, + { 1, 17, 29 } + }, { /* Coeff Band 1 */ + { 37, 75, 128 }, + { 41, 76, 128 }, + { 26, 66, 116 }, + { 12, 52, 94 }, + { 2, 32, 55 }, + { 1, 10, 16 } + }, { /* Coeff Band 2 */ + { 50, 127, 154 }, + { 37, 109, 152 }, + { 16, 82, 121 }, + { 5, 59, 85 }, + { 1, 35, 54 }, + { 1, 13, 20 } + }, { /* Coeff Band 3 */ + { 40, 142, 167 }, + { 17, 110, 157 }, + { 2, 71, 112 }, + { 1, 44, 72 }, + { 1, 27, 45 }, + { 1, 11, 17 } + }, { /* Coeff Band 4 */ + { 30, 175, 188 }, + { 9, 124, 169 }, + { 1, 74, 116 }, + { 1, 48, 78 }, + { 1, 30, 49 }, + { 1, 11, 18 } + }, { /* Coeff Band 5 */ + { 10, 222, 223 }, + { 2, 150, 194 }, + { 1, 83, 128 }, + { 1, 48, 79 }, + { 1, 27, 45 }, + { 1, 11, 17 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 36, 41, 235 }, + { 29, 36, 193 }, + { 10, 27, 111 } + }, { /* Coeff Band 1 */ + { 85, 165, 222 }, + { 177, 162, 215 }, + { 110, 135, 195 }, + { 57, 113, 168 }, + { 23, 83, 120 }, + { 10, 49, 61 } + }, { /* Coeff Band 2 */ + { 85, 190, 223 }, + { 36, 139, 200 }, + { 5, 90, 146 }, + { 1, 60, 103 }, + { 1, 38, 65 }, + { 1, 18, 30 } + }, { /* Coeff Band 3 */ + { 72, 202, 223 }, + { 23, 141, 199 }, + { 2, 86, 140 }, + { 1, 56, 97 }, + { 1, 36, 61 }, + { 1, 16, 27 } + }, { /* Coeff Band 4 */ + { 55, 218, 225 }, + { 13, 145, 200 }, + { 1, 86, 141 }, + { 1, 57, 99 }, + { 1, 35, 61 }, + { 1, 13, 22 } + }, { /* Coeff Band 5 */ + { 15, 235, 212 }, + { 1, 132, 184 }, + { 1, 84, 139 }, + { 1, 57, 97 }, + { 1, 34, 56 }, + { 1, 14, 23 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 181, 21, 201 }, + { 61, 37, 123 }, + { 10, 38, 71 } + }, { /* Coeff Band 1 */ + { 47, 106, 172 }, + { 95, 104, 173 }, + { 42, 93, 159 }, + { 18, 77, 131 }, + { 4, 50, 81 }, + { 1, 17, 23 } + }, { /* Coeff Band 2 */ + { 62, 147, 199 }, + { 44, 130, 189 }, + { 28, 102, 154 }, + { 18, 75, 115 }, + { 2, 44, 65 }, + { 1, 12, 19 } + }, { /* Coeff Band 3 */ + { 55, 153, 210 }, + { 24, 130, 194 }, + { 3, 93, 146 }, + { 1, 61, 97 }, + { 1, 31, 50 }, + { 1, 10, 16 } + }, { /* Coeff Band 4 */ + { 49, 186, 223 }, + { 17, 148, 204 }, + { 1, 96, 142 }, + { 1, 53, 83 }, + { 1, 26, 44 }, + { 1, 11, 17 } + }, { /* Coeff Band 5 */ + { 13, 217, 212 }, + { 2, 136, 180 }, + { 1, 78, 124 }, + { 1, 50, 83 }, + { 1, 29, 49 }, + { 1, 14, 23 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 197, 13, 247 }, + { 82, 17, 222 }, + { 25, 17, 162 } + }, { /* Coeff Band 1 */ + { 126, 186, 247 }, + { 234, 191, 243 }, + { 176, 177, 234 }, + { 104, 158, 220 }, + { 66, 128, 186 }, + { 55, 90, 137 } + }, { /* Coeff Band 2 */ + { 111, 197, 242 }, + { 46, 158, 219 }, + { 9, 104, 171 }, + { 2, 65, 125 }, + { 1, 44, 80 }, + { 1, 17, 91 } + }, { /* Coeff Band 3 */ + { 104, 208, 245 }, + { 39, 168, 224 }, + { 3, 109, 162 }, + { 1, 79, 124 }, + { 1, 50, 102 }, + { 1, 43, 102 } + }, { /* Coeff Band 4 */ + { 84, 220, 246 }, + { 31, 177, 231 }, + { 2, 115, 180 }, + { 1, 79, 134 }, + { 1, 55, 77 }, + { 1, 60, 79 } + }, { /* Coeff Band 5 */ + { 43, 243, 240 }, + { 8, 180, 217 }, + { 1, 115, 166 }, + { 1, 84, 121 }, + { 1, 51, 67 }, + { 1, 16, 6 } + } + } + } + } +}; + +const int8_t ff_vp9_mv_joint_tree[3][2] = { + { -MV_JOINT_ZERO, 1 }, // '0' + { -MV_JOINT_H, 2 }, // '10' + { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' +}; + +const int8_t ff_vp9_mv_class_tree[10][2] = { + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { 3, 4 }, + { -2, -3 }, // '110x' + { 5, 6 }, + { -4, -5 }, // '1110x' + { -6, 7 }, // '11110' + { 8, 9 }, + { -7, -8 }, // '111110x' + { -9, -10 }, // '111111x' +}; + +const int8_t ff_vp9_mv_fp_tree[3][2] = { + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { -2, -3 }, // '11x' +}; diff --git a/media/ffvpx/libavcodec/vp9data.h b/media/ffvpx/libavcodec/vp9data.h index cb12e7e94..086dbdec0 100644 --- a/media/ffvpx/libavcodec/vp9data.h +++ b/media/ffvpx/libavcodec/vp9data.h @@ -24,2254 +24,48 @@ #include -#include "vp9.h" - -static const int8_t vp9_partition_tree[3][2] = { - { -PARTITION_NONE, 1 }, // '0' - { -PARTITION_H, 2 }, // '10' - { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' -}; - -static const uint8_t vp9_default_kf_partition_probs[4][4][3] = { - { /* 64x64 -> 32x32 */ - { 174, 35, 49 } /* a/l both not split */, - { 68, 11, 27 } /* a split, l not split */, - { 57, 15, 9 } /* l split, a not split */, - { 12, 3, 3 } /* a/l both split */ - }, { /* 32x32 -> 16x16 */ - { 150, 40, 39 } /* a/l both not split */, - { 78, 12, 26 } /* a split, l not split */, - { 67, 33, 11 } /* l split, a not split */, - { 24, 7, 5 } /* a/l both split */, - }, { /* 16x16 -> 8x8 */ - { 149, 53, 53 } /* a/l both not split */, - { 94, 20, 48 } /* a split, l not split */, - { 83, 53, 24 } /* l split, a not split */, - { 52, 18, 18 } /* a/l both split */, - }, { /* 8x8 -> 4x4 */ - { 158, 97, 94 } /* a/l both not split */, - { 93, 24, 99 } /* a split, l not split */, - { 85, 119, 44 } /* l split, a not split */, - { 62, 59, 67 } /* a/l both split */, - }, -}; - -static const int8_t vp9_segmentation_tree[7][2] = { - { 1, 2 }, - { 3, 4 }, - { 5, 6 }, - { -0, -1 }, // '00x' - { -2, -3 }, // '01x' - { -4, -5 }, // '10x' - { -6, -7 }, // '11x' -}; - -static const int8_t vp9_intramode_tree[9][2] = { - { -DC_PRED, 1 }, // '0' - { -TM_VP8_PRED, 2 }, // '10' - { -VERT_PRED, 3 }, // '110' - { 4, 6 }, - { -HOR_PRED, 5 }, // '11100' - { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' - { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' - { -VERT_LEFT_PRED, 8 }, // '111110' - { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' -}; - -static const uint8_t vp9_default_kf_ymode_probs[10][10][9] = { - { /* above = v */ - { 43, 46, 168, 134, 107, 128, 69, 142, 92 } /* left = v */, - { 44, 29, 68, 159, 201, 177, 50, 57, 77 } /* left = h */, - { 63, 36, 126, 146, 123, 158, 60, 90, 96 } /* left = dc */, - { 58, 38, 76, 114, 97, 172, 78, 133, 92 } /* left = d45 */, - { 46, 41, 76, 140, 63, 184, 69, 112, 57 } /* left = d135 */, - { 38, 32, 85, 140, 46, 112, 54, 151, 133 } /* left = d117 */, - { 39, 27, 61, 131, 110, 175, 44, 75, 136 } /* left = d153 */, - { 47, 35, 80, 100, 74, 143, 64, 163, 74 } /* left = d63 */, - { 52, 30, 74, 113, 130, 175, 51, 64, 58 } /* left = d27 */, - { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /* left = tm */ - }, { /* above = h */ - { 55, 44, 68, 166, 179, 192, 57, 57, 108 } /* left = v */, - { 42, 26, 11, 199, 241, 228, 23, 15, 85 } /* left = h */, - { 82, 26, 26, 171, 208, 204, 44, 32, 105 } /* left = dc */, - { 68, 42, 19, 131, 160, 199, 55, 52, 83 } /* left = d45 */, - { 58, 50, 25, 139, 115, 232, 39, 52, 118 } /* left = d135 */, - { 50, 35, 33, 153, 104, 162, 64, 59, 131 } /* left = d117 */, - { 44, 24, 16, 150, 177, 202, 33, 19, 156 } /* left = d153 */, - { 53, 49, 21, 110, 116, 168, 59, 80, 76 } /* left = d63 */, - { 55, 27, 12, 153, 203, 218, 26, 27, 49 } /* left = d27 */, - { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /* left = tm */ - }, { /* above = dc */ - { 92, 45, 102, 136, 116, 180, 74, 90, 100 } /* left = v */, - { 73, 32, 19, 187, 222, 215, 46, 34, 100 } /* left = h */, - { 137, 30, 42, 148, 151, 207, 70, 52, 91 } /* left = dc */, - { 91, 30, 32, 116, 121, 186, 93, 86, 94 } /* left = d45 */, - { 72, 35, 36, 149, 68, 206, 68, 63, 105 } /* left = d135 */, - { 73, 31, 28, 138, 57, 124, 55, 122, 151 } /* left = d117 */, - { 67, 23, 21, 140, 126, 197, 40, 37, 171 } /* left = d153 */, - { 74, 32, 27, 107, 86, 160, 63, 134, 102 } /* left = d63 */, - { 86, 27, 28, 128, 154, 212, 45, 43, 53 } /* left = d27 */, - { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /* left = tm */ - }, { /* above = d45 */ - { 59, 38, 83, 112, 103, 162, 98, 136, 90 } /* left = v */, - { 62, 30, 23, 158, 200, 207, 59, 57, 50 } /* left = h */, - { 103, 26, 36, 129, 132, 201, 83, 80, 93 } /* left = dc */, - { 67, 30, 29, 84, 86, 191, 102, 91, 59 } /* left = d45 */, - { 60, 32, 33, 112, 71, 220, 64, 89, 104 } /* left = d135 */, - { 53, 26, 34, 130, 56, 149, 84, 120, 103 } /* left = d117 */, - { 53, 21, 23, 133, 109, 210, 56, 77, 172 } /* left = d153 */, - { 61, 29, 29, 93, 97, 165, 83, 175, 162 } /* left = d63 */, - { 77, 19, 29, 112, 142, 228, 55, 66, 36 } /* left = d27 */, - { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /* left = tm */ - }, { /* above = d135 */ - { 53, 40, 55, 139, 69, 183, 61, 80, 110 } /* left = v */, - { 40, 29, 19, 161, 180, 207, 43, 24, 91 } /* left = h */, - { 69, 23, 29, 128, 83, 199, 46, 44, 101 } /* left = dc */, - { 60, 34, 19, 105, 61, 198, 53, 64, 89 } /* left = d45 */, - { 52, 31, 22, 158, 40, 209, 58, 62, 89 } /* left = d135 */, - { 44, 31, 29, 147, 46, 158, 56, 102, 198 } /* left = d117 */, - { 35, 19, 12, 135, 87, 209, 41, 45, 167 } /* left = d153 */, - { 51, 38, 25, 113, 58, 164, 70, 93, 97 } /* left = d63 */, - { 55, 25, 21, 118, 95, 215, 38, 39, 66 } /* left = d27 */, - { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /* left = tm */ - }, { /* above = d117 */ - { 46, 27, 80, 150, 55, 124, 55, 121, 135 } /* left = v */, - { 36, 23, 27, 165, 149, 166, 54, 64, 118 } /* left = h */, - { 64, 19, 37, 156, 66, 138, 49, 95, 133 } /* left = dc */, - { 53, 21, 36, 131, 63, 163, 60, 109, 81 } /* left = d45 */, - { 40, 26, 35, 154, 40, 185, 51, 97, 123 } /* left = d135 */, - { 35, 19, 34, 179, 19, 97, 48, 129, 124 } /* left = d117 */, - { 36, 20, 26, 136, 62, 164, 33, 77, 154 } /* left = d153 */, - { 45, 26, 28, 129, 45, 129, 49, 147, 123 } /* left = d63 */, - { 45, 18, 32, 130, 90, 157, 40, 79, 91 } /* left = d27 */, - { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /* left = tm */ - }, { /* above = d153 */ - { 56, 39, 58, 133, 117, 173, 48, 53, 187 } /* left = v */, - { 35, 21, 12, 161, 212, 207, 20, 23, 145 } /* left = h */, - { 75, 17, 22, 136, 138, 185, 32, 34, 166 } /* left = dc */, - { 56, 29, 19, 117, 109, 181, 55, 68, 112 } /* left = d45 */, - { 47, 29, 17, 153, 64, 220, 59, 51, 114 } /* left = d135 */, - { 46, 16, 24, 136, 76, 147, 41, 64, 172 } /* left = d117 */, - { 34, 17, 11, 108, 152, 187, 13, 15, 209 } /* left = d153 */, - { 55, 30, 18, 122, 79, 179, 44, 88, 116 } /* left = d63 */, - { 51, 24, 14, 115, 133, 209, 32, 26, 104 } /* left = d27 */, - { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /* left = tm */ - }, { /* above = d63 */ - { 48, 34, 86, 101, 92, 146, 78, 179, 134 } /* left = v */, - { 47, 22, 24, 138, 187, 178, 68, 69, 59 } /* left = h */, - { 78, 23, 39, 111, 117, 170, 74, 124, 94 } /* left = dc */, - { 56, 25, 33, 105, 112, 187, 95, 177, 129 } /* left = d45 */, - { 48, 31, 27, 114, 63, 183, 82, 116, 56 } /* left = d135 */, - { 43, 28, 37, 121, 63, 123, 61, 192, 169 } /* left = d117 */, - { 42, 17, 24, 109, 97, 177, 56, 76, 122 } /* left = d153 */, - { 46, 23, 32, 74, 86, 150, 67, 183, 88 } /* left = d63 */, - { 58, 18, 28, 105, 139, 182, 70, 92, 63 } /* left = d27 */, - { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /* left = tm */ - }, { /* above = d27 */ - { 62, 44, 61, 123, 105, 189, 48, 57, 64 } /* left = v */, - { 47, 25, 17, 175, 222, 220, 24, 30, 86 } /* left = h */, - { 82, 22, 32, 127, 143, 213, 39, 41, 70 } /* left = dc */, - { 68, 36, 17, 106, 102, 206, 59, 74, 74 } /* left = d45 */, - { 57, 39, 23, 151, 68, 216, 55, 63, 58 } /* left = d135 */, - { 49, 30, 35, 141, 70, 168, 82, 40, 115 } /* left = d117 */, - { 51, 25, 15, 136, 129, 202, 38, 35, 139 } /* left = d153 */, - { 59, 39, 19, 114, 75, 180, 77, 104, 42 } /* left = d63 */, - { 68, 26, 16, 111, 141, 215, 29, 28, 28 } /* left = d27 */, - { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /* left = tm */ - }, { /* above = tm */ - { 44, 78, 115, 132, 119, 173, 71, 112, 93 } /* left = v */, - { 39, 38, 21, 184, 227, 206, 42, 32, 64 } /* left = h */, - { 65, 70, 60, 155, 159, 199, 61, 60, 81 } /* left = dc */, - { 58, 47, 36, 124, 137, 193, 80, 82, 78 } /* left = d45 */, - { 49, 50, 35, 144, 95, 205, 63, 78, 59 } /* left = d135 */, - { 41, 53, 52, 148, 71, 142, 65, 128, 51 } /* left = d117 */, - { 40, 36, 28, 143, 143, 202, 40, 55, 137 } /* left = d153 */, - { 42, 44, 44, 104, 105, 164, 64, 130, 80 } /* left = d63 */, - { 52, 34, 29, 129, 183, 227, 42, 35, 43 } /* left = d27 */, - { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /* left = tm */ - } -}; - -static const uint8_t vp9_default_kf_uvmode_probs[10][9] = { - { 118, 15, 123, 148, 131, 101, 44, 93, 131 } /* y = v */, - { 113, 12, 23, 188, 226, 142, 26, 32, 125 } /* y = h */, - { 144, 11, 54, 157, 195, 130, 46, 58, 108 } /* y = dc */, - { 120, 11, 50, 123, 163, 135, 64, 77, 103 } /* y = d45 */, - { 113, 9, 36, 155, 111, 157, 32, 44, 161 } /* y = d135 */, - { 116, 9, 55, 176, 76, 96, 37, 61, 149 } /* y = d117 */, - { 115, 9, 28, 141, 161, 167, 21, 25, 193 } /* y = d153 */, - { 116, 12, 64, 120, 140, 125, 49, 115, 121 } /* y = d63 */, - { 120, 12, 32, 145, 195, 142, 32, 38, 86 } /* y = d27 */, - { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ -}; - -static const int8_t vp9_inter_mode_tree[3][2] = { - { -ZEROMV, 1 }, // '0' - { -NEARESTMV, 2 }, // '10' - { -NEARMV, -NEWMV }, // '11x' -}; - -static const int8_t vp9_filter_tree[2][2] = { - { -0, 1 }, // '0' - { -1, -2 }, // '1x' -}; - -static const enum FilterMode vp9_filter_lut[3] = { - FILTER_8TAP_REGULAR, - FILTER_8TAP_SMOOTH, - FILTER_8TAP_SHARP, -}; - -static const int16_t vp9_dc_qlookup[3][256] = { - { - 4, 8, 8, 9, 10, 11, 12, 12, - 13, 14, 15, 16, 17, 18, 19, 19, - 20, 21, 22, 23, 24, 25, 26, 26, - 27, 28, 29, 30, 31, 32, 32, 33, - 34, 35, 36, 37, 38, 38, 39, 40, - 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 53, - 54, 55, 56, 57, 57, 58, 59, 60, - 61, 62, 62, 63, 64, 65, 66, 66, - 67, 68, 69, 70, 70, 71, 72, 73, - 74, 74, 75, 76, 77, 78, 78, 79, - 80, 81, 81, 82, 83, 84, 85, 85, - 87, 88, 90, 92, 93, 95, 96, 98, - 99, 101, 102, 104, 105, 107, 108, 110, - 111, 113, 114, 116, 117, 118, 120, 121, - 123, 125, 127, 129, 131, 134, 136, 138, - 140, 142, 144, 146, 148, 150, 152, 154, - 156, 158, 161, 164, 166, 169, 172, 174, - 177, 180, 182, 185, 187, 190, 192, 195, - 199, 202, 205, 208, 211, 214, 217, 220, - 223, 226, 230, 233, 237, 240, 243, 247, - 250, 253, 257, 261, 265, 269, 272, 276, - 280, 284, 288, 292, 296, 300, 304, 309, - 313, 317, 322, 326, 330, 335, 340, 344, - 349, 354, 359, 364, 369, 374, 379, 384, - 389, 395, 400, 406, 411, 417, 423, 429, - 435, 441, 447, 454, 461, 467, 475, 482, - 489, 497, 505, 513, 522, 530, 539, 549, - 559, 569, 579, 590, 602, 614, 626, 640, - 654, 668, 684, 700, 717, 736, 755, 775, - 796, 819, 843, 869, 896, 925, 955, 988, - 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, - }, { - 4, 9, 10, 13, 15, 17, 20, 22, - 25, 28, 31, 34, 37, 40, 43, 47, - 50, 53, 57, 60, 64, 68, 71, 75, - 78, 82, 86, 90, 93, 97, 101, 105, - 109, 113, 116, 120, 124, 128, 132, 136, - 140, 143, 147, 151, 155, 159, 163, 166, - 170, 174, 178, 182, 185, 189, 193, 197, - 200, 204, 208, 212, 215, 219, 223, 226, - 230, 233, 237, 241, 244, 248, 251, 255, - 259, 262, 266, 269, 273, 276, 280, 283, - 287, 290, 293, 297, 300, 304, 307, 310, - 314, 317, 321, 324, 327, 331, 334, 337, - 343, 350, 356, 362, 369, 375, 381, 387, - 394, 400, 406, 412, 418, 424, 430, 436, - 442, 448, 454, 460, 466, 472, 478, 484, - 490, 499, 507, 516, 525, 533, 542, 550, - 559, 567, 576, 584, 592, 601, 609, 617, - 625, 634, 644, 655, 666, 676, 687, 698, - 708, 718, 729, 739, 749, 759, 770, 782, - 795, 807, 819, 831, 844, 856, 868, 880, - 891, 906, 920, 933, 947, 961, 975, 988, - 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, - 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, - 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, - 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, - 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, - 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, - 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, - 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, - 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, - 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, - 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, - }, { - 4, 12, 18, 25, 33, 41, 50, 60, - 70, 80, 91, 103, 115, 127, 140, 153, - 166, 180, 194, 208, 222, 237, 251, 266, - 281, 296, 312, 327, 343, 358, 374, 390, - 405, 421, 437, 453, 469, 484, 500, 516, - 532, 548, 564, 580, 596, 611, 627, 643, - 659, 674, 690, 706, 721, 737, 752, 768, - 783, 798, 814, 829, 844, 859, 874, 889, - 904, 919, 934, 949, 964, 978, 993, 1008, - 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, - 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, - 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, - 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, - 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, - 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, - 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, - 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, - 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, - 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, - 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, - 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, - 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, - 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, - 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, - 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, - 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, - 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, - 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, - 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, - 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, - 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, - 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, - } -}; - -static const int16_t vp9_ac_qlookup[3][256] = { - { - 4, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, - 104, 106, 108, 110, 112, 114, 116, 118, - 120, 122, 124, 126, 128, 130, 132, 134, - 136, 138, 140, 142, 144, 146, 148, 150, - 152, 155, 158, 161, 164, 167, 170, 173, - 176, 179, 182, 185, 188, 191, 194, 197, - 200, 203, 207, 211, 215, 219, 223, 227, - 231, 235, 239, 243, 247, 251, 255, 260, - 265, 270, 275, 280, 285, 290, 295, 300, - 305, 311, 317, 323, 329, 335, 341, 347, - 353, 359, 366, 373, 380, 387, 394, 401, - 408, 416, 424, 432, 440, 448, 456, 465, - 474, 483, 492, 501, 510, 520, 530, 540, - 550, 560, 571, 582, 593, 604, 615, 627, - 639, 651, 663, 676, 689, 702, 715, 729, - 743, 757, 771, 786, 801, 816, 832, 848, - 864, 881, 898, 915, 933, 951, 969, 988, - 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, - 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, - 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, - 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, - }, { - 4, 9, 11, 13, 16, 18, 21, 24, - 27, 30, 33, 37, 40, 44, 48, 51, - 55, 59, 63, 67, 71, 75, 79, 83, - 88, 92, 96, 100, 105, 109, 114, 118, - 122, 127, 131, 136, 140, 145, 149, 154, - 158, 163, 168, 172, 177, 181, 186, 190, - 195, 199, 204, 208, 213, 217, 222, 226, - 231, 235, 240, 244, 249, 253, 258, 262, - 267, 271, 275, 280, 284, 289, 293, 297, - 302, 306, 311, 315, 319, 324, 328, 332, - 337, 341, 345, 349, 354, 358, 362, 367, - 371, 375, 379, 384, 388, 392, 396, 401, - 409, 417, 425, 433, 441, 449, 458, 466, - 474, 482, 490, 498, 506, 514, 523, 531, - 539, 547, 555, 563, 571, 579, 588, 596, - 604, 616, 628, 640, 652, 664, 676, 688, - 700, 713, 725, 737, 749, 761, 773, 785, - 797, 809, 825, 841, 857, 873, 889, 905, - 922, 938, 954, 970, 986, 1002, 1018, 1038, - 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, - 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, - 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, - 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, - 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, - 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, - 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, - 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, - 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, - 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, - 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, - 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, - 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, - }, { - 4, 13, 19, 27, 35, 44, 54, 64, - 75, 87, 99, 112, 126, 139, 154, 168, - 183, 199, 214, 230, 247, 263, 280, 297, - 314, 331, 349, 366, 384, 402, 420, 438, - 456, 475, 493, 511, 530, 548, 567, 586, - 604, 623, 642, 660, 679, 698, 716, 735, - 753, 772, 791, 809, 828, 846, 865, 884, - 902, 920, 939, 957, 976, 994, 1012, 1030, - 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, - 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, - 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, - 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, - 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, - 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, - 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, - 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, - 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, - 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, - 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, - 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, - 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, - 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, - 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, - 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, - 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, - 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, - 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, - 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, - 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, - 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, - 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, - 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, - } -}; - -static const enum TxfmType vp9_intra_txfm_type[14] = { - [VERT_PRED] = ADST_DCT, - [HOR_PRED] = DCT_ADST, - [DC_PRED] = DCT_DCT, - [DIAG_DOWN_LEFT_PRED] = DCT_DCT, - [DIAG_DOWN_RIGHT_PRED] = ADST_ADST, - [VERT_RIGHT_PRED] = ADST_DCT, - [HOR_DOWN_PRED] = DCT_ADST, - [VERT_LEFT_PRED] = ADST_DCT, - [HOR_UP_PRED] = DCT_ADST, - [TM_VP8_PRED] = ADST_ADST, - [NEARESTMV] = DCT_DCT, - [NEARMV] = DCT_DCT, - [ZEROMV] = DCT_DCT, - [NEWMV] = DCT_DCT, -}; - -static const int16_t vp9_default_scan_4x4[16] = { - 0, 1, 4, 5, - 2, 8, 3, 6, - 12, 9, 7, 10, - 13, 11, 14, 15, -}; - -static const int16_t vp9_col_scan_4x4[16] = { - 0, 1, 2, 4, - 3, 5, 6, 8, - 7, 9, 10, 12, - 13, 11, 14, 15, -}; - -static const int16_t vp9_row_scan_4x4[16] = { - 0, 4, 1, 8, - 5, 12, 9, 2, - 6, 13, 3, 10, - 7, 14, 11, 15, -}; - -static const int16_t vp9_default_scan_8x8[64] = { - 0, 1, 8, 2, 9, 16, 10, 3, - 17, 24, 18, 11, 4, 25, 32, 19, - 12, 26, 5, 33, 20, 27, 40, 13, - 34, 6, 41, 28, 21, 35, 42, 48, - 14, 7, 36, 29, 43, 56, 49, 22, - 15, 37, 50, 44, 57, 30, 23, 51, - 45, 58, 38, 31, 52, 59, 39, 46, - 53, 60, 47, 54, 61, 55, 62, 63, -}; - -static const int16_t vp9_col_scan_8x8[64] = { - 0, 1, 2, 8, 3, 9, 4, 10, - 16, 5, 11, 17, 12, 18, 6, 24, - 19, 13, 25, 7, 26, 20, 32, 14, - 27, 21, 33, 28, 34, 15, 22, 35, - 40, 29, 41, 36, 23, 30, 42, 37, - 48, 43, 31, 44, 49, 38, 50, 56, - 45, 39, 51, 57, 52, 46, 58, 53, - 59, 47, 60, 54, 61, 55, 62, 63, -}; - -static const int16_t vp9_row_scan_8x8[64] = { - 0, 8, 16, 1, 9, 24, 2, 17, - 32, 10, 25, 3, 40, 18, 11, 33, - 26, 19, 4, 48, 41, 34, 12, 27, - 56, 20, 5, 42, 35, 13, 49, 28, - 6, 21, 43, 36, 14, 50, 29, 57, - 7, 44, 22, 37, 51, 15, 58, 30, - 23, 45, 52, 38, 59, 31, 46, 53, - 39, 60, 47, 61, 54, 62, 55, 63, -}; - -static const int16_t vp9_default_scan_16x16[256] = { - 0, 1, 16, 2, 17, 32, 3, 18, 33, 48, 4, 34, 19, 49, 20, 5, - 35, 64, 50, 36, 65, 21, 6, 51, 80, 66, 37, 22, 52, 7, 81, 67, - 38, 82, 53, 23, 96, 68, 8, 83, 97, 54, 39, 69, 112, 24, 98, 84, - 70, 55, 9, 40, 85, 99, 113, 128, 25, 114, 100, 71, 86, 56, 10, 41, - 115, 101, 129, 116, 72, 87, 26, 130, 144, 102, 57, 11, 42, 117, 131, 145, - 88, 103, 27, 73, 132, 118, 146, 58, 160, 12, 43, 133, 147, 104, 89, 119, - 161, 74, 148, 134, 28, 162, 59, 13, 176, 120, 149, 90, 135, 105, 163, 44, - 75, 177, 164, 29, 150, 121, 136, 178, 165, 14, 106, 60, 91, 151, 45, 179, - 192, 137, 166, 122, 76, 180, 152, 30, 61, 15, 107, 167, 181, 193, 92, 208, - 46, 138, 123, 153, 194, 77, 168, 182, 31, 195, 209, 183, 108, 139, 62, 154, - 47, 196, 93, 169, 210, 197, 224, 124, 184, 211, 78, 109, 170, 155, 63, 198, - 212, 185, 225, 240, 140, 94, 199, 125, 79, 213, 226, 171, 186, 156, 214, 200, - 110, 227, 141, 95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216, - 243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232, - 189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191, - 235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255, -}; - -static const int16_t vp9_col_scan_16x16[256] = { - 0, 1, 2, 3, 16, 4, 17, 5, 18, 6, 19, 32, 20, 7, 33, 21, - 34, 8, 35, 22, 48, 36, 9, 49, 23, 50, 37, 10, 38, 51, 24, 64, - 52, 11, 65, 39, 25, 53, 66, 54, 40, 67, 12, 80, 26, 68, 55, 81, - 41, 69, 13, 27, 82, 56, 70, 83, 42, 14, 84, 96, 71, 28, 57, 85, - 97, 15, 72, 98, 43, 86, 58, 99, 29, 87, 100, 112, 73, 44, 101, 59, - 30, 113, 88, 114, 74, 128, 102, 45, 31, 115, 60, 103, 89, 116, 75, 129, - 117, 46, 104, 90, 61, 130, 118, 131, 132, 105, 76, 47, 119, 144, 91, 62, - 133, 106, 145, 120, 146, 134, 77, 147, 121, 92, 135, 148, 63, 107, 136, 122, - 93, 149, 160, 78, 150, 137, 108, 161, 162, 151, 123, 79, 138, 163, 152, 94, - 164, 109, 165, 153, 124, 139, 176, 166, 95, 177, 167, 110, 154, 178, 125, 179, - 140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170, - 195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172, - 158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215, - 227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244, - 231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206, - 249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255, -}; - -static const int16_t vp9_row_scan_16x16[256] = { - 0, 16, 32, 1, 48, 17, 64, 33, 2, 80, 18, 49, 96, 34, 3, 65, - 19, 112, 50, 81, 35, 4, 128, 66, 20, 97, 51, 82, 5, 144, 36, 67, - 113, 98, 21, 52, 160, 83, 129, 37, 68, 6, 114, 176, 99, 53, 22, 84, - 145, 38, 69, 130, 7, 115, 192, 100, 54, 23, 85, 161, 146, 131, 39, 70, - 208, 116, 8, 101, 177, 55, 86, 24, 162, 147, 132, 71, 224, 117, 40, 102, - 9, 148, 56, 87, 193, 163, 240, 133, 178, 25, 118, 72, 41, 103, 164, 10, - 149, 88, 134, 209, 179, 57, 119, 194, 26, 73, 165, 150, 104, 42, 135, 11, - 180, 120, 89, 225, 195, 58, 27, 210, 151, 181, 166, 74, 43, 105, 12, 136, - 90, 59, 241, 121, 28, 196, 167, 211, 152, 44, 182, 137, 75, 13, 226, 106, - 122, 60, 197, 91, 168, 29, 183, 153, 14, 76, 212, 138, 45, 107, 15, 198, - 92, 227, 169, 30, 123, 154, 61, 242, 184, 213, 139, 46, 77, 31, 108, 170, - 199, 185, 124, 228, 93, 155, 214, 62, 140, 243, 78, 47, 200, 109, 186, 171, - 201, 94, 63, 215, 229, 156, 79, 125, 141, 110, 216, 187, 172, 244, 202, 230, - 217, 95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233, - 203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250, - 235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255, -}; - -static const int16_t vp9_default_scan_32x32[1024] = { - 0, 1, 32, 2, 33, 64, 3, 34, 65, 4, 96, 35, 66, 5, 36, 97, 67, 128, 98, 68, 37, 6, 129, 99, 7, 160, 69, 38, 130, 100, 161, 131, - 39, 70, 8, 101, 162, 132, 192, 71, 40, 9, 102, 163, 133, 193, 72, 224, 103, 41, 164, 10, 194, 134, 165, 73, 104, 135, 225, 42, 195, 11, 256, 166, - 226, 196, 74, 105, 136, 43, 12, 167, 197, 227, 257, 75, 106, 137, 228, 44, 198, 168, 258, 288, 13, 229, 76, 107, 199, 138, 259, 169, 289, 45, 230, 260, - 200, 108, 14, 170, 139, 320, 290, 77, 231, 261, 46, 201, 140, 291, 109, 232, 321, 262, 171, 78, 292, 15, 322, 202, 263, 352, 172, 293, 233, 141, 323, 110, - 47, 203, 264, 234, 294, 353, 324, 16, 79, 204, 265, 295, 325, 173, 354, 142, 235, 384, 48, 296, 111, 266, 355, 326, 80, 17, 205, 236, 174, 356, 385, 327, - 143, 297, 267, 357, 386, 112, 49, 328, 298, 206, 416, 237, 358, 387, 81, 175, 18, 329, 359, 388, 299, 330, 389, 113, 417, 238, 360, 50, 207, 418, 390, 331, - 19, 448, 361, 82, 419, 391, 239, 51, 362, 420, 114, 449, 480, 421, 83, 363, 450, 422, 512, 451, 423, 115, 452, 481, 453, 482, 454, 544, 483, 455, 513, 484, - 514, 485, 515, 486, 545, 576, 487, 546, 547, 608, 577, 578, 579, 609, 610, 611, 20, 144, 268, 392, 516, 640, 21, 52, 145, 176, 269, 300, 393, 424, 517, 548, - 641, 672, 22, 53, 84, 146, 177, 208, 270, 301, 332, 394, 425, 456, 518, 549, 580, 642, 673, 704, 23, 54, 85, 116, 147, 178, 209, 240, 271, 302, 333, 364, - 395, 426, 457, 488, 519, 550, 581, 612, 643, 674, 705, 736, 55, 86, 117, 179, 210, 241, 303, 334, 365, 427, 458, 489, 551, 582, 613, 675, 706, 737, 87, 118, - 211, 242, 335, 366, 459, 490, 583, 614, 707, 738, 119, 243, 367, 491, 615, 739, 24, 148, 272, 396, 520, 644, 768, 25, 56, 149, 180, 273, 304, 397, 428, 521, - 552, 645, 676, 769, 800, 26, 57, 88, 150, 181, 212, 274, 305, 336, 398, 429, 460, 522, 553, 584, 646, 677, 708, 770, 801, 832, 27, 58, 89, 120, 151, 182, - 213, 244, 275, 306, 337, 368, 399, 430, 461, 492, 523, 554, 585, 616, 647, 678, 709, 740, 771, 802, 833, 864, 59, 90, 121, 183, 214, 245, 307, 338, 369, 431, - 462, 493, 555, 586, 617, 679, 710, 741, 803, 834, 865, 91, 122, 215, 246, 339, 370, 463, 494, 587, 618, 711, 742, 835, 866, 123, 247, 371, 495, 619, 743, 867, - 28, 152, 276, 400, 524, 648, 772, 896, 29, 60, 153, 184, 277, 308, 401, 432, 525, 556, 649, 680, 773, 804, 897, 928, 30, 61, 92, 154, 185, 216, 278, 309, - 340, 402, 433, 464, 526, 557, 588, 650, 681, 712, 774, 805, 836, 898, 929, 960, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, - 527, 558, 589, 620, 651, 682, 713, 744, 775, 806, 837, 868, 899, 930, 961, 992, 63, 94, 125, 187, 218, 249, 311, 342, 373, 435, 466, 497, 559, 590, 621, 683, - 714, 745, 807, 838, 869, 931, 962, 993, 95, 126, 219, 250, 343, 374, 467, 498, 591, 622, 715, 746, 839, 870, 963, 994, 127, 251, 375, 499, 623, 747, 871, 995, - 156, 280, 404, 528, 652, 776, 900, 157, 188, 281, 312, 405, 436, 529, 560, 653, 684, 777, 808, 901, 932, 158, 189, 220, 282, 313, 344, 406, 437, 468, 530, 561, - 592, 654, 685, 716, 778, 809, 840, 902, 933, 964, 159, 190, 221, 252, 283, 314, 345, 376, 407, 438, 469, 500, 531, 562, 593, 624, 655, 686, 717, 748, 779, 810, - 841, 872, 903, 934, 965, 996, 191, 222, 253, 315, 346, 377, 439, 470, 501, 563, 594, 625, 687, 718, 749, 811, 842, 873, 935, 966, 997, 223, 254, 347, 378, 471, - 502, 595, 626, 719, 750, 843, 874, 967, 998, 255, 379, 503, 627, 751, 875, 999, 284, 408, 532, 656, 780, 904, 285, 316, 409, 440, 533, 564, 657, 688, 781, 812, - 905, 936, 286, 317, 348, 410, 441, 472, 534, 565, 596, 658, 689, 720, 782, 813, 844, 906, 937, 968, 287, 318, 349, 380, 411, 442, 473, 504, 535, 566, 597, 628, - 659, 690, 721, 752, 783, 814, 845, 876, 907, 938, 969, 1000, 319, 350, 381, 443, 474, 505, 567, 598, 629, 691, 722, 753, 815, 846, 877, 939, 970, 1001, 351, 382, - 475, 506, 599, 630, 723, 754, 847, 878, 971, 1002, 383, 507, 631, 755, 879, 1003, 412, 536, 660, 784, 908, 413, 444, 537, 568, 661, 692, 785, 816, 909, 940, 414, - 445, 476, 538, 569, 600, 662, 693, 724, 786, 817, 848, 910, 941, 972, 415, 446, 477, 508, 539, 570, 601, 632, 663, 694, 725, 756, 787, 818, 849, 880, 911, 942, - 973, 1004, 447, 478, 509, 571, 602, 633, 695, 726, 757, 819, 850, 881, 943, 974, 1005, 479, 510, 603, 634, 727, 758, 851, 882, 975, 1006, 511, 635, 759, 883, 1007, - 540, 664, 788, 912, 541, 572, 665, 696, 789, 820, 913, 944, 542, 573, 604, 666, 697, 728, 790, 821, 852, 914, 945, 976, 543, 574, 605, 636, 667, 698, 729, 760, - 791, 822, 853, 884, 915, 946, 977, 1008, 575, 606, 637, 699, 730, 761, 823, 854, 885, 947, 978, 1009, 607, 638, 731, 762, 855, 886, 979, 1010, 639, 763, 887, 1011, - 668, 792, 916, 669, 700, 793, 824, 917, 948, 670, 701, 732, 794, 825, 856, 918, 949, 980, 671, 702, 733, 764, 795, 826, 857, 888, 919, 950, 981, 1012, 703, 734, - 765, 827, 858, 889, 951, 982, 1013, 735, 766, 859, 890, 983, 1014, 767, 891, 1015, 796, 920, 797, 828, 921, 952, 798, 829, 860, 922, 953, 984, 799, 830, 861, 892, - 923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, -}; - -static const int16_t * const vp9_scans[5][4] = { - { - vp9_default_scan_4x4, vp9_col_scan_4x4, - vp9_row_scan_4x4, vp9_default_scan_4x4 - }, { - vp9_default_scan_8x8, vp9_col_scan_8x8, - vp9_row_scan_8x8, vp9_default_scan_8x8 - }, { - vp9_default_scan_16x16, vp9_col_scan_16x16, - vp9_row_scan_16x16, vp9_default_scan_16x16 - }, { - vp9_default_scan_32x32, vp9_default_scan_32x32, - vp9_default_scan_32x32, vp9_default_scan_32x32 - }, { // lossless - vp9_default_scan_4x4, vp9_default_scan_4x4, - vp9_default_scan_4x4, vp9_default_scan_4x4 - } -}; - -static const int16_t vp9_default_scan_4x4_nb[16][2] = { - { 0, 0 }, { 0, 0 }, { 4, 1 }, { 1, 1 }, - { 4, 4 }, { 2, 2 }, { 5, 2 }, { 8, 8 }, - { 8, 5 }, { 6, 3 }, { 9, 6 }, { 12, 9 }, - { 10, 7 }, { 13, 10 }, { 14, 11 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_4x4_nb[16][2] = { - { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, - { 4, 4 }, { 5, 5 }, { 4, 4 }, { 6, 6 }, - { 8, 8 }, { 9, 9 }, { 8, 8 }, { 12, 12 }, - { 10, 10 }, { 13, 13 }, { 14, 14 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_4x4_nb[16][2] = { - { 0, 0 }, { 0, 0 }, { 4, 4 }, { 1, 1 }, - { 8, 8 }, { 5, 5 }, { 1, 1 }, { 2, 2 }, - { 9, 9 }, { 2, 2 }, { 6, 6 }, { 3, 3 }, - { 10, 10 }, { 7, 7 }, { 11, 11 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_8x8_nb[64][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 8, 1 }, - { 8, 8 }, { 9, 2 }, { 2, 2 }, { 16, 9 }, - { 16, 16 }, { 17, 10 }, { 10, 3 }, { 3, 3 }, - { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11, 4 }, - { 25, 18 }, { 4, 4 }, { 32, 25 }, { 19, 12 }, - { 26, 19 }, { 32, 32 }, { 12, 5 }, { 33, 26 }, - { 5, 5 }, { 40, 33 }, { 27, 20 }, { 20, 13 }, - { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13, 6 }, - { 6, 6 }, { 35, 28 }, { 28, 21 }, { 42, 35 }, - { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14, 7 }, - { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 }, - { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 }, - { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 }, - { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 }, - { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 }, - { 54, 47 }, { 61, 54 }, { 62, 55 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_8x8_nb[64][2] = { - { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, - { 8, 8 }, { 3, 3 }, { 9, 9 }, { 8, 8 }, - { 4, 4 }, { 10, 10 }, { 16, 16 }, { 11, 11 }, - { 17, 17 }, { 5, 5 }, { 16, 16 }, { 18, 18 }, - { 12, 12 }, { 24, 24 }, { 6, 6 }, { 25, 25 }, - { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 }, - { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 }, - { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 }, - { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 }, - { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 }, - { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 }, - { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 }, - { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 }, - { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 }, - { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 }, - { 54, 54 }, { 61, 61 }, { 62, 62 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_8x8_nb[64][2] = { - { 0, 0 }, { 8, 8 }, { 0, 0 }, { 1, 1 }, - { 16, 16 }, { 1, 1 }, { 9, 9 }, { 24, 24 }, - { 2, 2 }, { 17, 17 }, { 2, 2 }, { 32, 32 }, - { 10, 10 }, { 3, 3 }, { 25, 25 }, { 18, 18 }, - { 11, 11 }, { 3, 3 }, { 40, 40 }, { 33, 33 }, - { 26, 26 }, { 4, 4 }, { 19, 19 }, { 48, 48 }, - { 12, 12 }, { 4, 4 }, { 34, 34 }, { 27, 27 }, - { 5, 5 }, { 41, 41 }, { 20, 20 }, { 5, 5 }, - { 13, 13 }, { 35, 35 }, { 28, 28 }, { 6, 6 }, - { 42, 42 }, { 21, 21 }, { 49, 49 }, { 6, 6 }, - { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 }, - { 7, 7 }, { 50, 50 }, { 22, 22 }, { 15, 15 }, - { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 }, - { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 }, - { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 }, - { 54, 54 }, { 47, 47 }, { 55, 55 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_16x16_nb[256][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 16, 1 }, - { 16, 16 }, { 2, 2 }, { 17, 2 }, { 32, 17 }, - { 32, 32 }, { 3, 3 }, { 33, 18 }, { 18, 3 }, - { 48, 33 }, { 19, 4 }, { 4, 4 }, { 34, 19 }, - { 48, 48 }, { 49, 34 }, { 35, 20 }, { 64, 49 }, - { 20, 5 }, { 5, 5 }, { 50, 35 }, { 64, 64 }, - { 65, 50 }, { 36, 21 }, { 21, 6 }, { 51, 36 }, - { 6, 6 }, { 80, 65 }, { 66, 51 }, { 37, 22 }, - { 81, 66 }, { 52, 37 }, { 22, 7 }, { 80, 80 }, - { 67, 52 }, { 7, 7 }, { 82, 67 }, { 96, 81 }, - { 53, 38 }, { 38, 23 }, { 68, 53 }, { 96, 96 }, - { 23, 8 }, { 97, 82 }, { 83, 68 }, { 69, 54 }, - { 54, 39 }, { 8, 8 }, { 39, 24 }, { 84, 69 }, - { 98, 83 }, { 112, 97 }, { 112, 112 }, { 24, 9 }, - { 113, 98 }, { 99, 84 }, { 70, 55 }, { 85, 70 }, - { 55, 40 }, { 9, 9 }, { 40, 25 }, { 114, 99 }, - { 100, 85 }, { 128, 113 }, { 115, 100 }, { 71, 56 }, - { 86, 71 }, { 25, 10 }, { 129, 114 }, { 128, 128 }, - { 101, 86 }, { 56, 41 }, { 10, 10 }, { 41, 26 }, - { 116, 101 }, { 130, 115 }, { 144, 129 }, { 87, 72 }, - { 102, 87 }, { 26, 11 }, { 72, 57 }, { 131, 116 }, - { 117, 102 }, { 145, 130 }, { 57, 42 }, { 144, 144 }, - { 11, 11 }, { 42, 27 }, { 132, 117 }, { 146, 131 }, - { 103, 88 }, { 88, 73 }, { 118, 103 }, { 160, 145 }, - { 73, 58 }, { 147, 132 }, { 133, 118 }, { 27, 12 }, - { 161, 146 }, { 58, 43 }, { 12, 12 }, { 160, 160 }, - { 119, 104 }, { 148, 133 }, { 89, 74 }, { 134, 119 }, - { 104, 89 }, { 162, 147 }, { 43, 28 }, { 74, 59 }, - { 176, 161 }, { 163, 148 }, { 28, 13 }, { 149, 134 }, - { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 }, - { 13, 13 }, { 105, 90 }, { 59, 44 }, { 90, 75 }, - { 150, 135 }, { 44, 29 }, { 178, 163 }, { 176, 176 }, - { 136, 121 }, { 165, 150 }, { 121, 106 }, { 75, 60 }, - { 179, 164 }, { 151, 136 }, { 29, 14 }, { 60, 45 }, - { 14, 14 }, { 106, 91 }, { 166, 151 }, { 180, 165 }, - { 192, 177 }, { 91, 76 }, { 192, 192 }, { 45, 30 }, - { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 }, - { 76, 61 }, { 167, 152 }, { 181, 166 }, { 30, 15 }, - { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107, 92 }, - { 138, 123 }, { 61, 46 }, { 153, 138 }, { 46, 31 }, - { 195, 180 }, { 92, 77 }, { 168, 153 }, { 209, 194 }, - { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 }, - { 210, 195 }, { 77, 62 }, { 108, 93 }, { 169, 154 }, - { 154, 139 }, { 62, 47 }, { 197, 182 }, { 211, 196 }, - { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 }, - { 93, 78 }, { 198, 183 }, { 124, 109 }, { 78, 63 }, - { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 }, - { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109, 94 }, - { 226, 211 }, { 140, 125 }, { 94, 79 }, { 240, 225 }, - { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 }, - { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 }, - { 228, 213 }, { 110, 95 }, { 215, 200 }, { 242, 227 }, - { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 }, - { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 }, - { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 }, - { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 }, - { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 }, - { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 }, - { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 }, - { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 }, - { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 }, - { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 }, - { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 }, - { 238, 223 }, { 253, 238 }, { 254, 239 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_16x16_nb[256][2] = { - { 0, 0 }, { 1, 1 }, { 2, 2 }, { 0, 0 }, - { 3, 3 }, { 16, 16 }, { 4, 4 }, { 17, 17 }, - { 5, 5 }, { 18, 18 }, { 16, 16 }, { 19, 19 }, - { 6, 6 }, { 32, 32 }, { 20, 20 }, { 33, 33 }, - { 7, 7 }, { 34, 34 }, { 21, 21 }, { 32, 32 }, - { 35, 35 }, { 8, 8 }, { 48, 48 }, { 22, 22 }, - { 49, 49 }, { 36, 36 }, { 9, 9 }, { 37, 37 }, - { 50, 50 }, { 23, 23 }, { 48, 48 }, { 51, 51 }, - { 10, 10 }, { 64, 64 }, { 38, 38 }, { 24, 24 }, - { 52, 52 }, { 65, 65 }, { 53, 53 }, { 39, 39 }, - { 66, 66 }, { 11, 11 }, { 64, 64 }, { 25, 25 }, - { 67, 67 }, { 54, 54 }, { 80, 80 }, { 40, 40 }, - { 68, 68 }, { 12, 12 }, { 26, 26 }, { 81, 81 }, - { 55, 55 }, { 69, 69 }, { 82, 82 }, { 41, 41 }, - { 13, 13 }, { 83, 83 }, { 80, 80 }, { 70, 70 }, - { 27, 27 }, { 56, 56 }, { 84, 84 }, { 96, 96 }, - { 14, 14 }, { 71, 71 }, { 97, 97 }, { 42, 42 }, - { 85, 85 }, { 57, 57 }, { 98, 98 }, { 28, 28 }, - { 86, 86 }, { 99, 99 }, { 96, 96 }, { 72, 72 }, - { 43, 43 }, { 100, 100 }, { 58, 58 }, { 29, 29 }, - { 112, 112 }, { 87, 87 }, { 113, 113 }, { 73, 73 }, - { 112, 112 }, { 101, 101 }, { 44, 44 }, { 30, 30 }, - { 114, 114 }, { 59, 59 }, { 102, 102 }, { 88, 88 }, - { 115, 115 }, { 74, 74 }, { 128, 128 }, { 116, 116 }, - { 45, 45 }, { 103, 103 }, { 89, 89 }, { 60, 60 }, - { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 }, - { 104, 104 }, { 75, 75 }, { 46, 46 }, { 118, 118 }, - { 128, 128 }, { 90, 90 }, { 61, 61 }, { 132, 132 }, - { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 }, - { 133, 133 }, { 76, 76 }, { 146, 146 }, { 120, 120 }, - { 91, 91 }, { 134, 134 }, { 147, 147 }, { 62, 62 }, - { 106, 106 }, { 135, 135 }, { 121, 121 }, { 92, 92 }, - { 148, 148 }, { 144, 144 }, { 77, 77 }, { 149, 149 }, - { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 }, - { 150, 150 }, { 122, 122 }, { 78, 78 }, { 137, 137 }, - { 162, 162 }, { 151, 151 }, { 93, 93 }, { 163, 163 }, - { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 }, - { 138, 138 }, { 160, 160 }, { 165, 165 }, { 94, 94 }, - { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 }, - { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 }, - { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 }, - { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 }, - { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 }, - { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 }, - { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 }, - { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 }, - { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 }, - { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 }, - { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 }, - { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 }, - { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 }, - { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 }, - { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 }, - { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 }, - { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 }, - { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 }, - { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 }, - { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 }, - { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 }, - { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 }, - { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 }, - { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 }, - { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 }, - { 252, 252 }, { 253, 253 }, { 254, 254 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_16x16_nb[256][2] = { - { 0, 0 }, { 16, 16 }, { 0, 0 }, { 32, 32 }, - { 1, 1 }, { 48, 48 }, { 17, 17 }, { 1, 1 }, - { 64, 64 }, { 2, 2 }, { 33, 33 }, { 80, 80 }, - { 18, 18 }, { 2, 2 }, { 49, 49 }, { 3, 3 }, - { 96, 96 }, { 34, 34 }, { 65, 65 }, { 19, 19 }, - { 3, 3 }, { 112, 112 }, { 50, 50 }, { 4, 4 }, - { 81, 81 }, { 35, 35 }, { 66, 66 }, { 4, 4 }, - { 128, 128 }, { 20, 20 }, { 51, 51 }, { 97, 97 }, - { 82, 82 }, { 5, 5 }, { 36, 36 }, { 144, 144 }, - { 67, 67 }, { 113, 113 }, { 21, 21 }, { 52, 52 }, - { 5, 5 }, { 98, 98 }, { 160, 160 }, { 83, 83 }, - { 37, 37 }, { 6, 6 }, { 68, 68 }, { 129, 129 }, - { 22, 22 }, { 53, 53 }, { 114, 114 }, { 6, 6 }, - { 99, 99 }, { 176, 176 }, { 84, 84 }, { 38, 38 }, - { 7, 7 }, { 69, 69 }, { 145, 145 }, { 130, 130 }, - { 115, 115 }, { 23, 23 }, { 54, 54 }, { 192, 192 }, - { 100, 100 }, { 7, 7 }, { 85, 85 }, { 161, 161 }, - { 39, 39 }, { 70, 70 }, { 8, 8 }, { 146, 146 }, - { 131, 131 }, { 116, 116 }, { 55, 55 }, { 208, 208 }, - { 101, 101 }, { 24, 24 }, { 86, 86 }, { 8, 8 }, - { 132, 132 }, { 40, 40 }, { 71, 71 }, { 177, 177 }, - { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 }, - { 9, 9 }, { 102, 102 }, { 56, 56 }, { 25, 25 }, - { 87, 87 }, { 148, 148 }, { 9, 9 }, { 133, 133 }, - { 72, 72 }, { 118, 118 }, { 193, 193 }, { 163, 163 }, - { 41, 41 }, { 103, 103 }, { 178, 178 }, { 10, 10 }, - { 57, 57 }, { 149, 149 }, { 134, 134 }, { 88, 88 }, - { 26, 26 }, { 119, 119 }, { 10, 10 }, { 164, 164 }, - { 104, 104 }, { 73, 73 }, { 209, 209 }, { 179, 179 }, - { 42, 42 }, { 11, 11 }, { 194, 194 }, { 135, 135 }, - { 165, 165 }, { 150, 150 }, { 58, 58 }, { 27, 27 }, - { 89, 89 }, { 11, 11 }, { 120, 120 }, { 74, 74 }, - { 43, 43 }, { 225, 225 }, { 105, 105 }, { 12, 12 }, - { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 }, - { 28, 28 }, { 166, 166 }, { 121, 121 }, { 59, 59 }, - { 12, 12 }, { 210, 210 }, { 90, 90 }, { 106, 106 }, - { 44, 44 }, { 181, 181 }, { 75, 75 }, { 152, 152 }, - { 13, 13 }, { 167, 167 }, { 137, 137 }, { 13, 13 }, - { 60, 60 }, { 196, 196 }, { 122, 122 }, { 29, 29 }, - { 91, 91 }, { 14, 14 }, { 182, 182 }, { 76, 76 }, - { 211, 211 }, { 153, 153 }, { 14, 14 }, { 107, 107 }, - { 138, 138 }, { 45, 45 }, { 226, 226 }, { 168, 168 }, - { 197, 197 }, { 123, 123 }, { 30, 30 }, { 61, 61 }, - { 15, 15 }, { 92, 92 }, { 154, 154 }, { 183, 183 }, - { 169, 169 }, { 108, 108 }, { 212, 212 }, { 77, 77 }, - { 139, 139 }, { 198, 198 }, { 46, 46 }, { 124, 124 }, - { 227, 227 }, { 62, 62 }, { 31, 31 }, { 184, 184 }, - { 93, 93 }, { 170, 170 }, { 155, 155 }, { 185, 185 }, - { 78, 78 }, { 47, 47 }, { 199, 199 }, { 213, 213 }, - { 140, 140 }, { 63, 63 }, { 109, 109 }, { 125, 125 }, - { 94, 94 }, { 200, 200 }, { 171, 171 }, { 156, 156 }, - { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 }, - { 79, 79 }, { 141, 141 }, { 110, 110 }, { 229, 229 }, - { 95, 95 }, { 126, 126 }, { 215, 215 }, { 172, 172 }, - { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 }, - { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 }, - { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 }, - { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 }, - { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 }, - { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 }, - { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 }, - { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 }, - { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 }, - { 238, 238 }, { 223, 223 }, { 239, 239 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_32x32_nb[1024][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 32, 1 }, - { 32, 32 }, { 2, 2 }, { 33, 2 }, { 64, 33 }, - { 3, 3 }, { 64, 64 }, { 34, 3 }, { 65, 34 }, - { 4, 4 }, { 35, 4 }, { 96, 65 }, { 66, 35 }, - { 96, 96 }, { 97, 66 }, { 67, 36 }, { 36, 5 }, - { 5, 5 }, { 128, 97 }, { 98, 67 }, { 6, 6 }, - { 128, 128 }, { 68, 37 }, { 37, 6 }, { 129, 98 }, - { 99, 68 }, { 160, 129 }, { 130, 99 }, { 38, 7 }, - { 69, 38 }, { 7, 7 }, { 100, 69 }, { 161, 130 }, - { 131, 100 }, { 160, 160 }, { 70, 39 }, { 39, 8 }, - { 8, 8 }, { 101, 70 }, { 162, 131 }, { 132, 101 }, - { 192, 161 }, { 71, 40 }, { 192, 192 }, { 102, 71 }, - { 40, 9 }, { 163, 132 }, { 9, 9 }, { 193, 162 }, - { 133, 102 }, { 164, 133 }, { 72, 41 }, { 103, 72 }, - { 134, 103 }, { 224, 193 }, { 41, 10 }, { 194, 163 }, - { 10, 10 }, { 224, 224 }, { 165, 134 }, { 225, 194 }, - { 195, 164 }, { 73, 42 }, { 104, 73 }, { 135, 104 }, - { 42, 11 }, { 11, 11 }, { 166, 135 }, { 196, 165 }, - { 226, 195 }, { 256, 225 }, { 74, 43 }, { 105, 74 }, - { 136, 105 }, { 227, 196 }, { 43, 12 }, { 197, 166 }, - { 167, 136 }, { 257, 226 }, { 256, 256 }, { 12, 12 }, - { 228, 197 }, { 75, 44 }, { 106, 75 }, { 198, 167 }, - { 137, 106 }, { 258, 227 }, { 168, 137 }, { 288, 257 }, - { 44, 13 }, { 229, 198 }, { 259, 228 }, { 199, 168 }, - { 107, 76 }, { 13, 13 }, { 169, 138 }, { 138, 107 }, - { 288, 288 }, { 289, 258 }, { 76, 45 }, { 230, 199 }, - { 260, 229 }, { 45, 14 }, { 200, 169 }, { 139, 108 }, - { 290, 259 }, { 108, 77 }, { 231, 200 }, { 320, 289 }, - { 261, 230 }, { 170, 139 }, { 77, 46 }, { 291, 260 }, - { 14, 14 }, { 321, 290 }, { 201, 170 }, { 262, 231 }, - { 320, 320 }, { 171, 140 }, { 292, 261 }, { 232, 201 }, - { 140, 109 }, { 322, 291 }, { 109, 78 }, { 46, 15 }, - { 202, 171 }, { 263, 232 }, { 233, 202 }, { 293, 262 }, - { 352, 321 }, { 323, 292 }, { 15, 15 }, { 78, 47 }, - { 203, 172 }, { 264, 233 }, { 294, 263 }, { 324, 293 }, - { 172, 141 }, { 353, 322 }, { 141, 110 }, { 234, 203 }, - { 352, 352 }, { 47, 16 }, { 295, 264 }, { 110, 79 }, - { 265, 234 }, { 354, 323 }, { 325, 294 }, { 79, 48 }, - { 16, 16 }, { 204, 173 }, { 235, 204 }, { 173, 142 }, - { 355, 324 }, { 384, 353 }, { 326, 295 }, { 142, 111 }, - { 296, 265 }, { 266, 235 }, { 356, 325 }, { 385, 354 }, - { 111, 80 }, { 48, 17 }, { 327, 296 }, { 297, 266 }, - { 205, 174 }, { 384, 384 }, { 236, 205 }, { 357, 326 }, - { 386, 355 }, { 80, 49 }, { 174, 143 }, { 17, 17 }, - { 328, 297 }, { 358, 327 }, { 387, 356 }, { 298, 267 }, - { 329, 298 }, { 388, 357 }, { 112, 81 }, { 416, 385 }, - { 237, 206 }, { 359, 328 }, { 49, 18 }, { 206, 175 }, - { 417, 386 }, { 389, 358 }, { 330, 299 }, { 18, 18 }, - { 416, 416 }, { 360, 329 }, { 81, 50 }, { 418, 387 }, - { 390, 359 }, { 238, 207 }, { 50, 19 }, { 361, 330 }, - { 419, 388 }, { 113, 82 }, { 448, 417 }, { 448, 448 }, - { 420, 389 }, { 82, 51 }, { 362, 331 }, { 449, 418 }, - { 421, 390 }, { 480, 480 }, { 450, 419 }, { 422, 391 }, - { 114, 83 }, { 451, 420 }, { 480, 449 }, { 452, 421 }, - { 481, 450 }, { 453, 422 }, { 512, 512 }, { 482, 451 }, - { 454, 423 }, { 512, 481 }, { 483, 452 }, { 513, 482 }, - { 484, 453 }, { 514, 483 }, { 485, 454 }, { 544, 513 }, - { 544, 544 }, { 486, 455 }, { 545, 514 }, { 546, 515 }, - { 576, 576 }, { 576, 545 }, { 577, 546 }, { 578, 547 }, - { 608, 577 }, { 609, 578 }, { 610, 579 }, { 19, 19 }, - { 143, 112 }, { 267, 236 }, { 391, 360 }, { 515, 484 }, - { 608, 608 }, { 20, 20 }, { 51, 20 }, { 144, 113 }, - { 175, 144 }, { 268, 237 }, { 299, 268 }, { 392, 361 }, - { 423, 392 }, { 516, 485 }, { 547, 516 }, { 640, 609 }, - { 640, 640 }, { 21, 21 }, { 52, 21 }, { 83, 52 }, - { 145, 114 }, { 176, 145 }, { 207, 176 }, { 269, 238 }, - { 300, 269 }, { 331, 300 }, { 393, 362 }, { 424, 393 }, - { 455, 424 }, { 517, 486 }, { 548, 517 }, { 579, 548 }, - { 641, 610 }, { 672, 641 }, { 672, 672 }, { 22, 22 }, - { 53, 22 }, { 84, 53 }, { 115, 84 }, { 146, 115 }, - { 177, 146 }, { 208, 177 }, { 239, 208 }, { 270, 239 }, - { 301, 270 }, { 332, 301 }, { 363, 332 }, { 394, 363 }, - { 425, 394 }, { 456, 425 }, { 487, 456 }, { 518, 487 }, - { 549, 518 }, { 580, 549 }, { 611, 580 }, { 642, 611 }, - { 673, 642 }, { 704, 673 }, { 704, 704 }, { 54, 23 }, - { 85, 54 }, { 116, 85 }, { 178, 147 }, { 209, 178 }, - { 240, 209 }, { 302, 271 }, { 333, 302 }, { 364, 333 }, - { 426, 395 }, { 457, 426 }, { 488, 457 }, { 550, 519 }, - { 581, 550 }, { 612, 581 }, { 674, 643 }, { 705, 674 }, - { 736, 705 }, { 86, 55 }, { 117, 86 }, { 210, 179 }, - { 241, 210 }, { 334, 303 }, { 365, 334 }, { 458, 427 }, - { 489, 458 }, { 582, 551 }, { 613, 582 }, { 706, 675 }, - { 737, 706 }, { 118, 87 }, { 242, 211 }, { 366, 335 }, - { 490, 459 }, { 614, 583 }, { 738, 707 }, { 23, 23 }, - { 147, 116 }, { 271, 240 }, { 395, 364 }, { 519, 488 }, - { 643, 612 }, { 736, 736 }, { 24, 24 }, { 55, 24 }, - { 148, 117 }, { 179, 148 }, { 272, 241 }, { 303, 272 }, - { 396, 365 }, { 427, 396 }, { 520, 489 }, { 551, 520 }, - { 644, 613 }, { 675, 644 }, { 768, 737 }, { 768, 768 }, - { 25, 25 }, { 56, 25 }, { 87, 56 }, { 149, 118 }, - { 180, 149 }, { 211, 180 }, { 273, 242 }, { 304, 273 }, - { 335, 304 }, { 397, 366 }, { 428, 397 }, { 459, 428 }, - { 521, 490 }, { 552, 521 }, { 583, 552 }, { 645, 614 }, - { 676, 645 }, { 707, 676 }, { 769, 738 }, { 800, 769 }, - { 800, 800 }, { 26, 26 }, { 57, 26 }, { 88, 57 }, - { 119, 88 }, { 150, 119 }, { 181, 150 }, { 212, 181 }, - { 243, 212 }, { 274, 243 }, { 305, 274 }, { 336, 305 }, - { 367, 336 }, { 398, 367 }, { 429, 398 }, { 460, 429 }, - { 491, 460 }, { 522, 491 }, { 553, 522 }, { 584, 553 }, - { 615, 584 }, { 646, 615 }, { 677, 646 }, { 708, 677 }, - { 739, 708 }, { 770, 739 }, { 801, 770 }, { 832, 801 }, - { 832, 832 }, { 58, 27 }, { 89, 58 }, { 120, 89 }, - { 182, 151 }, { 213, 182 }, { 244, 213 }, { 306, 275 }, - { 337, 306 }, { 368, 337 }, { 430, 399 }, { 461, 430 }, - { 492, 461 }, { 554, 523 }, { 585, 554 }, { 616, 585 }, - { 678, 647 }, { 709, 678 }, { 740, 709 }, { 802, 771 }, - { 833, 802 }, { 864, 833 }, { 90, 59 }, { 121, 90 }, - { 214, 183 }, { 245, 214 }, { 338, 307 }, { 369, 338 }, - { 462, 431 }, { 493, 462 }, { 586, 555 }, { 617, 586 }, - { 710, 679 }, { 741, 710 }, { 834, 803 }, { 865, 834 }, - { 122, 91 }, { 246, 215 }, { 370, 339 }, { 494, 463 }, - { 618, 587 }, { 742, 711 }, { 866, 835 }, { 27, 27 }, - { 151, 120 }, { 275, 244 }, { 399, 368 }, { 523, 492 }, - { 647, 616 }, { 771, 740 }, { 864, 864 }, { 28, 28 }, - { 59, 28 }, { 152, 121 }, { 183, 152 }, { 276, 245 }, - { 307, 276 }, { 400, 369 }, { 431, 400 }, { 524, 493 }, - { 555, 524 }, { 648, 617 }, { 679, 648 }, { 772, 741 }, - { 803, 772 }, { 896, 865 }, { 896, 896 }, { 29, 29 }, - { 60, 29 }, { 91, 60 }, { 153, 122 }, { 184, 153 }, - { 215, 184 }, { 277, 246 }, { 308, 277 }, { 339, 308 }, - { 401, 370 }, { 432, 401 }, { 463, 432 }, { 525, 494 }, - { 556, 525 }, { 587, 556 }, { 649, 618 }, { 680, 649 }, - { 711, 680 }, { 773, 742 }, { 804, 773 }, { 835, 804 }, - { 897, 866 }, { 928, 897 }, { 928, 928 }, { 30, 30 }, - { 61, 30 }, { 92, 61 }, { 123, 92 }, { 154, 123 }, - { 185, 154 }, { 216, 185 }, { 247, 216 }, { 278, 247 }, - { 309, 278 }, { 340, 309 }, { 371, 340 }, { 402, 371 }, - { 433, 402 }, { 464, 433 }, { 495, 464 }, { 526, 495 }, - { 557, 526 }, { 588, 557 }, { 619, 588 }, { 650, 619 }, - { 681, 650 }, { 712, 681 }, { 743, 712 }, { 774, 743 }, - { 805, 774 }, { 836, 805 }, { 867, 836 }, { 898, 867 }, - { 929, 898 }, { 960, 929 }, { 960, 960 }, { 62, 31 }, - { 93, 62 }, { 124, 93 }, { 186, 155 }, { 217, 186 }, - { 248, 217 }, { 310, 279 }, { 341, 310 }, { 372, 341 }, - { 434, 403 }, { 465, 434 }, { 496, 465 }, { 558, 527 }, - { 589, 558 }, { 620, 589 }, { 682, 651 }, { 713, 682 }, - { 744, 713 }, { 806, 775 }, { 837, 806 }, { 868, 837 }, - { 930, 899 }, { 961, 930 }, { 992, 961 }, { 94, 63 }, - { 125, 94 }, { 218, 187 }, { 249, 218 }, { 342, 311 }, - { 373, 342 }, { 466, 435 }, { 497, 466 }, { 590, 559 }, - { 621, 590 }, { 714, 683 }, { 745, 714 }, { 838, 807 }, - { 869, 838 }, { 962, 931 }, { 993, 962 }, { 126, 95 }, - { 250, 219 }, { 374, 343 }, { 498, 467 }, { 622, 591 }, - { 746, 715 }, { 870, 839 }, { 994, 963 }, { 155, 124 }, - { 279, 248 }, { 403, 372 }, { 527, 496 }, { 651, 620 }, - { 775, 744 }, { 899, 868 }, { 156, 125 }, { 187, 156 }, - { 280, 249 }, { 311, 280 }, { 404, 373 }, { 435, 404 }, - { 528, 497 }, { 559, 528 }, { 652, 621 }, { 683, 652 }, - { 776, 745 }, { 807, 776 }, { 900, 869 }, { 931, 900 }, - { 157, 126 }, { 188, 157 }, { 219, 188 }, { 281, 250 }, - { 312, 281 }, { 343, 312 }, { 405, 374 }, { 436, 405 }, - { 467, 436 }, { 529, 498 }, { 560, 529 }, { 591, 560 }, - { 653, 622 }, { 684, 653 }, { 715, 684 }, { 777, 746 }, - { 808, 777 }, { 839, 808 }, { 901, 870 }, { 932, 901 }, - { 963, 932 }, { 158, 127 }, { 189, 158 }, { 220, 189 }, - { 251, 220 }, { 282, 251 }, { 313, 282 }, { 344, 313 }, - { 375, 344 }, { 406, 375 }, { 437, 406 }, { 468, 437 }, - { 499, 468 }, { 530, 499 }, { 561, 530 }, { 592, 561 }, - { 623, 592 }, { 654, 623 }, { 685, 654 }, { 716, 685 }, - { 747, 716 }, { 778, 747 }, { 809, 778 }, { 840, 809 }, - { 871, 840 }, { 902, 871 }, { 933, 902 }, { 964, 933 }, - { 995, 964 }, { 190, 159 }, { 221, 190 }, { 252, 221 }, - { 314, 283 }, { 345, 314 }, { 376, 345 }, { 438, 407 }, - { 469, 438 }, { 500, 469 }, { 562, 531 }, { 593, 562 }, - { 624, 593 }, { 686, 655 }, { 717, 686 }, { 748, 717 }, - { 810, 779 }, { 841, 810 }, { 872, 841 }, { 934, 903 }, - { 965, 934 }, { 996, 965 }, { 222, 191 }, { 253, 222 }, - { 346, 315 }, { 377, 346 }, { 470, 439 }, { 501, 470 }, - { 594, 563 }, { 625, 594 }, { 718, 687 }, { 749, 718 }, - { 842, 811 }, { 873, 842 }, { 966, 935 }, { 997, 966 }, - { 254, 223 }, { 378, 347 }, { 502, 471 }, { 626, 595 }, - { 750, 719 }, { 874, 843 }, { 998, 967 }, { 283, 252 }, - { 407, 376 }, { 531, 500 }, { 655, 624 }, { 779, 748 }, - { 903, 872 }, { 284, 253 }, { 315, 284 }, { 408, 377 }, - { 439, 408 }, { 532, 501 }, { 563, 532 }, { 656, 625 }, - { 687, 656 }, { 780, 749 }, { 811, 780 }, { 904, 873 }, - { 935, 904 }, { 285, 254 }, { 316, 285 }, { 347, 316 }, - { 409, 378 }, { 440, 409 }, { 471, 440 }, { 533, 502 }, - { 564, 533 }, { 595, 564 }, { 657, 626 }, { 688, 657 }, - { 719, 688 }, { 781, 750 }, { 812, 781 }, { 843, 812 }, - { 905, 874 }, { 936, 905 }, { 967, 936 }, { 286, 255 }, - { 317, 286 }, { 348, 317 }, { 379, 348 }, { 410, 379 }, - { 441, 410 }, { 472, 441 }, { 503, 472 }, { 534, 503 }, - { 565, 534 }, { 596, 565 }, { 627, 596 }, { 658, 627 }, - { 689, 658 }, { 720, 689 }, { 751, 720 }, { 782, 751 }, - { 813, 782 }, { 844, 813 }, { 875, 844 }, { 906, 875 }, - { 937, 906 }, { 968, 937 }, { 999, 968 }, { 318, 287 }, - { 349, 318 }, { 380, 349 }, { 442, 411 }, { 473, 442 }, - { 504, 473 }, { 566, 535 }, { 597, 566 }, { 628, 597 }, - { 690, 659 }, { 721, 690 }, { 752, 721 }, { 814, 783 }, - { 845, 814 }, { 876, 845 }, { 938, 907 }, { 969, 938 }, - { 1000, 969 }, { 350, 319 }, { 381, 350 }, { 474, 443 }, - { 505, 474 }, { 598, 567 }, { 629, 598 }, { 722, 691 }, - { 753, 722 }, { 846, 815 }, { 877, 846 }, { 970, 939 }, - { 1001, 970 }, { 382, 351 }, { 506, 475 }, { 630, 599 }, - { 754, 723 }, { 878, 847 }, { 1002, 971 }, { 411, 380 }, - { 535, 504 }, { 659, 628 }, { 783, 752 }, { 907, 876 }, - { 412, 381 }, { 443, 412 }, { 536, 505 }, { 567, 536 }, - { 660, 629 }, { 691, 660 }, { 784, 753 }, { 815, 784 }, - { 908, 877 }, { 939, 908 }, { 413, 382 }, { 444, 413 }, - { 475, 444 }, { 537, 506 }, { 568, 537 }, { 599, 568 }, - { 661, 630 }, { 692, 661 }, { 723, 692 }, { 785, 754 }, - { 816, 785 }, { 847, 816 }, { 909, 878 }, { 940, 909 }, - { 971, 940 }, { 414, 383 }, { 445, 414 }, { 476, 445 }, - { 507, 476 }, { 538, 507 }, { 569, 538 }, { 600, 569 }, - { 631, 600 }, { 662, 631 }, { 693, 662 }, { 724, 693 }, - { 755, 724 }, { 786, 755 }, { 817, 786 }, { 848, 817 }, - { 879, 848 }, { 910, 879 }, { 941, 910 }, { 972, 941 }, - { 1003, 972 }, { 446, 415 }, { 477, 446 }, { 508, 477 }, - { 570, 539 }, { 601, 570 }, { 632, 601 }, { 694, 663 }, - { 725, 694 }, { 756, 725 }, { 818, 787 }, { 849, 818 }, - { 880, 849 }, { 942, 911 }, { 973, 942 }, { 1004, 973 }, - { 478, 447 }, { 509, 478 }, { 602, 571 }, { 633, 602 }, - { 726, 695 }, { 757, 726 }, { 850, 819 }, { 881, 850 }, - { 974, 943 }, { 1005, 974 }, { 510, 479 }, { 634, 603 }, - { 758, 727 }, { 882, 851 }, { 1006, 975 }, { 539, 508 }, - { 663, 632 }, { 787, 756 }, { 911, 880 }, { 540, 509 }, - { 571, 540 }, { 664, 633 }, { 695, 664 }, { 788, 757 }, - { 819, 788 }, { 912, 881 }, { 943, 912 }, { 541, 510 }, - { 572, 541 }, { 603, 572 }, { 665, 634 }, { 696, 665 }, - { 727, 696 }, { 789, 758 }, { 820, 789 }, { 851, 820 }, - { 913, 882 }, { 944, 913 }, { 975, 944 }, { 542, 511 }, - { 573, 542 }, { 604, 573 }, { 635, 604 }, { 666, 635 }, - { 697, 666 }, { 728, 697 }, { 759, 728 }, { 790, 759 }, - { 821, 790 }, { 852, 821 }, { 883, 852 }, { 914, 883 }, - { 945, 914 }, { 976, 945 }, { 1007, 976 }, { 574, 543 }, - { 605, 574 }, { 636, 605 }, { 698, 667 }, { 729, 698 }, - { 760, 729 }, { 822, 791 }, { 853, 822 }, { 884, 853 }, - { 946, 915 }, { 977, 946 }, { 1008, 977 }, { 606, 575 }, - { 637, 606 }, { 730, 699 }, { 761, 730 }, { 854, 823 }, - { 885, 854 }, { 978, 947 }, { 1009, 978 }, { 638, 607 }, - { 762, 731 }, { 886, 855 }, { 1010, 979 }, { 667, 636 }, - { 791, 760 }, { 915, 884 }, { 668, 637 }, { 699, 668 }, - { 792, 761 }, { 823, 792 }, { 916, 885 }, { 947, 916 }, - { 669, 638 }, { 700, 669 }, { 731, 700 }, { 793, 762 }, - { 824, 793 }, { 855, 824 }, { 917, 886 }, { 948, 917 }, - { 979, 948 }, { 670, 639 }, { 701, 670 }, { 732, 701 }, - { 763, 732 }, { 794, 763 }, { 825, 794 }, { 856, 825 }, - { 887, 856 }, { 918, 887 }, { 949, 918 }, { 980, 949 }, - { 1011, 980 }, { 702, 671 }, { 733, 702 }, { 764, 733 }, - { 826, 795 }, { 857, 826 }, { 888, 857 }, { 950, 919 }, - { 981, 950 }, { 1012, 981 }, { 734, 703 }, { 765, 734 }, - { 858, 827 }, { 889, 858 }, { 982, 951 }, { 1013, 982 }, - { 766, 735 }, { 890, 859 }, { 1014, 983 }, { 795, 764 }, - { 919, 888 }, { 796, 765 }, { 827, 796 }, { 920, 889 }, - { 951, 920 }, { 797, 766 }, { 828, 797 }, { 859, 828 }, - { 921, 890 }, { 952, 921 }, { 983, 952 }, { 798, 767 }, - { 829, 798 }, { 860, 829 }, { 891, 860 }, { 922, 891 }, - { 953, 922 }, { 984, 953 }, { 1015, 984 }, { 830, 799 }, - { 861, 830 }, { 892, 861 }, { 954, 923 }, { 985, 954 }, - { 1016, 985 }, { 862, 831 }, { 893, 862 }, { 986, 955 }, - { 1017, 986 }, { 894, 863 }, { 1018, 987 }, { 923, 892 }, - { 924, 893 }, { 955, 924 }, { 925, 894 }, { 956, 925 }, - { 987, 956 }, { 926, 895 }, { 957, 926 }, { 988, 957 }, - { 1019, 988 }, { 958, 927 }, { 989, 958 }, { 1020, 989 }, - { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, -}; - -static const int16_t (* const vp9_scans_nb[5][4])[2] = { - { - vp9_default_scan_4x4_nb, vp9_col_scan_4x4_nb, - vp9_row_scan_4x4_nb, vp9_default_scan_4x4_nb - }, { - vp9_default_scan_8x8_nb, vp9_col_scan_8x8_nb, - vp9_row_scan_8x8_nb, vp9_default_scan_8x8_nb - }, { - vp9_default_scan_16x16_nb, vp9_col_scan_16x16_nb, - vp9_row_scan_16x16_nb, vp9_default_scan_16x16_nb - }, { - vp9_default_scan_32x32_nb, vp9_default_scan_32x32_nb, - vp9_default_scan_32x32_nb, vp9_default_scan_32x32_nb - }, { // lossless - vp9_default_scan_4x4_nb, vp9_default_scan_4x4_nb, - vp9_default_scan_4x4_nb, vp9_default_scan_4x4_nb - } -}; - -static const uint8_t vp9_model_pareto8[256][8] = { - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 3, 86, 128, 6, 86, 23, 88, 29 }, - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 9, 86, 129, 17, 88, 61, 94, 76 }, - { 12, 86, 129, 22, 88, 77, 97, 93 }, - { 15, 87, 129, 28, 89, 93, 100, 110 }, - { 17, 87, 129, 33, 90, 105, 103, 123 }, - { 20, 88, 130, 38, 91, 118, 106, 136 }, - { 23, 88, 130, 43, 91, 128, 108, 146 }, - { 26, 89, 131, 48, 92, 139, 111, 156 }, - { 28, 89, 131, 53, 93, 147, 114, 163 }, - { 31, 90, 131, 58, 94, 156, 117, 171 }, - { 34, 90, 131, 62, 94, 163, 119, 177 }, - { 37, 90, 132, 66, 95, 171, 122, 184 }, - { 39, 90, 132, 70, 96, 177, 124, 189 }, - { 42, 91, 132, 75, 97, 183, 127, 194 }, - { 44, 91, 132, 79, 97, 188, 129, 198 }, - { 47, 92, 133, 83, 98, 193, 132, 202 }, - { 49, 92, 133, 86, 99, 197, 134, 205 }, - { 52, 93, 133, 90, 100, 201, 137, 208 }, - { 54, 93, 133, 94, 100, 204, 139, 211 }, - { 57, 94, 134, 98, 101, 208, 142, 214 }, - { 59, 94, 134, 101, 102, 211, 144, 216 }, - { 62, 94, 135, 105, 103, 214, 146, 218 }, - { 64, 94, 135, 108, 103, 216, 148, 220 }, - { 66, 95, 135, 111, 104, 219, 151, 222 }, - { 68, 95, 135, 114, 105, 221, 153, 223 }, - { 71, 96, 136, 117, 106, 224, 155, 225 }, - { 73, 96, 136, 120, 106, 225, 157, 226 }, - { 76, 97, 136, 123, 107, 227, 159, 228 }, - { 78, 97, 136, 126, 108, 229, 160, 229 }, - { 80, 98, 137, 129, 109, 231, 162, 231 }, - { 82, 98, 137, 131, 109, 232, 164, 232 }, - { 84, 98, 138, 134, 110, 234, 166, 233 }, - { 86, 98, 138, 137, 111, 235, 168, 234 }, - { 89, 99, 138, 140, 112, 236, 170, 235 }, - { 91, 99, 138, 142, 112, 237, 171, 235 }, - { 93, 100, 139, 145, 113, 238, 173, 236 }, - { 95, 100, 139, 147, 114, 239, 174, 237 }, - { 97, 101, 140, 149, 115, 240, 176, 238 }, - { 99, 101, 140, 151, 115, 241, 177, 238 }, - { 101, 102, 140, 154, 116, 242, 179, 239 }, - { 103, 102, 140, 156, 117, 242, 180, 239 }, - { 105, 103, 141, 158, 118, 243, 182, 240 }, - { 107, 103, 141, 160, 118, 243, 183, 240 }, - { 109, 104, 141, 162, 119, 244, 185, 241 }, - { 111, 104, 141, 164, 119, 244, 186, 241 }, - { 113, 104, 142, 166, 120, 245, 187, 242 }, - { 114, 104, 142, 168, 121, 245, 188, 242 }, - { 116, 105, 143, 170, 122, 246, 190, 243 }, - { 118, 105, 143, 171, 122, 246, 191, 243 }, - { 120, 106, 143, 173, 123, 247, 192, 244 }, - { 121, 106, 143, 175, 124, 247, 193, 244 }, - { 123, 107, 144, 177, 125, 248, 195, 244 }, - { 125, 107, 144, 178, 125, 248, 196, 244 }, - { 127, 108, 145, 180, 126, 249, 197, 245 }, - { 128, 108, 145, 181, 127, 249, 198, 245 }, - { 130, 109, 145, 183, 128, 249, 199, 245 }, - { 132, 109, 145, 184, 128, 249, 200, 245 }, - { 134, 110, 146, 186, 129, 250, 201, 246 }, - { 135, 110, 146, 187, 130, 250, 202, 246 }, - { 137, 111, 147, 189, 131, 251, 203, 246 }, - { 138, 111, 147, 190, 131, 251, 204, 246 }, - { 140, 112, 147, 192, 132, 251, 205, 247 }, - { 141, 112, 147, 193, 132, 251, 206, 247 }, - { 143, 113, 148, 194, 133, 251, 207, 247 }, - { 144, 113, 148, 195, 134, 251, 207, 247 }, - { 146, 114, 149, 197, 135, 252, 208, 248 }, - { 147, 114, 149, 198, 135, 252, 209, 248 }, - { 149, 115, 149, 199, 136, 252, 210, 248 }, - { 150, 115, 149, 200, 137, 252, 210, 248 }, - { 152, 115, 150, 201, 138, 252, 211, 248 }, - { 153, 115, 150, 202, 138, 252, 212, 248 }, - { 155, 116, 151, 204, 139, 253, 213, 249 }, - { 156, 116, 151, 205, 139, 253, 213, 249 }, - { 158, 117, 151, 206, 140, 253, 214, 249 }, - { 159, 117, 151, 207, 141, 253, 215, 249 }, - { 161, 118, 152, 208, 142, 253, 216, 249 }, - { 162, 118, 152, 209, 142, 253, 216, 249 }, - { 163, 119, 153, 210, 143, 253, 217, 249 }, - { 164, 119, 153, 211, 143, 253, 217, 249 }, - { 166, 120, 153, 212, 144, 254, 218, 250 }, - { 167, 120, 153, 212, 145, 254, 219, 250 }, - { 168, 121, 154, 213, 146, 254, 220, 250 }, - { 169, 121, 154, 214, 146, 254, 220, 250 }, - { 171, 122, 155, 215, 147, 254, 221, 250 }, - { 172, 122, 155, 216, 147, 254, 221, 250 }, - { 173, 123, 155, 217, 148, 254, 222, 250 }, - { 174, 123, 155, 217, 149, 254, 222, 250 }, - { 176, 124, 156, 218, 150, 254, 223, 250 }, - { 177, 124, 156, 219, 150, 254, 223, 250 }, - { 178, 125, 157, 220, 151, 254, 224, 251 }, - { 179, 125, 157, 220, 151, 254, 224, 251 }, - { 180, 126, 157, 221, 152, 254, 225, 251 }, - { 181, 126, 157, 221, 152, 254, 225, 251 }, - { 183, 127, 158, 222, 153, 254, 226, 251 }, - { 184, 127, 158, 223, 154, 254, 226, 251 }, - { 185, 128, 159, 224, 155, 255, 227, 251 }, - { 186, 128, 159, 224, 155, 255, 227, 251 }, - { 187, 129, 160, 225, 156, 255, 228, 251 }, - { 188, 130, 160, 225, 156, 255, 228, 251 }, - { 189, 131, 160, 226, 157, 255, 228, 251 }, - { 190, 131, 160, 226, 158, 255, 228, 251 }, - { 191, 132, 161, 227, 159, 255, 229, 251 }, - { 192, 132, 161, 227, 159, 255, 229, 251 }, - { 193, 133, 162, 228, 160, 255, 230, 252 }, - { 194, 133, 162, 229, 160, 255, 230, 252 }, - { 195, 134, 163, 230, 161, 255, 231, 252 }, - { 196, 134, 163, 230, 161, 255, 231, 252 }, - { 197, 135, 163, 231, 162, 255, 231, 252 }, - { 198, 135, 163, 231, 162, 255, 231, 252 }, - { 199, 136, 164, 232, 163, 255, 232, 252 }, - { 200, 136, 164, 232, 164, 255, 232, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 202, 138, 166, 233, 166, 255, 233, 252 }, - { 203, 138, 166, 233, 166, 255, 233, 252 }, - { 204, 139, 166, 234, 167, 255, 234, 252 }, - { 205, 139, 166, 234, 167, 255, 234, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 207, 141, 168, 236, 169, 255, 235, 252 }, - { 208, 141, 168, 236, 170, 255, 235, 252 }, - { 209, 142, 169, 237, 171, 255, 236, 252 }, - { 209, 143, 169, 237, 171, 255, 236, 252 }, - { 210, 144, 169, 237, 172, 255, 236, 252 }, - { 211, 144, 169, 237, 172, 255, 236, 252 }, - { 212, 145, 170, 238, 173, 255, 237, 252 }, - { 213, 145, 170, 238, 173, 255, 237, 252 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 216, 148, 173, 240, 176, 255, 238, 253 }, - { 217, 148, 173, 240, 176, 255, 238, 253 }, - { 218, 149, 173, 241, 177, 255, 239, 253 }, - { 218, 149, 173, 241, 178, 255, 239, 253 }, - { 219, 150, 174, 241, 179, 255, 239, 253 }, - { 219, 151, 174, 241, 179, 255, 239, 253 }, - { 220, 152, 175, 242, 180, 255, 240, 253 }, - { 221, 152, 175, 242, 180, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 225, 156, 178, 244, 184, 255, 241, 253 }, - { 225, 157, 178, 244, 184, 255, 241, 253 }, - { 226, 158, 179, 244, 185, 255, 242, 253 }, - { 227, 158, 179, 244, 185, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 230, 161, 182, 246, 188, 255, 243, 253 }, - { 230, 162, 182, 246, 188, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 234, 166, 185, 247, 192, 255, 244, 253 }, - { 234, 167, 185, 247, 192, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 237, 171, 189, 249, 196, 255, 245, 254 }, - { 237, 172, 189, 249, 196, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 240, 175, 192, 249, 199, 255, 246, 254 }, - { 240, 176, 192, 249, 199, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 242, 179, 195, 250, 202, 255, 246, 254 }, - { 242, 180, 195, 250, 202, 255, 246, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 243, 182, 197, 251, 204, 255, 247, 254 }, - { 243, 183, 197, 251, 204, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 245, 186, 200, 251, 207, 255, 247, 254 }, - { 245, 187, 200, 251, 207, 255, 247, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 189, 202, 252, 208, 255, 248, 254 }, - { 246, 190, 202, 252, 208, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 192, 204, 252, 210, 255, 248, 254 }, - { 247, 193, 204, 252, 210, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 195, 206, 252, 212, 255, 249, 254 }, - { 248, 196, 206, 252, 212, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 198, 208, 253, 214, 255, 249, 254 }, - { 249, 199, 209, 253, 214, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 201, 211, 253, 215, 255, 249, 254 }, - { 250, 202, 211, 253, 215, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 251, 204, 213, 253, 217, 255, 250, 254 }, - { 251, 205, 213, 253, 217, 255, 250, 254 }, - { 251, 206, 214, 254, 218, 255, 250, 254 }, - { 251, 206, 215, 254, 218, 255, 250, 254 }, - { 252, 207, 216, 254, 219, 255, 250, 254 }, - { 252, 208, 216, 254, 219, 255, 250, 254 }, - { 252, 209, 217, 254, 220, 255, 250, 254 }, - { 252, 210, 217, 254, 220, 255, 250, 254 }, - { 252, 211, 218, 254, 221, 255, 250, 254 }, - { 252, 212, 218, 254, 221, 255, 250, 254 }, - { 253, 213, 219, 254, 222, 255, 250, 254 }, - { 253, 213, 220, 254, 222, 255, 250, 254 }, - { 253, 214, 221, 254, 223, 255, 250, 254 }, - { 253, 215, 221, 254, 223, 255, 250, 254 }, - { 253, 216, 222, 254, 224, 255, 251, 254 }, - { 253, 217, 223, 254, 224, 255, 251, 254 }, - { 253, 218, 224, 254, 225, 255, 251, 254 }, - { 253, 219, 224, 254, 225, 255, 251, 254 }, - { 254, 220, 225, 254, 225, 255, 251, 254 }, - { 254, 221, 226, 254, 225, 255, 251, 254 }, - { 254, 222, 227, 255, 226, 255, 251, 254 }, - { 254, 223, 227, 255, 226, 255, 251, 254 }, - { 254, 224, 228, 255, 227, 255, 251, 254 }, - { 254, 225, 229, 255, 227, 255, 251, 254 }, - { 254, 226, 230, 255, 228, 255, 251, 254 }, - { 254, 227, 230, 255, 229, 255, 251, 254 }, - { 255, 228, 231, 255, 230, 255, 251, 254 }, - { 255, 229, 232, 255, 230, 255, 251, 254 }, - { 255, 230, 233, 255, 231, 255, 252, 254 }, - { 255, 231, 234, 255, 231, 255, 252, 254 }, - { 255, 232, 235, 255, 232, 255, 252, 254 }, - { 255, 233, 236, 255, 232, 255, 252, 254 }, - { 255, 235, 237, 255, 233, 255, 252, 254 }, - { 255, 236, 238, 255, 234, 255, 252, 254 }, - { 255, 238, 240, 255, 235, 255, 252, 255 }, - { 255, 239, 241, 255, 235, 255, 252, 254 }, - { 255, 241, 243, 255, 236, 255, 252, 254 }, - { 255, 243, 245, 255, 237, 255, 252, 254 }, - { 255, 246, 247, 255, 239, 255, 253, 255 }, -}; - -typedef struct { - uint8_t y_mode[4][9]; - uint8_t uv_mode[10][9]; - uint8_t filter[4][2]; - uint8_t mv_mode[7][3]; - uint8_t intra[4]; - uint8_t comp[5]; - uint8_t single_ref[5][2]; - uint8_t comp_ref[5]; - uint8_t tx32p[2][3]; - uint8_t tx16p[2][2]; - uint8_t tx8p[2]; - uint8_t skip[3]; - uint8_t mv_joint[3]; - struct { - uint8_t sign; - uint8_t classes[10]; - uint8_t class0; - uint8_t bits[10]; - uint8_t class0_fp[2][3]; - uint8_t fp[3]; - uint8_t class0_hp; - uint8_t hp; - } mv_comp[2]; - uint8_t partition[4][4][3]; -} prob_context; - -static const prob_context vp9_default_probs = { - { /* y_mode */ - { 65, 32, 18, 144, 162, 194, 41, 51, 98 } /* bsize < 8x8 */, - { 132, 68, 18, 165, 217, 196, 45, 40, 78 } /* bsize < 16x16 */, - { 173, 80, 19, 176, 240, 193, 64, 35, 46 } /* bsize < 32x32 */, - { 221, 135, 38, 194, 248, 121, 96, 85, 29 } /* bsize >= 32x32 */ - }, { /* uv_mode */ - { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */, - { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */, - { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */, - { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */, - { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */, - { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */, - { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */, - { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */, - { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d27 */, - { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */ - }, { /* filter */ - { 235, 162, }, - { 36, 255, }, - { 34, 3, }, - { 149, 144, }, - }, { /* mv_mode */ - { 2, 173, 34}, // 0 = both zero mv - { 7, 145, 85}, // 1 = one zero mv + one a predicted mv - { 7, 166, 63}, // 2 = two predicted mvs - { 7, 94, 66}, // 3 = one predicted/zero and one new mv - { 8, 64, 46}, // 4 = two new mvs - { 17, 81, 31}, // 5 = one intra neighbour + x - { 25, 29, 30}, // 6 = two intra neighbours - }, { /* intra */ - 9, 102, 187, 225 - }, { /* comp */ - 239, 183, 119, 96, 41 - }, { /* single_ref */ - { 33, 16 }, - { 77, 74 }, - { 142, 142 }, - { 172, 170 }, - { 238, 247 } - }, { /* comp_ref */ - 50, 126, 123, 221, 226 - }, { /* tx32p */ - { 3, 136, 37, }, - { 5, 52, 13, }, - }, { /* tx16p */ - { 20, 152, }, - { 15, 101, }, - }, { /* tx8p */ - 100, 66 - }, { /* skip */ - 192, 128, 64 - }, { /* mv_joint */ - 32, 64, 96 - }, { - { /* mv vertical component */ - 128, /* sign */ - { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ - 216, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240}, /* bits */ - { /* class0_fp */ - { 128, 128, 64 }, - { 96, 112, 64 } - }, - { 64, 96, 64 }, /* fp */ - 160, /* class0_hp bit */ - 128, /* hp */ - }, { /* mv horizontal component */ - 128, /* sign */ - { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */ - 208, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ - { /* class0_fp */ - { 128, 128, 64 }, - { 96, 112, 64 } - }, - { 64, 96, 64 }, /* fp */ - 160, /* class0_hp bit */ - 128, /* hp */ - } - }, { /* partition */ - { /* 64x64 -> 32x32 */ - { 222, 34, 30 } /* a/l both not split */, - { 72, 16, 44 } /* a split, l not split */, - { 58, 32, 12 } /* l split, a not split */, - { 10, 7, 6 } /* a/l both split */, - }, { /* 32x32 -> 16x16 */ - { 177, 58, 59 } /* a/l both not split */, - { 68, 26, 63 } /* a split, l not split */, - { 52, 79, 25 } /* l split, a not split */, - { 17, 14, 12 } /* a/l both split */, - }, { /* 16x16 -> 8x8 */ - { 174, 73, 87 } /* a/l both not split */, - { 92, 41, 83 } /* a split, l not split */, - { 82, 99, 50 } /* l split, a not split */, - { 53, 39, 39 } /* a/l both split */, - }, { /* 8x8 -> 4x4 */ - { 199, 122, 141 } /* a/l both not split */, - { 147, 63, 159 } /* a split, l not split */, - { 148, 133, 118 } /* l split, a not split */, - { 121, 104, 114 } /* a/l both split */, - } - }, -}; - -static const uint8_t vp9_default_coef_probs[4][2][2][6][6][3] = { - { /* tx = 4x4 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 195, 29, 183 }, - { 84, 49, 136 }, - { 8, 42, 71 } - }, { /* Coeff Band 1 */ - { 31, 107, 169 }, - { 35, 99, 159 }, - { 17, 82, 140 }, - { 8, 66, 114 }, - { 2, 44, 76 }, - { 1, 19, 32 } - }, { /* Coeff Band 2 */ - { 40, 132, 201 }, - { 29, 114, 187 }, - { 13, 91, 157 }, - { 7, 75, 127 }, - { 3, 58, 95 }, - { 1, 28, 47 } - }, { /* Coeff Band 3 */ - { 69, 142, 221 }, - { 42, 122, 201 }, - { 15, 91, 159 }, - { 6, 67, 121 }, - { 1, 42, 77 }, - { 1, 17, 31 } - }, { /* Coeff Band 4 */ - { 102, 148, 228 }, - { 67, 117, 204 }, - { 17, 82, 154 }, - { 6, 59, 114 }, - { 2, 39, 75 }, - { 1, 15, 29 } - }, { /* Coeff Band 5 */ - { 156, 57, 233 }, - { 119, 57, 212 }, - { 58, 48, 163 }, - { 29, 40, 124 }, - { 12, 30, 81 }, - { 3, 12, 31 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 191, 107, 226 }, - { 124, 117, 204 }, - { 25, 99, 155 } - }, { /* Coeff Band 1 */ - { 29, 148, 210 }, - { 37, 126, 194 }, - { 8, 93, 157 }, - { 2, 68, 118 }, - { 1, 39, 69 }, - { 1, 17, 33 } - }, { /* Coeff Band 2 */ - { 41, 151, 213 }, - { 27, 123, 193 }, - { 3, 82, 144 }, - { 1, 58, 105 }, - { 1, 32, 60 }, - { 1, 13, 26 } - }, { /* Coeff Band 3 */ - { 59, 159, 220 }, - { 23, 126, 198 }, - { 4, 88, 151 }, - { 1, 66, 114 }, - { 1, 38, 71 }, - { 1, 18, 34 } - }, { /* Coeff Band 4 */ - { 114, 136, 232 }, - { 51, 114, 207 }, - { 11, 83, 155 }, - { 3, 56, 105 }, - { 1, 33, 65 }, - { 1, 17, 34 } - }, { /* Coeff Band 5 */ - { 149, 65, 234 }, - { 121, 57, 215 }, - { 61, 49, 166 }, - { 28, 36, 114 }, - { 12, 25, 76 }, - { 3, 16, 42 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 214, 49, 220 }, - { 132, 63, 188 }, - { 42, 65, 137 } - }, { /* Coeff Band 1 */ - { 85, 137, 221 }, - { 104, 131, 216 }, - { 49, 111, 192 }, - { 21, 87, 155 }, - { 2, 49, 87 }, - { 1, 16, 28 } - }, { /* Coeff Band 2 */ - { 89, 163, 230 }, - { 90, 137, 220 }, - { 29, 100, 183 }, - { 10, 70, 135 }, - { 2, 42, 81 }, - { 1, 17, 33 } - }, { /* Coeff Band 3 */ - { 108, 167, 237 }, - { 55, 133, 222 }, - { 15, 97, 179 }, - { 4, 72, 135 }, - { 1, 45, 85 }, - { 1, 19, 38 } - }, { /* Coeff Band 4 */ - { 124, 146, 240 }, - { 66, 124, 224 }, - { 17, 88, 175 }, - { 4, 58, 122 }, - { 1, 36, 75 }, - { 1, 18, 37 } - }, { /* Coeff Band 5 */ - { 141, 79, 241 }, - { 126, 70, 227 }, - { 66, 58, 182 }, - { 30, 44, 136 }, - { 12, 34, 96 }, - { 2, 20, 47 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 229, 99, 249 }, - { 143, 111, 235 }, - { 46, 109, 192 } - }, { /* Coeff Band 1 */ - { 82, 158, 236 }, - { 94, 146, 224 }, - { 25, 117, 191 }, - { 9, 87, 149 }, - { 3, 56, 99 }, - { 1, 33, 57 } - }, { /* Coeff Band 2 */ - { 83, 167, 237 }, - { 68, 145, 222 }, - { 10, 103, 177 }, - { 2, 72, 131 }, - { 1, 41, 79 }, - { 1, 20, 39 } - }, { /* Coeff Band 3 */ - { 99, 167, 239 }, - { 47, 141, 224 }, - { 10, 104, 178 }, - { 2, 73, 133 }, - { 1, 44, 85 }, - { 1, 22, 47 } - }, { /* Coeff Band 4 */ - { 127, 145, 243 }, - { 71, 129, 228 }, - { 17, 93, 177 }, - { 3, 61, 124 }, - { 1, 41, 84 }, - { 1, 21, 52 } - }, { /* Coeff Band 5 */ - { 157, 78, 244 }, - { 140, 72, 231 }, - { 69, 58, 184 }, - { 31, 44, 137 }, - { 14, 38, 105 }, - { 8, 23, 61 } - } - } - } - }, { /* tx = 8x8 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 125, 34, 187 }, - { 52, 41, 133 }, - { 6, 31, 56 } - }, { /* Coeff Band 1 */ - { 37, 109, 153 }, - { 51, 102, 147 }, - { 23, 87, 128 }, - { 8, 67, 101 }, - { 1, 41, 63 }, - { 1, 19, 29 } - }, { /* Coeff Band 2 */ - { 31, 154, 185 }, - { 17, 127, 175 }, - { 6, 96, 145 }, - { 2, 73, 114 }, - { 1, 51, 82 }, - { 1, 28, 45 } - }, { /* Coeff Band 3 */ - { 23, 163, 200 }, - { 10, 131, 185 }, - { 2, 93, 148 }, - { 1, 67, 111 }, - { 1, 41, 69 }, - { 1, 14, 24 } - }, { /* Coeff Band 4 */ - { 29, 176, 217 }, - { 12, 145, 201 }, - { 3, 101, 156 }, - { 1, 69, 111 }, - { 1, 39, 63 }, - { 1, 14, 23 } - }, { /* Coeff Band 5 */ - { 57, 192, 233 }, - { 25, 154, 215 }, - { 6, 109, 167 }, - { 3, 78, 118 }, - { 1, 48, 69 }, - { 1, 21, 29 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 202, 105, 245 }, - { 108, 106, 216 }, - { 18, 90, 144 } - }, { /* Coeff Band 1 */ - { 33, 172, 219 }, - { 64, 149, 206 }, - { 14, 117, 177 }, - { 5, 90, 141 }, - { 2, 61, 95 }, - { 1, 37, 57 } - }, { /* Coeff Band 2 */ - { 33, 179, 220 }, - { 11, 140, 198 }, - { 1, 89, 148 }, - { 1, 60, 104 }, - { 1, 33, 57 }, - { 1, 12, 21 } - }, { /* Coeff Band 3 */ - { 30, 181, 221 }, - { 8, 141, 198 }, - { 1, 87, 145 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 20 } - }, { /* Coeff Band 4 */ - { 32, 186, 224 }, - { 7, 142, 198 }, - { 1, 86, 143 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 22 } - }, { /* Coeff Band 5 */ - { 57, 192, 227 }, - { 20, 143, 204 }, - { 3, 96, 154 }, - { 1, 68, 112 }, - { 1, 42, 69 }, - { 1, 19, 32 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 212, 35, 215 }, - { 113, 47, 169 }, - { 29, 48, 105 } - }, { /* Coeff Band 1 */ - { 74, 129, 203 }, - { 106, 120, 203 }, - { 49, 107, 178 }, - { 19, 84, 144 }, - { 4, 50, 84 }, - { 1, 15, 25 } - }, { /* Coeff Band 2 */ - { 71, 172, 217 }, - { 44, 141, 209 }, - { 15, 102, 173 }, - { 6, 76, 133 }, - { 2, 51, 89 }, - { 1, 24, 42 } - }, { /* Coeff Band 3 */ - { 64, 185, 231 }, - { 31, 148, 216 }, - { 8, 103, 175 }, - { 3, 74, 131 }, - { 1, 46, 81 }, - { 1, 18, 30 } - }, { /* Coeff Band 4 */ - { 65, 196, 235 }, - { 25, 157, 221 }, - { 5, 105, 174 }, - { 1, 67, 120 }, - { 1, 38, 69 }, - { 1, 15, 30 } - }, { /* Coeff Band 5 */ - { 65, 204, 238 }, - { 30, 156, 224 }, - { 7, 107, 177 }, - { 2, 70, 124 }, - { 1, 42, 73 }, - { 1, 18, 34 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 225, 86, 251 }, - { 144, 104, 235 }, - { 42, 99, 181 } - }, { /* Coeff Band 1 */ - { 85, 175, 239 }, - { 112, 165, 229 }, - { 29, 136, 200 }, - { 12, 103, 162 }, - { 6, 77, 123 }, - { 2, 53, 84 } - }, { /* Coeff Band 2 */ - { 75, 183, 239 }, - { 30, 155, 221 }, - { 3, 106, 171 }, - { 1, 74, 128 }, - { 1, 44, 76 }, - { 1, 17, 28 } - }, { /* Coeff Band 3 */ - { 73, 185, 240 }, - { 27, 159, 222 }, - { 2, 107, 172 }, - { 1, 75, 127 }, - { 1, 42, 73 }, - { 1, 17, 29 } - }, { /* Coeff Band 4 */ - { 62, 190, 238 }, - { 21, 159, 222 }, - { 2, 107, 172 }, - { 1, 72, 122 }, - { 1, 40, 71 }, - { 1, 18, 32 } - }, { /* Coeff Band 5 */ - { 61, 199, 240 }, - { 27, 161, 226 }, - { 4, 113, 180 }, - { 1, 76, 129 }, - { 1, 46, 80 }, - { 1, 23, 41 } - } - } - } - }, { /* tx = 16x16 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 7, 27, 153 }, - { 5, 30, 95 }, - { 1, 16, 30 } - }, { /* Coeff Band 1 */ - { 50, 75, 127 }, - { 57, 75, 124 }, - { 27, 67, 108 }, - { 10, 54, 86 }, - { 1, 33, 52 }, - { 1, 12, 18 } - }, { /* Coeff Band 2 */ - { 43, 125, 151 }, - { 26, 108, 148 }, - { 7, 83, 122 }, - { 2, 59, 89 }, - { 1, 38, 60 }, - { 1, 17, 27 } - }, { /* Coeff Band 3 */ - { 23, 144, 163 }, - { 13, 112, 154 }, - { 2, 75, 117 }, - { 1, 50, 81 }, - { 1, 31, 51 }, - { 1, 14, 23 } - }, { /* Coeff Band 4 */ - { 18, 162, 185 }, - { 6, 123, 171 }, - { 1, 78, 125 }, - { 1, 51, 86 }, - { 1, 31, 54 }, - { 1, 14, 23 } - }, { /* Coeff Band 5 */ - { 15, 199, 227 }, - { 3, 150, 204 }, - { 1, 91, 146 }, - { 1, 55, 95 }, - { 1, 30, 53 }, - { 1, 11, 20 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 19, 55, 240 }, - { 19, 59, 196 }, - { 3, 52, 105 } - }, { /* Coeff Band 1 */ - { 41, 166, 207 }, - { 104, 153, 199 }, - { 31, 123, 181 }, - { 14, 101, 152 }, - { 5, 72, 106 }, - { 1, 36, 52 } - }, { /* Coeff Band 2 */ - { 35, 176, 211 }, - { 12, 131, 190 }, - { 2, 88, 144 }, - { 1, 60, 101 }, - { 1, 36, 60 }, - { 1, 16, 28 } - }, { /* Coeff Band 3 */ - { 28, 183, 213 }, - { 8, 134, 191 }, - { 1, 86, 142 }, - { 1, 56, 96 }, - { 1, 30, 53 }, - { 1, 12, 20 } - }, { /* Coeff Band 4 */ - { 20, 190, 215 }, - { 4, 135, 192 }, - { 1, 84, 139 }, - { 1, 53, 91 }, - { 1, 28, 49 }, - { 1, 11, 20 } - }, { /* Coeff Band 5 */ - { 13, 196, 216 }, - { 2, 137, 192 }, - { 1, 86, 143 }, - { 1, 57, 99 }, - { 1, 32, 56 }, - { 1, 13, 24 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 211, 29, 217 }, - { 96, 47, 156 }, - { 22, 43, 87 } - }, { /* Coeff Band 1 */ - { 78, 120, 193 }, - { 111, 116, 186 }, - { 46, 102, 164 }, - { 15, 80, 128 }, - { 2, 49, 76 }, - { 1, 18, 28 } - }, { /* Coeff Band 2 */ - { 71, 161, 203 }, - { 42, 132, 192 }, - { 10, 98, 150 }, - { 3, 69, 109 }, - { 1, 44, 70 }, - { 1, 18, 29 } - }, { /* Coeff Band 3 */ - { 57, 186, 211 }, - { 30, 140, 196 }, - { 4, 93, 146 }, - { 1, 62, 102 }, - { 1, 38, 65 }, - { 1, 16, 27 } - }, { /* Coeff Band 4 */ - { 47, 199, 217 }, - { 14, 145, 196 }, - { 1, 88, 142 }, - { 1, 57, 98 }, - { 1, 36, 62 }, - { 1, 15, 26 } - }, { /* Coeff Band 5 */ - { 26, 219, 229 }, - { 5, 155, 207 }, - { 1, 94, 151 }, - { 1, 60, 104 }, - { 1, 36, 62 }, - { 1, 16, 28 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 233, 29, 248 }, - { 146, 47, 220 }, - { 43, 52, 140 } - }, { /* Coeff Band 1 */ - { 100, 163, 232 }, - { 179, 161, 222 }, - { 63, 142, 204 }, - { 37, 113, 174 }, - { 26, 89, 137 }, - { 18, 68, 97 } - }, { /* Coeff Band 2 */ - { 85, 181, 230 }, - { 32, 146, 209 }, - { 7, 100, 164 }, - { 3, 71, 121 }, - { 1, 45, 77 }, - { 1, 18, 30 } - }, { /* Coeff Band 3 */ - { 65, 187, 230 }, - { 20, 148, 207 }, - { 2, 97, 159 }, - { 1, 68, 116 }, - { 1, 40, 70 }, - { 1, 14, 29 } - }, { /* Coeff Band 4 */ - { 40, 194, 227 }, - { 8, 147, 204 }, - { 1, 94, 155 }, - { 1, 65, 112 }, - { 1, 39, 66 }, - { 1, 14, 26 } - }, { /* Coeff Band 5 */ - { 16, 208, 228 }, - { 3, 151, 207 }, - { 1, 98, 160 }, - { 1, 67, 117 }, - { 1, 41, 74 }, - { 1, 17, 31 } - } - } - } - }, { /* tx = 32x32 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 17, 38, 140 }, - { 7, 34, 80 }, - { 1, 17, 29 } - }, { /* Coeff Band 1 */ - { 37, 75, 128 }, - { 41, 76, 128 }, - { 26, 66, 116 }, - { 12, 52, 94 }, - { 2, 32, 55 }, - { 1, 10, 16 } - }, { /* Coeff Band 2 */ - { 50, 127, 154 }, - { 37, 109, 152 }, - { 16, 82, 121 }, - { 5, 59, 85 }, - { 1, 35, 54 }, - { 1, 13, 20 } - }, { /* Coeff Band 3 */ - { 40, 142, 167 }, - { 17, 110, 157 }, - { 2, 71, 112 }, - { 1, 44, 72 }, - { 1, 27, 45 }, - { 1, 11, 17 } - }, { /* Coeff Band 4 */ - { 30, 175, 188 }, - { 9, 124, 169 }, - { 1, 74, 116 }, - { 1, 48, 78 }, - { 1, 30, 49 }, - { 1, 11, 18 } - }, { /* Coeff Band 5 */ - { 10, 222, 223 }, - { 2, 150, 194 }, - { 1, 83, 128 }, - { 1, 48, 79 }, - { 1, 27, 45 }, - { 1, 11, 17 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 36, 41, 235 }, - { 29, 36, 193 }, - { 10, 27, 111 } - }, { /* Coeff Band 1 */ - { 85, 165, 222 }, - { 177, 162, 215 }, - { 110, 135, 195 }, - { 57, 113, 168 }, - { 23, 83, 120 }, - { 10, 49, 61 } - }, { /* Coeff Band 2 */ - { 85, 190, 223 }, - { 36, 139, 200 }, - { 5, 90, 146 }, - { 1, 60, 103 }, - { 1, 38, 65 }, - { 1, 18, 30 } - }, { /* Coeff Band 3 */ - { 72, 202, 223 }, - { 23, 141, 199 }, - { 2, 86, 140 }, - { 1, 56, 97 }, - { 1, 36, 61 }, - { 1, 16, 27 } - }, { /* Coeff Band 4 */ - { 55, 218, 225 }, - { 13, 145, 200 }, - { 1, 86, 141 }, - { 1, 57, 99 }, - { 1, 35, 61 }, - { 1, 13, 22 } - }, { /* Coeff Band 5 */ - { 15, 235, 212 }, - { 1, 132, 184 }, - { 1, 84, 139 }, - { 1, 57, 97 }, - { 1, 34, 56 }, - { 1, 14, 23 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 181, 21, 201 }, - { 61, 37, 123 }, - { 10, 38, 71 } - }, { /* Coeff Band 1 */ - { 47, 106, 172 }, - { 95, 104, 173 }, - { 42, 93, 159 }, - { 18, 77, 131 }, - { 4, 50, 81 }, - { 1, 17, 23 } - }, { /* Coeff Band 2 */ - { 62, 147, 199 }, - { 44, 130, 189 }, - { 28, 102, 154 }, - { 18, 75, 115 }, - { 2, 44, 65 }, - { 1, 12, 19 } - }, { /* Coeff Band 3 */ - { 55, 153, 210 }, - { 24, 130, 194 }, - { 3, 93, 146 }, - { 1, 61, 97 }, - { 1, 31, 50 }, - { 1, 10, 16 } - }, { /* Coeff Band 4 */ - { 49, 186, 223 }, - { 17, 148, 204 }, - { 1, 96, 142 }, - { 1, 53, 83 }, - { 1, 26, 44 }, - { 1, 11, 17 } - }, { /* Coeff Band 5 */ - { 13, 217, 212 }, - { 2, 136, 180 }, - { 1, 78, 124 }, - { 1, 50, 83 }, - { 1, 29, 49 }, - { 1, 14, 23 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 197, 13, 247 }, - { 82, 17, 222 }, - { 25, 17, 162 } - }, { /* Coeff Band 1 */ - { 126, 186, 247 }, - { 234, 191, 243 }, - { 176, 177, 234 }, - { 104, 158, 220 }, - { 66, 128, 186 }, - { 55, 90, 137 } - }, { /* Coeff Band 2 */ - { 111, 197, 242 }, - { 46, 158, 219 }, - { 9, 104, 171 }, - { 2, 65, 125 }, - { 1, 44, 80 }, - { 1, 17, 91 } - }, { /* Coeff Band 3 */ - { 104, 208, 245 }, - { 39, 168, 224 }, - { 3, 109, 162 }, - { 1, 79, 124 }, - { 1, 50, 102 }, - { 1, 43, 102 } - }, { /* Coeff Band 4 */ - { 84, 220, 246 }, - { 31, 177, 231 }, - { 2, 115, 180 }, - { 1, 79, 134 }, - { 1, 55, 77 }, - { 1, 60, 79 } - }, { /* Coeff Band 5 */ - { 43, 243, 240 }, - { 8, 180, 217 }, - { 1, 115, 166 }, - { 1, 84, 121 }, - { 1, 51, 67 }, - { 1, 16, 6 } - } - } - } - } -}; - -enum MVJoint { - MV_JOINT_ZERO, - MV_JOINT_H, - MV_JOINT_V, - MV_JOINT_HV, -}; - -static const int8_t vp9_mv_joint_tree[3][2] = { - { -MV_JOINT_ZERO, 1 }, // '0' - { -MV_JOINT_H, 2 }, // '10' - { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' -}; - -static const int8_t vp9_mv_class_tree[10][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { 3, 4 }, - { -2, -3 }, // '110x' - { 5, 6 }, - { -4, -5 }, // '1110x' - { -6, 7 }, // '11110' - { 8, 9 }, - { -7, -8 }, // '111110x' - { -9, -10 }, // '111111x' -}; - -static const int8_t vp9_mv_fp_tree[3][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { -2, -3 }, // '11x' -}; +#include "vp9dec.h" + +extern const uint8_t ff_vp9_bwh_tab[2][N_BS_SIZES][2]; +extern const int8_t ff_vp9_partition_tree[3][2]; +extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3]; +extern const int8_t ff_vp9_segmentation_tree[7][2]; +extern const int8_t ff_vp9_intramode_tree[9][2]; +extern const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9]; +extern const uint8_t ff_vp9_default_kf_uvmode_probs[10][9]; +extern const int8_t ff_vp9_inter_mode_tree[3][2]; +extern const int8_t ff_vp9_filter_tree[2][2]; +extern const enum FilterMode ff_vp9_filter_lut[3]; +extern const int16_t ff_vp9_dc_qlookup[3][256]; +extern const int16_t ff_vp9_ac_qlookup[3][256]; +extern const enum TxfmType ff_vp9_intra_txfm_type[14]; +extern const int16_t ff_vp9_default_scan_4x4[16]; +extern const int16_t ff_vp9_col_scan_4x4[16]; +extern const int16_t ff_vp9_row_scan_4x4[16]; +extern const int16_t ff_vp9_default_scan_8x8[64]; +extern const int16_t ff_vp9_col_scan_8x8[64]; +extern const int16_t ff_vp9_row_scan_8x8[64]; +extern const int16_t ff_vp9_default_scan_16x16[256]; +extern const int16_t ff_vp9_col_scan_16x16[256]; +extern const int16_t ff_vp9_row_scan_16x16[256]; +extern const int16_t ff_vp9_default_scan_32x32[1024]; +extern const int16_t * const ff_vp9_scans[5][4]; +extern const int16_t ff_vp9_default_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_col_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_row_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_default_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_col_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_row_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_default_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_col_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_row_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_default_scan_32x32_nb[1024][2]; +extern const int16_t (* const ff_vp9_scans_nb[5][4])[2]; +extern const uint8_t ff_vp9_model_pareto8[256][8]; +extern const ProbContext ff_vp9_default_probs; +extern const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3]; +extern const int8_t ff_vp9_mv_joint_tree[3][2]; +extern const int8_t ff_vp9_mv_class_tree[10][2]; +extern const int8_t ff_vp9_mv_fp_tree[3][2]; #endif /* AVCODEC_VP9DATA_H */ diff --git a/media/ffvpx/libavcodec/vp9dec.h b/media/ffvpx/libavcodec/vp9dec.h new file mode 100644 index 000000000..66573edc7 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9dec.h @@ -0,0 +1,240 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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_VP9DEC_H +#define AVCODEC_VP9DEC_H + +#include +#include +#include + +#include "libavutil/buffer.h" +#include "libavutil/thread.h" +#include "libavutil/internal.h" + +#include "vp9.h" +#include "vp9dsp.h" +#include "vp9shared.h" + +enum MVJoint { + MV_JOINT_ZERO, + MV_JOINT_H, + MV_JOINT_V, + MV_JOINT_HV, +}; + +typedef struct ProbContext { + uint8_t y_mode[4][9]; + uint8_t uv_mode[10][9]; + uint8_t filter[4][2]; + uint8_t mv_mode[7][3]; + uint8_t intra[4]; + uint8_t comp[5]; + uint8_t single_ref[5][2]; + uint8_t comp_ref[5]; + uint8_t tx32p[2][3]; + uint8_t tx16p[2][2]; + uint8_t tx8p[2]; + uint8_t skip[3]; + uint8_t mv_joint[3]; + struct { + uint8_t sign; + uint8_t classes[10]; + uint8_t class0; + uint8_t bits[10]; + uint8_t class0_fp[2][3]; + uint8_t fp[3]; + uint8_t class0_hp; + uint8_t hp; + } mv_comp[2]; + uint8_t partition[4][4][3]; +} ProbContext; + +typedef struct VP9Filter { + uint8_t level[8 * 8]; + uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */] + [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */]; +} VP9Filter; + +typedef struct VP9Block { + uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip; + enum FilterMode filter; + VP56mv mv[4 /* b_idx */][2 /* ref */]; + enum BlockSize bs; + enum TxfmMode tx, uvtx; + enum BlockLevel bl; + enum BlockPartition bp; +} VP9Block; + +typedef struct VP9TileData VP9TileData; + +typedef struct VP9Context { + VP9SharedContext s; + VP9TileData *td; + + VP9DSPContext dsp; + VideoDSPContext vdsp; + GetBitContext gb; + VP56RangeCoder c; + int pass, active_tile_cols; + +#if HAVE_THREADS + pthread_mutex_t progress_mutex; + pthread_cond_t progress_cond; + atomic_int *entries; +#endif + + uint8_t ss_h, ss_v; + uint8_t last_bpp, bpp_index, bytesperpixel; + uint8_t last_keyframe; + // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal + // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads + // and are therefore per-stream. pix_fmt represents the value in the header + // of the currently processed frame. + int w, h; + enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; + unsigned sb_cols, sb_rows, rows, cols; + ThreadFrame next_refs[8]; + + struct { + uint8_t lim_lut[64]; + uint8_t mblim_lut[64]; + } filter_lut; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][3]; + } prob_ctx[4]; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][11]; + } prob; + + // contextual (above) cache + uint8_t *above_partition_ctx; + uint8_t *above_mode_ctx; + // FIXME maybe merge some of the below in a flags field? + uint8_t *above_y_nnz_ctx; + uint8_t *above_uv_nnz_ctx[2]; + uint8_t *above_skip_ctx; // 1bit + uint8_t *above_txfm_ctx; // 2bit + uint8_t *above_segpred_ctx; // 1bit + uint8_t *above_intra_ctx; // 1bit + uint8_t *above_comp_ctx; // 1bit + uint8_t *above_ref_ctx; // 2bit + uint8_t *above_filter_ctx; + VP56mv (*above_mv_ctx)[2]; + + // whole-frame cache + uint8_t *intra_pred_data[3]; + VP9Filter *lflvl; + + // block reconstruction intermediates + int block_alloc_using_2pass; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; +} VP9Context; + +struct VP9TileData { + //VP9Context should be const, but because of the threading API(generates + //a lot of warnings) it's not. + VP9Context *s; + VP56RangeCoder *c_b; + VP56RangeCoder *c; + int row, row7, col, col7; + uint8_t *dst[3]; + ptrdiff_t y_stride, uv_stride; + VP9Block *b_base, *b; + unsigned tile_col_start; + + struct { + unsigned y_mode[4][10]; + unsigned uv_mode[10][10]; + unsigned filter[4][3]; + unsigned mv_mode[7][4]; + unsigned intra[4][2]; + unsigned comp[5][2]; + unsigned single_ref[5][2][2]; + unsigned comp_ref[5][2]; + unsigned tx32p[2][4]; + unsigned tx16p[2][3]; + unsigned tx8p[2][2]; + unsigned skip[3][2]; + unsigned mv_joint[4]; + struct { + unsigned sign[2]; + unsigned classes[11]; + unsigned class0[2]; + unsigned bits[10][2]; + unsigned class0_fp[2][4]; + unsigned fp[4]; + unsigned class0_hp[2]; + unsigned hp[2]; + } mv_comp[2]; + unsigned partition[4][4][4]; + unsigned coef[4][2][2][6][6][3]; + unsigned eob[4][2][2][6][6][2]; + } counts; + + // whole-frame cache + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; + + // contextual (left) cache + DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; + DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; + DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; + DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16]; + DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; + DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; + // block reconstruction intermediates + DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; + DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; + struct { int x, y; } min_mv, max_mv; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; +}; + +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb); + +void ff_vp9_adapt_probs(VP9Context *s); + +void ff_vp9_decode_block(VP9TileData *td, int row, int col, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp); + +void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, + int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff); + +void ff_vp9_intra_recon_8bpp(VP9TileData *td, + ptrdiff_t y_off, ptrdiff_t uv_off); +void ff_vp9_intra_recon_16bpp(VP9TileData *td, + ptrdiff_t y_off, ptrdiff_t uv_off); +void ff_vp9_inter_recon_8bpp(VP9TileData *td); +void ff_vp9_inter_recon_16bpp(VP9TileData *td); + +#endif /* AVCODEC_VP9DEC_H */ diff --git a/media/ffvpx/libavcodec/vp9dsp.c b/media/ffvpx/libavcodec/vp9dsp.c index 54e77e267..f6d73f73c 100644 --- a/media/ffvpx/libavcodec/vp9dsp.c +++ b/media/ffvpx/libavcodec/vp9dsp.c @@ -25,6 +25,62 @@ #include "libavutil/common.h" #include "vp9dsp.h" +const DECLARE_ALIGNED(16, int16_t, ff_vp9_subpel_filters)[3][16][8] = { + [FILTER_8TAP_REGULAR] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, + { 0, 1, -5, 126, 8, -3, 1, 0 }, + { -1, 3, -10, 122, 18, -6, 2, 0 }, + { -1, 4, -13, 118, 27, -9, 3, -1 }, + { -1, 4, -16, 112, 37, -11, 4, -1 }, + { -1, 5, -18, 105, 48, -14, 4, -1 }, + { -1, 5, -19, 97, 58, -16, 5, -1 }, + { -1, 6, -19, 88, 68, -18, 5, -1 }, + { -1, 6, -19, 78, 78, -19, 6, -1 }, + { -1, 5, -18, 68, 88, -19, 6, -1 }, + { -1, 5, -16, 58, 97, -19, 5, -1 }, + { -1, 4, -14, 48, 105, -18, 5, -1 }, + { -1, 4, -11, 37, 112, -16, 4, -1 }, + { -1, 3, -9, 27, 118, -13, 4, -1 }, + { 0, 2, -6, 18, 122, -10, 3, -1 }, + { 0, 1, -3, 8, 126, -5, 1, 0 }, + }, [FILTER_8TAP_SHARP] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, + { -1, 3, -7, 127, 8, -3, 1, 0 }, + { -2, 5, -13, 125, 17, -6, 3, -1 }, + { -3, 7, -17, 121, 27, -10, 5, -2 }, + { -4, 9, -20, 115, 37, -13, 6, -2 }, + { -4, 10, -23, 108, 48, -16, 8, -3 }, + { -4, 10, -24, 100, 59, -19, 9, -3 }, + { -4, 11, -24, 90, 70, -21, 10, -4 }, + { -4, 11, -23, 80, 80, -23, 11, -4 }, + { -4, 10, -21, 70, 90, -24, 11, -4 }, + { -3, 9, -19, 59, 100, -24, 10, -4 }, + { -3, 8, -16, 48, 108, -23, 10, -4 }, + { -2, 6, -13, 37, 115, -20, 9, -4 }, + { -2, 5, -10, 27, 121, -17, 7, -3 }, + { -1, 3, -6, 17, 125, -13, 5, -2 }, + { 0, 1, -3, 8, 127, -7, 3, -1 }, + }, [FILTER_8TAP_SMOOTH] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, + { -3, -1, 32, 64, 38, 1, -3, 0 }, + { -2, -2, 29, 63, 41, 2, -3, 0 }, + { -2, -2, 26, 63, 43, 4, -4, 0 }, + { -2, -3, 24, 62, 46, 5, -4, 0 }, + { -2, -3, 21, 60, 49, 7, -4, 0 }, + { -1, -4, 18, 59, 51, 9, -4, 0 }, + { -1, -4, 16, 57, 53, 12, -4, -1 }, + { -1, -4, 14, 55, 55, 14, -4, -1 }, + { -1, -4, 12, 53, 57, 16, -4, -1 }, + { 0, -4, 9, 51, 59, 18, -4, -1 }, + { 0, -4, 7, 49, 60, 21, -3, -2 }, + { 0, -4, 5, 46, 62, 24, -3, -2 }, + { 0, -4, 4, 43, 63, 26, -2, -2 }, + { 0, -3, 2, 41, 63, 29, -2, -2 }, + { 0, -3, 1, 38, 64, 32, -1, -3 }, + } +}; + + av_cold void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact) { if (bpp == 8) { @@ -36,6 +92,8 @@ av_cold void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact) ff_vp9dsp_init_12(dsp); } + if (ARCH_AARCH64) ff_vp9dsp_init_aarch64(dsp, bpp); + if (ARCH_ARM) ff_vp9dsp_init_arm(dsp, bpp); if (ARCH_X86) ff_vp9dsp_init_x86(dsp, bpp, bitexact); if (ARCH_MIPS) ff_vp9dsp_init_mips(dsp, bpp); } diff --git a/media/ffvpx/libavcodec/vp9dsp.h b/media/ffvpx/libavcodec/vp9dsp.h index 733f5bfc4..e2256316a 100644 --- a/media/ffvpx/libavcodec/vp9dsp.h +++ b/media/ffvpx/libavcodec/vp9dsp.h @@ -27,7 +27,7 @@ #include #include -#include "vp9.h" +#include "libavcodec/vp9.h" typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, @@ -111,21 +111,25 @@ typedef struct VP9DSPContext { * * dst/stride are aligned by hsize */ - vp9_mc_func mc[5][4][2][2][2]; + vp9_mc_func mc[5][N_FILTERS][2][2][2]; /* * for scalable MC, first 3 dimensions identical to above, the other two * don't exist since it changes per stepsize. */ - vp9_scaled_mc_func smc[5][4][2]; + vp9_scaled_mc_func smc[5][N_FILTERS][2]; } VP9DSPContext; +extern const int16_t ff_vp9_subpel_filters[3][16][8]; + void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact); void ff_vp9dsp_init_8(VP9DSPContext *dsp); void ff_vp9dsp_init_10(VP9DSPContext *dsp); void ff_vp9dsp_init_12(VP9DSPContext *dsp); +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp); +void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp); void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact); void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp); diff --git a/media/ffvpx/libavcodec/vp9dsp_template.c b/media/ffvpx/libavcodec/vp9dsp_template.c index 4d810fec3..bb54561a6 100644 --- a/media/ffvpx/libavcodec/vp9dsp_template.c +++ b/media/ffvpx/libavcodec/vp9dsp_template.c @@ -1991,61 +1991,6 @@ copy_avg_fn(4) #endif /* BIT_DEPTH != 12 */ -static const int16_t vp9_subpel_filters[3][16][8] = { - [FILTER_8TAP_REGULAR] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, - { 0, 1, -5, 126, 8, -3, 1, 0 }, - { -1, 3, -10, 122, 18, -6, 2, 0 }, - { -1, 4, -13, 118, 27, -9, 3, -1 }, - { -1, 4, -16, 112, 37, -11, 4, -1 }, - { -1, 5, -18, 105, 48, -14, 4, -1 }, - { -1, 5, -19, 97, 58, -16, 5, -1 }, - { -1, 6, -19, 88, 68, -18, 5, -1 }, - { -1, 6, -19, 78, 78, -19, 6, -1 }, - { -1, 5, -18, 68, 88, -19, 6, -1 }, - { -1, 5, -16, 58, 97, -19, 5, -1 }, - { -1, 4, -14, 48, 105, -18, 5, -1 }, - { -1, 4, -11, 37, 112, -16, 4, -1 }, - { -1, 3, -9, 27, 118, -13, 4, -1 }, - { 0, 2, -6, 18, 122, -10, 3, -1 }, - { 0, 1, -3, 8, 126, -5, 1, 0 }, - }, [FILTER_8TAP_SHARP] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, - { -1, 3, -7, 127, 8, -3, 1, 0 }, - { -2, 5, -13, 125, 17, -6, 3, -1 }, - { -3, 7, -17, 121, 27, -10, 5, -2 }, - { -4, 9, -20, 115, 37, -13, 6, -2 }, - { -4, 10, -23, 108, 48, -16, 8, -3 }, - { -4, 10, -24, 100, 59, -19, 9, -3 }, - { -4, 11, -24, 90, 70, -21, 10, -4 }, - { -4, 11, -23, 80, 80, -23, 11, -4 }, - { -4, 10, -21, 70, 90, -24, 11, -4 }, - { -3, 9, -19, 59, 100, -24, 10, -4 }, - { -3, 8, -16, 48, 108, -23, 10, -4 }, - { -2, 6, -13, 37, 115, -20, 9, -4 }, - { -2, 5, -10, 27, 121, -17, 7, -3 }, - { -1, 3, -6, 17, 125, -13, 5, -2 }, - { 0, 1, -3, 8, 127, -7, 3, -1 }, - }, [FILTER_8TAP_SMOOTH] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, - { -3, -1, 32, 64, 38, 1, -3, 0 }, - { -2, -2, 29, 63, 41, 2, -3, 0 }, - { -2, -2, 26, 63, 43, 4, -4, 0 }, - { -2, -3, 24, 62, 46, 5, -4, 0 }, - { -2, -3, 21, 60, 49, 7, -4, 0 }, - { -1, -4, 18, 59, 51, 9, -4, 0 }, - { -1, -4, 16, 57, 53, 12, -4, -1 }, - { -1, -4, 14, 55, 55, 14, -4, -1 }, - { -1, -4, 12, 53, 57, 16, -4, -1 }, - { 0, -4, 9, 51, 59, 18, -4, -1 }, - { 0, -4, 7, 49, 60, 21, -3, -2 }, - { 0, -4, 5, 46, 62, 24, -3, -2 }, - { 0, -4, 4, 43, 63, 26, -2, -2 }, - { 0, -3, 2, 41, 63, 29, -2, -2 }, - { 0, -3, 1, 38, 64, 32, -1, -3 }, - } -}; - #define FILTER_8TAP(src, x, F, stride) \ av_clip_pixel((F[0] * src[x + -3 * stride] + \ F[1] * src[x + -2 * stride] + \ @@ -2155,7 +2100,7 @@ static void avg##_8tap_##type##_##sz##dir##_c(uint8_t *dst, ptrdiff_t dst_stride int h, int mx, int my) \ { \ avg##_8tap_1d_##dir##_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][dir_m]); \ + ff_vp9_subpel_filters[type_idx][dir_m]); \ } #define filter_fn_2d(sz, type, type_idx, avg) \ @@ -2164,8 +2109,8 @@ static void avg##_8tap_##type##_##sz##hv_c(uint8_t *dst, ptrdiff_t dst_stride, \ int h, int mx, int my) \ { \ avg##_8tap_2d_hv_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][mx], \ - vp9_subpel_filters[type_idx][my]); \ + ff_vp9_subpel_filters[type_idx][mx], \ + ff_vp9_subpel_filters[type_idx][my]); \ } #if BIT_DEPTH != 12 @@ -2454,7 +2399,7 @@ static void avg##_scaled_##type##_##sz##_c(uint8_t *dst, ptrdiff_t dst_stride, \ int h, int mx, int my, int dx, int dy) \ { \ avg##_scaled_8tap_c(dst, dst_stride, src, src_stride, sz, h, mx, my, dx, dy, \ - vp9_subpel_filters[type_idx]); \ + ff_vp9_subpel_filters[type_idx]); \ } #if BIT_DEPTH != 12 diff --git a/media/ffvpx/libavcodec/vp9lpf.c b/media/ffvpx/libavcodec/vp9lpf.c new file mode 100644 index 000000000..414cede85 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9lpf.c @@ -0,0 +1,202 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "vp9dec.h" + +static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v, + uint8_t *lvl, uint8_t (*mask)[4], + uint8_t *dst, ptrdiff_t ls) +{ + int y, x, bytesperpixel = s->bytesperpixel; + + // filter edges between columns (e.g. block1 | block2) + for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) { + uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v]; + unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3]; + unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3]; + unsigned hm = hm1 | hm2 | hm13 | hm23; + + for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) { + if (col || x > 1) { + if (hm1 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (hmask1[0] & x) { + if (hmask2[0] & x) { + av_assert2(l[8 << ss_v] == L); + s->dsp.loop_filter_16[0](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H); + } + } else if (hm2 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[!!(hmask1[1] & x)] + [!!(hmask2[1] & x)] + [0](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[!!(hmask1[1] & x)] + [0](ptr, ls, E, I, H); + } + } else if (hm2 & x) { + int L = l[8 << ss_v], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[!!(hmask2[1] & x)] + [0](ptr + 8 * ls, ls, E, I, H); + } + } + if (ss_h) { + if (x & 0xAA) + l += 2; + } else { + if (hm13 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (hm23 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H); + } else { + s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H); + } + } else if (hm23 & x) { + int L = l[8 << ss_v], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H); + } + l++; + } + } + } +} + +static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v, + uint8_t *lvl, uint8_t (*mask)[4], + uint8_t *dst, ptrdiff_t ls) +{ + int y, x, bytesperpixel = s->bytesperpixel; + + // block1 + // filter edges between rows (e.g. ------) + // block2 + for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) { + uint8_t *ptr = dst, *l = lvl, *vmask = mask[y]; + unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3]; + + for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) { + if (row || y) { + if (vm & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (vmask[0] & x) { + if (vmask[0] & (x << (1 + ss_h))) { + av_assert2(l[1 + ss_h] == L); + s->dsp.loop_filter_16[1](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H); + } + } else if (vm & (x << (1 + ss_h))) { + L = l[1 + ss_h]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[!!(vmask[1] & x)] + [!!(vmask[1] & (x << (1 + ss_h)))] + [1](ptr, ls, E, I, H); + } else { + s->dsp.loop_filter_8[!!(vmask[1] & x)] + [1](ptr, ls, E, I, H); + } + } else if (vm & (x << (1 + ss_h))) { + int L = l[1 + ss_h], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))] + [1](ptr + 8 * bytesperpixel, ls, E, I, H); + } + } + if (!ss_v) { + if (vm3 & x) { + int L = *l, H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (vm3 & (x << (1 + ss_h))) { + L = l[1 + ss_h]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.lim_lut[L] << 8; + s->dsp.loop_filter_mix2[0][0][1](ptr + ls * 4, ls, E, I, H); + } else { + s->dsp.loop_filter_8[0][1](ptr + ls * 4, ls, E, I, H); + } + } else if (vm3 & (x << (1 + ss_h))) { + int L = l[1 + ss_h], H = L >> 4; + int E = s->filter_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + s->dsp.loop_filter_8[0][1](ptr + ls * 4 + 8 * bytesperpixel, ls, E, I, H); + } + } + } + if (ss_v) { + if (y & 1) + lvl += 16; + } else { + lvl += 8; + } + } +} + +void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, + int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) +{ + VP9Context *s = avctx->priv_data; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + uint8_t *dst = f->data[0] + yoff; + ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1]; + uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v]; + int p; + + /* FIXME: In how far can we interleave the v/h loopfilter calls? E.g. + * if you think of them as acting on a 8x8 block max, we can interleave + * each v/h within the single x loop, but that only works if we work on + * 8 pixel blocks, and we won't always do that (we want at least 16px + * to use SSE2 optimizations, perhaps 32 for AVX2) */ + + filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y); + filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y); + + for (p = 0; p < 2; p++) { + dst = f->data[1 + p] + uvoff; + filter_plane_cols(s, col, s->ss_h, s->ss_v, lflvl->level, uv_masks[0], dst, ls_uv); + filter_plane_rows(s, row, s->ss_h, s->ss_v, lflvl->level, uv_masks[1], dst, ls_uv); + } +} diff --git a/media/ffvpx/libavcodec/vp9mvs.c b/media/ffvpx/libavcodec/vp9mvs.c new file mode 100644 index 000000000..88db1c341 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9mvs.c @@ -0,0 +1,364 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "internal.h" +#include "vp56.h" +#include "vp9.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, + VP9TileData *td) +{ + dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x); + dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y); +} + +static void find_ref_mvs(VP9TileData *td, + VP56mv *pmv, int ref, int z, int idx, int sb) +{ + static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { + [BS_64x64] = { { 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 }, + { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 } }, + [BS_64x32] = { { 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 } }, + [BS_32x64] = { { -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 }, + { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 } }, + [BS_32x32] = { { 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } }, + [BS_32x16] = { { 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 }, + { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } }, + [BS_16x32] = { { -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 }, + { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 } }, + [BS_16x16] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 }, + { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } }, + [BS_16x8] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 }, + { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 } }, + [BS_8x16] = { { -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 }, + { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 } }, + [BS_8x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + [BS_8x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + [BS_4x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + [BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, + { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, + }; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; + const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; +#define INVALID_MV 0x80008000U + uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; + int i; + +#define RETURN_DIRECT_MV(mv) \ + do { \ + uint32_t m = AV_RN32A(&mv); \ + if (!idx) { \ + AV_WN32A(pmv, m); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ + } while (0) + + if (sb >= 0) { + if (sb == 2 || sb == 1) { + RETURN_DIRECT_MV(b->mv[0][z]); + } else if (sb == 3) { + RETURN_DIRECT_MV(b->mv[2][z]); + RETURN_DIRECT_MV(b->mv[1][z]); + RETURN_DIRECT_MV(b->mv[0][z]); + } + +#define RETURN_MV(mv) \ + do { \ + if (sb > 0) { \ + VP56mv tmp; \ + uint32_t m; \ + av_assert2(idx == 1); \ + av_assert2(mem != INVALID_MV); \ + if (mem_sub8x8 == INVALID_MV) { \ + clamp_mv(&tmp, &mv, td); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ + mem_sub8x8 = AV_RN32A(&mv); \ + } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ + clamp_mv(&tmp, &mv, td); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + } else { \ + /* BUG I'm pretty sure this isn't the intention */ \ + AV_WN32A(pmv, 0); \ + } \ + return; \ + } \ + } else { \ + uint32_t m = AV_RN32A(&mv); \ + if (!idx) { \ + clamp_mv(pmv, &mv, td); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + clamp_mv(pmv, &mv, td); \ + return; \ + } \ + } \ + } while (0) + + if (row > 0) { + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col]; + if (mv->ref[0] == ref) + RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]); + else if (mv->ref[1] == ref) + RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); + } + if (col > td->tile_col_start) { + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; + if (mv->ref[0] == ref) + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]); + else if (mv->ref[1] == ref) + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]); + } + i = 2; + } else { + i = 0; + } + + // previously coded MVs in this neighborhood, using same reference frame + for (; i < 8; i++) { + int c = p[i][0] + col, r = p[i][1] + row; + + if (c >= td->tile_col_start && c < s->cols && + r >= 0 && r < s->rows) { + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + + if (mv->ref[0] == ref) + RETURN_MV(mv->mv[0]); + else if (mv->ref[1] == ref) + RETURN_MV(mv->mv[1]); + } + } + + // MV at this position in previous frame, using same reference frame + if (s->s.h.use_last_frame_mvs) { + VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + + if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) + ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0); + if (mv->ref[0] == ref) + RETURN_MV(mv->mv[0]); + else if (mv->ref[1] == ref) + RETURN_MV(mv->mv[1]); + } + +#define RETURN_SCALE_MV(mv, scale) \ + do { \ + if (scale) { \ + VP56mv mv_temp = { -mv.x, -mv.y }; \ + RETURN_MV(mv_temp); \ + } else { \ + RETURN_MV(mv); \ + } \ + } while (0) + + // previously coded MVs in this neighborhood, using different reference frame + for (i = 0; i < 8; i++) { + int c = p[i][0] + col, r = p[i][1] + row; + + if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; + + if (mv->ref[0] != ref && mv->ref[0] >= 0) + RETURN_SCALE_MV(mv->mv[0], + s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); + if (mv->ref[1] != ref && mv->ref[1] >= 0 && + // BUG - libvpx has this condition regardless of whether + // we used the first ref MV and pre-scaling + AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { + RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + } + } + } + + // MV at this position in previous frame, using different reference frame + if (s->s.h.use_last_frame_mvs) { + VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + + // no need to await_progress, because we already did that above + if (mv->ref[0] != ref && mv->ref[0] >= 0) + RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]); + if (mv->ref[1] != ref && mv->ref[1] >= 0 && + // BUG - libvpx has this condition regardless of whether + // we used the first ref MV and pre-scaling + AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) { + RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + } + } + + AV_ZERO32(pmv); + clamp_mv(pmv, pmv, td); +#undef INVALID_MV +#undef RETURN_MV +#undef RETURN_SCALE_MV +} + +static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp) +{ + VP9Context *s = td->s; + int bit, sign = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].sign); + int n, c = vp8_rac_get_tree(td->c, ff_vp9_mv_class_tree, + s->prob.p.mv_comp[idx].classes); + + td->counts.mv_comp[idx].sign[sign]++; + td->counts.mv_comp[idx].classes[c]++; + if (c) { + int m; + + for (n = 0, m = 0; m < c; m++) { + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].bits[m]); + n |= bit << m; + td->counts.mv_comp[idx].bits[m][bit]++; + } + n <<= 3; + bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree, + s->prob.p.mv_comp[idx].fp); + n |= bit << 1; + td->counts.mv_comp[idx].fp[bit]++; + if (hp) { + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].hp); + td->counts.mv_comp[idx].hp[bit]++; + n |= bit; + } else { + n |= 1; + // bug in libvpx - we count for bw entropy purposes even if the + // bit wasn't coded + td->counts.mv_comp[idx].hp[1]++; + } + n += 8 << c; + } else { + n = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0); + td->counts.mv_comp[idx].class0[n]++; + bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree, + s->prob.p.mv_comp[idx].class0_fp[n]); + td->counts.mv_comp[idx].class0_fp[n][bit]++; + n = (n << 3) | (bit << 1); + if (hp) { + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0_hp); + td->counts.mv_comp[idx].class0_hp[bit]++; + n |= bit; + } else { + n |= 1; + // bug in libvpx - we count for bw entropy purposes even if the + // bit wasn't coded + td->counts.mv_comp[idx].class0_hp[1]++; + } + } + + return sign ? -(n + 1) : (n + 1); +} + +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + + if (mode == ZEROMV) { + AV_ZERO64(mv); + } else { + int hp; + + // FIXME cache this value and reuse for other subblocks + find_ref_mvs(td, &mv[0], b->ref[0], 0, mode == NEARMV, + mode == NEWMV ? -1 : sb); + // FIXME maybe move this code into find_ref_mvs() + if ((mode == NEWMV || sb == -1) && + !(hp = s->s.h.highprecisionmvs && + abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) { + if (mv[0].y & 1) { + if (mv[0].y < 0) + mv[0].y++; + else + mv[0].y--; + } + if (mv[0].x & 1) { + if (mv[0].x < 0) + mv[0].x++; + else + mv[0].x--; + } + } + if (mode == NEWMV) { + enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree, + s->prob.p.mv_joint); + + td->counts.mv_joint[j]++; + if (j >= MV_JOINT_V) + mv[0].y += read_mv_component(td, 0, hp); + if (j & 1) + mv[0].x += read_mv_component(td, 1, hp); + } + + if (b->comp) { + // FIXME cache this value and reuse for other subblocks + find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV, + mode == NEWMV ? -1 : sb); + if ((mode == NEWMV || sb == -1) && + !(hp = s->s.h.highprecisionmvs && + abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) { + if (mv[1].y & 1) { + if (mv[1].y < 0) + mv[1].y++; + else + mv[1].y--; + } + if (mv[1].x & 1) { + if (mv[1].x < 0) + mv[1].x++; + else + mv[1].x--; + } + } + if (mode == NEWMV) { + enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree, + s->prob.p.mv_joint); + + td->counts.mv_joint[j]++; + if (j >= MV_JOINT_V) + mv[1].y += read_mv_component(td, 0, hp); + if (j & 1) + mv[1].x += read_mv_component(td, 1, hp); + } + } + } +} diff --git a/media/ffvpx/libavcodec/vp9prob.c b/media/ffvpx/libavcodec/vp9prob.c new file mode 100644 index 000000000..fb295b482 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9prob.c @@ -0,0 +1,274 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 "vp56.h" +#include "vp9.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1, + int max_count, int update_factor) +{ + unsigned ct = ct0 + ct1, p2, p1; + + if (!ct) + return; + + update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count); + p1 = *p; + p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct; + p2 = av_clip(p2, 1, 255); + + // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8 + *p = p1 + (((p2 - p1) * update_factor + 128) >> 8); +} + +void ff_vp9_adapt_probs(VP9Context *s) +{ + int i, j, k, l, m; + ProbContext *p = &s->prob_ctx[s->s.h.framectxid].p; + int uf = (s->s.h.keyframe || s->s.h.intraonly || !s->last_keyframe) ? 112 : 128; + + // coefficients + for (i = 0; i < 4; i++) + for (j = 0; j < 2; j++) + for (k = 0; k < 2; k++) + for (l = 0; l < 6; l++) + for (m = 0; m < 6; m++) { + uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m]; + unsigned *e = s->td[0].counts.eob[i][j][k][l][m]; + unsigned *c = s->td[0].counts.coef[i][j][k][l][m]; + + if (l == 0 && m >= 3) // dc only has 3 pt + break; + + adapt_prob(&pp[0], e[0], e[1], 24, uf); + adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf); + adapt_prob(&pp[2], c[1], c[2], 24, uf); + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + memcpy(p->skip, s->prob.p.skip, sizeof(p->skip)); + memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p)); + memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p)); + memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p)); + return; + } + + // skip flag + for (i = 0; i < 3; i++) + adapt_prob(&p->skip[i], s->td[0].counts.skip[i][0], + s->td[0].counts.skip[i][1], 20, 128); + + // intra/inter flag + for (i = 0; i < 4; i++) + adapt_prob(&p->intra[i], s->td[0].counts.intra[i][0], + s->td[0].counts.intra[i][1], 20, 128); + + // comppred flag + if (s->s.h.comppredmode == PRED_SWITCHABLE) { + for (i = 0; i < 5; i++) + adapt_prob(&p->comp[i], s->td[0].counts.comp[i][0], + s->td[0].counts.comp[i][1], 20, 128); + } + + // reference frames + if (s->s.h.comppredmode != PRED_SINGLEREF) { + for (i = 0; i < 5; i++) + adapt_prob(&p->comp_ref[i], s->td[0].counts.comp_ref[i][0], + s->td[0].counts.comp_ref[i][1], 20, 128); + } + + if (s->s.h.comppredmode != PRED_COMPREF) { + for (i = 0; i < 5; i++) { + uint8_t *pp = p->single_ref[i]; + unsigned (*c)[2] = s->td[0].counts.single_ref[i]; + + adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); + adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); + } + } + + // block partitioning + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) { + uint8_t *pp = p->partition[i][j]; + unsigned *c = s->td[0].counts.partition[i][j]; + + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + } + + // tx size + if (s->s.h.txfmmode == TX_SWITCHABLE) { + for (i = 0; i < 2; i++) { + unsigned *c16 = s->td[0].counts.tx16p[i], *c32 = s->td[0].counts.tx32p[i]; + + adapt_prob(&p->tx8p[i], s->td[0].counts.tx8p[i][0], + s->td[0].counts.tx8p[i][1], 20, 128); + adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); + adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); + adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); + adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128); + adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128); + } + } + + // interpolation filter + if (s->s.h.filtermode == FILTER_SWITCHABLE) { + for (i = 0; i < 4; i++) { + uint8_t *pp = p->filter[i]; + unsigned *c = s->td[0].counts.filter[i]; + + adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); + adapt_prob(&pp[1], c[1], c[2], 20, 128); + } + } + + // inter modes + for (i = 0; i < 7; i++) { + uint8_t *pp = p->mv_mode[i]; + unsigned *c = s->td[0].counts.mv_mode[i]; + + adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128); + adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128); + adapt_prob(&pp[2], c[1], c[3], 20, 128); + } + + // mv joints + { + uint8_t *pp = p->mv_joint; + unsigned *c = s->td[0].counts.mv_joint; + + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + } + + // mv components + for (i = 0; i < 2; i++) { + uint8_t *pp; + unsigned *c, (*c2)[2], sum; + + adapt_prob(&p->mv_comp[i].sign, s->td[0].counts.mv_comp[i].sign[0], + s->td[0].counts.mv_comp[i].sign[1], 20, 128); + + pp = p->mv_comp[i].classes; + c = s->td[0].counts.mv_comp[i].classes; + sum = c[1] + c[2] + c[3] + c[4] + c[5] + + c[6] + c[7] + c[8] + c[9] + c[10]; + adapt_prob(&pp[0], c[0], sum, 20, 128); + sum -= c[1]; + adapt_prob(&pp[1], c[1], sum, 20, 128); + sum -= c[2] + c[3]; + adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128); + adapt_prob(&pp[3], c[2], c[3], 20, 128); + sum -= c[4] + c[5]; + adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128); + adapt_prob(&pp[5], c[4], c[5], 20, 128); + sum -= c[6]; + adapt_prob(&pp[6], c[6], sum, 20, 128); + adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128); + adapt_prob(&pp[8], c[7], c[8], 20, 128); + adapt_prob(&pp[9], c[9], c[10], 20, 128); + + adapt_prob(&p->mv_comp[i].class0, s->td[0].counts.mv_comp[i].class0[0], + s->td[0].counts.mv_comp[i].class0[1], 20, 128); + pp = p->mv_comp[i].bits; + c2 = s->td[0].counts.mv_comp[i].bits; + for (j = 0; j < 10; j++) + adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128); + + for (j = 0; j < 2; j++) { + pp = p->mv_comp[i].class0_fp[j]; + c = s->td[0].counts.mv_comp[i].class0_fp[j]; + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + } + pp = p->mv_comp[i].fp; + c = s->td[0].counts.mv_comp[i].fp; + adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); + adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); + adapt_prob(&pp[2], c[2], c[3], 20, 128); + + if (s->s.h.highprecisionmvs) { + adapt_prob(&p->mv_comp[i].class0_hp, + s->td[0].counts.mv_comp[i].class0_hp[0], + s->td[0].counts.mv_comp[i].class0_hp[1], 20, 128); + adapt_prob(&p->mv_comp[i].hp, s->td[0].counts.mv_comp[i].hp[0], + s->td[0].counts.mv_comp[i].hp[1], 20, 128); + } + } + + // y intra modes + for (i = 0; i < 4; i++) { + uint8_t *pp = p->y_mode[i]; + unsigned *c = s->td[0].counts.y_mode[i], sum, s2; + + sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; + adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); + sum -= c[TM_VP8_PRED]; + adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); + sum -= c[VERT_PRED]; + adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); + s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; + sum -= s2; + adapt_prob(&pp[3], s2, sum, 20, 128); + s2 -= c[HOR_PRED]; + adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); + adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], + 20, 128); + sum -= c[DIAG_DOWN_LEFT_PRED]; + adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); + sum -= c[VERT_LEFT_PRED]; + adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); + adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); + } + + // uv intra modes + for (i = 0; i < 10; i++) { + uint8_t *pp = p->uv_mode[i]; + unsigned *c = s->td[0].counts.uv_mode[i], sum, s2; + + sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; + adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); + sum -= c[TM_VP8_PRED]; + adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128); + sum -= c[VERT_PRED]; + adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128); + s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; + sum -= s2; + adapt_prob(&pp[3], s2, sum, 20, 128); + s2 -= c[HOR_PRED]; + adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128); + adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], + 20, 128); + sum -= c[DIAG_DOWN_LEFT_PRED]; + adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128); + sum -= c[VERT_LEFT_PRED]; + adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128); + adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128); + } +} diff --git a/media/ffvpx/libavcodec/vp9recon.c b/media/ffvpx/libavcodec/vp9recon.c new file mode 100644 index 000000000..49bb04e1f --- /dev/null +++ b/media/ffvpx/libavcodec/vp9recon.c @@ -0,0 +1,644 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avassert.h" + +#include "avcodec.h" +#include "internal.h" +#include "videodsp.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline int check_intra_mode(VP9TileData *td, int mode, uint8_t **a, + uint8_t *dst_edge, ptrdiff_t stride_edge, + uint8_t *dst_inner, ptrdiff_t stride_inner, + uint8_t *l, int col, int x, int w, + int row, int y, enum TxfmMode tx, + int p, int ss_h, int ss_v, int bytesperpixel) +{ + VP9Context *s = td->s; + int have_top = row > 0 || y > 0; + int have_left = col > td->tile_col_start || x > 0; + int have_right = x < w - 1; + int bpp = s->s.h.bpp; + static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { + [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, + { DC_127_PRED, VERT_PRED } }, + [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_PRED, HOR_PRED } }, + [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, + { LEFT_DC_PRED, DC_PRED } }, + [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, + { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, + [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, + { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, + [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, + { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, + [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, + { HOR_DOWN_PRED, HOR_DOWN_PRED } }, + [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, + { DC_127_PRED, VERT_LEFT_PRED } }, + [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, + { HOR_UP_PRED, HOR_UP_PRED } }, + [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, + { HOR_PRED, TM_VP8_PRED } }, + }; + static const struct { + uint8_t needs_left:1; + uint8_t needs_top:1; + uint8_t needs_topleft:1; + uint8_t needs_topright:1; + uint8_t invert_left:1; + } edges[N_INTRA_PRED_MODES] = { + [VERT_PRED] = { .needs_top = 1 }, + [HOR_PRED] = { .needs_left = 1 }, + [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, + [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, + [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, + [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, + [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, + .needs_topleft = 1 }, + [LEFT_DC_PRED] = { .needs_left = 1 }, + [TOP_DC_PRED] = { .needs_top = 1 }, + [DC_128_PRED] = { 0 }, + [DC_127_PRED] = { 0 }, + [DC_129_PRED] = { 0 } + }; + + av_assert2(mode >= 0 && mode < 10); + mode = mode_conv[mode][have_left][have_top]; + if (edges[mode].needs_top) { + uint8_t *top, *topleft; + int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; + int n_px_need_tr = 0; + + if (tx == TX_4X4 && edges[mode].needs_topright && have_right) + n_px_need_tr = 4; + + // if top of sb64-row, use s->intra_pred_data[] instead of + // dst[-stride] for intra prediction (it contains pre- instead of + // post-loopfilter data) + if (have_top) { + top = !(row & 7) && !y ? + s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : + y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; + if (have_left) + topleft = !(row & 7) && !y ? + s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : + y == 0 || x == 0 ? &dst_edge[-stride_edge] : + &dst_inner[-stride_inner]; + } + + if (have_top && + (!edges[mode].needs_topleft || (have_left && top == topleft)) && + (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && + n_px_need + n_px_need_tr <= n_px_have) { + *a = top; + } else { + if (have_top) { + if (n_px_need <= n_px_have) { + memcpy(*a, top, n_px_need * bytesperpixel); + } else { +#define memset_bpp(c, i1, v, i2, num) do { \ + if (bytesperpixel == 1) { \ + memset(&(c)[(i1)], (v)[(i2)], (num)); \ + } else { \ + int n, val = AV_RN16A(&(v)[(i2) * 2]); \ + for (n = 0; n < (num); n++) { \ + AV_WN16A(&(c)[((i1) + n) * 2], val); \ + } \ + } \ +} while (0) + memcpy(*a, top, n_px_have * bytesperpixel); + memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have); + } + } else { +#define memset_val(c, val, num) do { \ + if (bytesperpixel == 1) { \ + memset((c), (val), (num)); \ + } else { \ + int n; \ + for (n = 0; n < (num); n++) { \ + AV_WN16A(&(c)[n * 2], (val)); \ + } \ + } \ +} while (0) + memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need); + } + if (edges[mode].needs_topleft) { + if (have_left && have_top) { +#define assign_bpp(c, i1, v, i2) do { \ + if (bytesperpixel == 1) { \ + (c)[(i1)] = (v)[(i2)]; \ + } else { \ + AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \ + } \ +} while (0) + assign_bpp(*a, -1, topleft, -1); + } else { +#define assign_val(c, i, v) do { \ + if (bytesperpixel == 1) { \ + (c)[(i)] = (v); \ + } else { \ + AV_WN16A(&(c)[(i) * 2], (v)); \ + } \ +} while (0) + assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1)); + } + } + if (tx == TX_4X4 && edges[mode].needs_topright) { + if (have_top && have_right && + n_px_need + n_px_need_tr <= n_px_have) { + memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); + } else { + memset_bpp(*a, 4, *a, 3, 4); + } + } + } + } + if (edges[mode].needs_left) { + if (have_left) { + int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; + uint8_t *dst = x == 0 ? dst_edge : dst_inner; + ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; + + if (edges[mode].invert_left) { + if (n_px_need <= n_px_have) { + for (i = 0; i < n_px_need; i++) + assign_bpp(l, i, &dst[i * stride], -1); + } else { + for (i = 0; i < n_px_have; i++) + assign_bpp(l, i, &dst[i * stride], -1); + memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have); + } + } else { + if (n_px_need <= n_px_have) { + for (i = 0; i < n_px_need; i++) + assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); + } else { + for (i = 0; i < n_px_have; i++) + assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1); + memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have); + } + } + } else { + memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx); + } + } + + return mode; +} + +static av_always_inline void intra_recon(VP9TileData *td, ptrdiff_t y_off, + ptrdiff_t uv_off, int bytesperpixel) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = td->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; + LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); + LOCAL_ALIGNED_32(uint8_t, l, [64]); + + for (n = 0, y = 0; y < end_y; y += step1d) { + uint8_t *ptr = dst, *ptr_r = dst_r; + for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, + ptr_r += 4 * step1d * bytesperpixel, n += step) { + int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? + y * 2 + x : 0]; + uint8_t *a = &a_buf[32]; + enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; + int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; + + mode = check_intra_mode(td, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[0], + ptr, td->y_stride, l, + col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); + s->dsp.intra_pred[b->tx][mode](ptr, td->y_stride, l, a); + if (eob) + s->dsp.itxfm_add[tx][txtp](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; + dst += 4 * step1d * td->y_stride; + } + + // U/V + w4 >>= s->ss_h; + end_x >>= s->ss_h; + end_y >>= s->ss_v; + step = 1 << (b->uvtx * 2); + for (p = 0; p < 2; p++) { + dst = td->dst[1 + p]; + dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; + for (n = 0, y = 0; y < end_y; y += uvstep1d) { + uint8_t *ptr = dst, *ptr_r = dst_r; + for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, + ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { + int mode = b->uvmode; + uint8_t *a = &a_buf[32]; + int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n]) : td->uveob[p][n]; + + mode = check_intra_mode(td, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[1], + ptr, td->uv_stride, l, col, x, w4, row, y, + b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); + s->dsp.intra_pred[b->uvtx][mode](ptr, td->uv_stride, l, a); + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; + dst += 4 * uvstep1d * td->uv_stride; + } + } +} + +void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(td, y_off, uv_off, 1); +} + +void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(td, y_off, uv_off, 2); +} + +static av_always_inline void mc_luma_unscaled(VP9TileData *td, vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, int bytesperpixel) +{ + VP9Context *s = td->s; + int mx = mv->x, my = mv->y, th; + + y += my >> 3; + x += mx >> 3; + ref += y * ref_stride + x * bytesperpixel; + mx &= 7; + my &= 7; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, + 160, ref_stride, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_stride = 160; + } + mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); +} + +static av_always_inline void mc_chroma_unscaled(VP9TileData *td, vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, int bytesperpixel) +{ + VP9Context *s = td->s; + int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; + + y += my >> 4; + x += mx >> 4; + ref_u += y * src_stride_u + x * bytesperpixel; + ref_v += y * src_stride_v + x * bytesperpixel; + mx &= 15; + my &= 15; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, + 160, src_stride_u, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref_u = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); + + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, + 160, src_stride_v, + bw + !!mx * 7, bh + !!my * 7, + x - !!mx * 3, y - !!my * 3, w, h); + ref_v = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); + } else { + mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); + mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); + } +} + +#define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_unscaled(td, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, bw, bh, w, h, bytesperpixel) +#define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ + mc_chroma_unscaled(td, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h, bytesperpixel) +#define SCALED 0 +#define FN(x) x##_8bpp +#define BYTES_PER_PIXEL 1 +#include "vp9_mc_template.c" +#undef FN +#undef BYTES_PER_PIXEL +#define FN(x) x##_16bpp +#define BYTES_PER_PIXEL 2 +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void mc_luma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, + vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, + int px, int py, int pw, int ph, + int bw, int bh, int w, int h, int bytesperpixel, + const uint16_t *scale, const uint8_t *step) +{ + VP9Context *s = td->s; + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_luma_unscaled(td, mc, dst, dst_stride, ref, ref_stride, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { +#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + // BUG libvpx seems to scale the two components separately. This introduces + // rounding errors but we have to reproduce them to be exactly compatible + // with the output from libvpx... + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); + + y = my >> 4; + x = mx >> 4; + ref += y * ref_stride + x * bytesperpixel; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + ref - 3 * ref_stride - 3 * bytesperpixel, + 288, ref_stride, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_stride = 288; + } + smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); + } +} + +static av_always_inline void mc_chroma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, + vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, + int px, int py, int pw, int ph, + int bw, int bh, int w, int h, int bytesperpixel, + const uint16_t *scale, const uint8_t *step) +{ + VP9Context *s = td->s; + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_chroma_unscaled(td, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, + ref_v, src_stride_v, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + if (s->ss_h) { + // BUG https://code.google.com/p/webm/issues/detail?id=820 + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); + mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); + } else { + mv.x = av_clip(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + } + if (s->ss_v) { + // BUG https://code.google.com/p/webm/issues/detail?id=820 + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); + my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); + } else { + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); + } +#undef scale_mv + y = my >> 4; + x = mx >> 4; + ref_u += y * src_stride_u + x * bytesperpixel; + ref_v += y * src_stride_v + x * bytesperpixel; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + ref_u - 3 * src_stride_u - 3 * bytesperpixel, + 288, src_stride_u, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_u = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); + + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, + ref_v - 3 * src_stride_v - 3 * bytesperpixel, + 288, src_stride_v, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_v = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); + } else { + smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); + smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); + } + } +} + +#define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_scaled(td, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ + s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ + mc_chroma_scaled(td, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ + s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define SCALED 1 +#define FN(x) x##_scaled_8bpp +#define BYTES_PER_PIXEL 1 +#include "vp9_mc_template.c" +#undef FN +#undef BYTES_PER_PIXEL +#define FN(x) x##_scaled_16bpp +#define BYTES_PER_PIXEL 2 +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void inter_recon(VP9TileData *td, int bytesperpixel) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; + + if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { + if (bytesperpixel == 1) { + inter_pred_scaled_8bpp(td); + } else { + inter_pred_scaled_16bpp(td); + } + } else { + if (bytesperpixel == 1) { + inter_pred_8bpp(td); + } else { + inter_pred_16bpp(td); + } + } + + if (!b->skip) { + /* mostly copied intra_recon() */ + + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); + int end_x = FFMIN(2 * (s->cols - col), w4); + int end_y = FFMIN(2 * (s->rows - row), h4); + int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = td->dst[0]; + + // y itxfm add + for (n = 0, y = 0; y < end_y; y += step1d) { + uint8_t *ptr = dst; + for (x = 0; x < end_x; x += step1d, + ptr += 4 * step1d * bytesperpixel, n += step) { + int eob = b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; + + if (eob) + s->dsp.itxfm_add[tx][DCT_DCT](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); + } + dst += 4 * td->y_stride * step1d; + } + + // uv itxfm add + end_x >>= s->ss_h; + end_y >>= s->ss_v; + step = 1 << (b->uvtx * 2); + for (p = 0; p < 2; p++) { + dst = td->dst[p + 1]; + for (n = 0, y = 0; y < end_y; y += uvstep1d) { + uint8_t *ptr = dst; + for (x = 0; x < end_x; x += uvstep1d, + ptr += 4 * uvstep1d * bytesperpixel, n += step) { + int eob = b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n]) : td->uveob[p][n]; + + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst += 4 * uvstep1d * td->uv_stride; + } + } + } +} + +void ff_vp9_inter_recon_8bpp(VP9TileData *td) +{ + inter_recon(td, 1); +} + +void ff_vp9_inter_recon_16bpp(VP9TileData *td) +{ + inter_recon(td, 2); +} diff --git a/media/ffvpx/libavcodec/vp9shared.h b/media/ffvpx/libavcodec/vp9shared.h new file mode 100644 index 000000000..54726df74 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9shared.h @@ -0,0 +1,169 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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_VP9SHARED_H +#define AVCODEC_VP9SHARED_H + +#include +#include + +#include "vp9.h" +#include "thread.h" +#include "vp56.h" + +enum BlockPartition { + PARTITION_NONE, // [ ] <-. + PARTITION_H, // [-] | + PARTITION_V, // [|] | + PARTITION_SPLIT, // [+] --' +}; + +enum InterPredMode { + NEARESTMV = 10, + NEARMV = 11, + ZEROMV = 12, + NEWMV = 13, +}; + +enum CompPredMode { + PRED_SINGLEREF, + PRED_COMPREF, + PRED_SWITCHABLE, +}; + +typedef struct VP9mvrefPair { + VP56mv mv[2]; + int8_t ref[2]; +} VP9mvrefPair; + +typedef struct VP9Frame { + ThreadFrame tf; + AVBufferRef *extradata; + uint8_t *segmentation_map; + VP9mvrefPair *mv; + int uses_2pass; + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; +} VP9Frame; + +enum BlockLevel { + BL_64X64, + BL_32X32, + BL_16X16, + BL_8X8, +}; + +enum BlockSize { + BS_64x64, + BS_64x32, + BS_32x64, + BS_32x32, + BS_32x16, + BS_16x32, + BS_16x16, + BS_16x8, + BS_8x16, + BS_8x8, + BS_8x4, + BS_4x8, + BS_4x4, + N_BS_SIZES, +}; + +typedef struct VP9BitstreamHeader { + // bitstream header + uint8_t profile; + uint8_t bpp; + uint8_t keyframe; + uint8_t invisible; + uint8_t errorres; + uint8_t intraonly; + uint8_t resetctx; + uint8_t refreshrefmask; + uint8_t highprecisionmvs; + enum FilterMode filtermode; + uint8_t allowcompinter; + uint8_t refreshctx; + uint8_t parallelmode; + uint8_t framectxid; + uint8_t use_last_frame_mvs; + uint8_t refidx[3]; + uint8_t signbias[3]; + uint8_t fixcompref; + uint8_t varcompref[2]; + struct { + uint8_t level; + int8_t sharpness; + } filter; + struct { + uint8_t enabled; + uint8_t updated; + int8_t mode[2]; + int8_t ref[4]; + } lf_delta; + 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; + uint8_t absolute_vals; + uint8_t update_map; + uint8_t prob[7]; + uint8_t pred_prob[3]; + struct { + uint8_t q_enabled; + uint8_t lf_enabled; + uint8_t ref_enabled; + uint8_t skip_enabled; + uint8_t ref_val; + int16_t q_val; + int8_t lf_val; + int16_t qmul[2][2]; + uint8_t lflvl[4][2]; + } feat[MAX_SEGMENT]; + } segmentation; + enum TxfmMode txfmmode; + enum CompPredMode comppredmode; + struct { + unsigned log2_tile_cols, log2_tile_rows; + unsigned tile_cols, tile_rows; + } tiling; + + int uncompressed_header_size; + int compressed_header_size; +} VP9BitstreamHeader; + +typedef struct VP9SharedContext { + VP9BitstreamHeader h; + + ThreadFrame refs[8]; +#define CUR_FRAME 0 +#define REF_FRAME_MVPAIR 1 +#define REF_FRAME_SEGMAP 2 + VP9Frame frames[3]; +} VP9SharedContext; + +#endif /* AVCODEC_VP9SHARED_H */ diff --git a/media/ffvpx/libavcodec/x86/constants.h b/media/ffvpx/libavcodec/x86/constants.h index b82aef9a4..bbb0ef844 100644 --- a/media/ffvpx/libavcodec/x86/constants.h +++ b/media/ffvpx/libavcodec/x86/constants.h @@ -43,6 +43,7 @@ extern const xmm_reg ff_pw_64; extern const uint64_t ff_pw_96; extern const uint64_t ff_pw_128; extern const ymm_reg ff_pw_255; +extern const ymm_reg ff_pw_256; extern const ymm_reg ff_pw_512; extern const ymm_reg ff_pw_1023; extern const ymm_reg ff_pw_1024; diff --git a/media/ffvpx/libavcodec/x86/flacdsp_init.c b/media/ffvpx/libavcodec/x86/flacdsp_init.c index e28c5c932..1971f81b8 100644 --- a/media/ffvpx/libavcodec/x86/flacdsp_init.c +++ b/media/ffvpx/libavcodec/x86/flacdsp_init.c @@ -53,7 +53,7 @@ DECORRELATE_FUNCS(32, avx); av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); #if CONFIG_FLAC_DECODER @@ -111,5 +111,5 @@ av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int c->lpc16_encode = ff_flac_enc_lpc_16_sse4; } #endif -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/h264_i386.h b/media/ffvpx/libavcodec/x86/h264_i386.h deleted file mode 100644 index 19cd12838..000000000 --- a/media/ffvpx/libavcodec/x86/h264_i386.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 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 - * H.264 / AVC / MPEG-4 part10 codec. - * non-MMX i386-specific optimizations for H.264 - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_X86_H264_I386_H -#define AVCODEC_X86_H264_I386_H - -#include - -#include "libavcodec/cabac.h" -#include "cabac.h" - -#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 -#define decode_significance decode_significance_x86 -static int decode_significance_x86(CABACContext *c, int max_coeff, - uint8_t *significant_coeff_ctx_base, - int *index, x86_reg last_off){ - void *end= significant_coeff_ctx_base + max_coeff - 1; - int minusstart= -(intptr_t)significant_coeff_ctx_base; - int minusindex= 4-(intptr_t)index; - int bit; - x86_reg coeff_count; - -#ifdef BROKEN_RELOCATIONS - void *tables; - - __asm__ volatile( - "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" - : "=&r"(tables) - : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) - ); -#endif - - __asm__ volatile( - "3: \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c11(%6)", "%c12(%6)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%13") - - "test $1, %4 \n\t" - " jz 4f \n\t" - "add %10, %1 \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c11(%6)", "%c12(%6)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%13") - - "sub %10, %1 \n\t" - "mov %2, %0 \n\t" - "movl %7, %%ecx \n\t" - "add %1, %%"FF_REG_c" \n\t" - "movl %%ecx, (%0) \n\t" - - "test $1, %4 \n\t" - " jnz 5f \n\t" - - "add"FF_OPSIZE" $4, %2 \n\t" - - "4: \n\t" - "add $1, %1 \n\t" - "cmp %8, %1 \n\t" - " jb 3b \n\t" - "mov %2, %0 \n\t" - "movl %7, %%ecx \n\t" - "add %1, %%"FF_REG_c" \n\t" - "movl %%ecx, (%0) \n\t" - "5: \n\t" - "add %9, %k0 \n\t" - "shr $2, %k0 \n\t" - : "=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), - "+&r"(c->low), "=&r"(bit), "+&r"(c->range) - : "r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), - "i"(offsetof(CABACContext, bytestream)), - "i"(offsetof(CABACContext, bytestream_end)) - TABLES_ARG - : "%"FF_REG_c, "memory" - ); - return coeff_count; -} - -#define decode_significance_8x8 decode_significance_8x8_x86 -static int decode_significance_8x8_x86(CABACContext *c, - uint8_t *significant_coeff_ctx_base, - int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){ - int minusindex= 4-(intptr_t)index; - int bit; - x86_reg coeff_count; - x86_reg last=0; - x86_reg state; - -#ifdef BROKEN_RELOCATIONS - void *tables; - - __asm__ volatile( - "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" - : "=&r"(tables) - : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) - ); -#endif - - __asm__ volatile( - "mov %1, %6 \n\t" - "3: \n\t" - - "mov %10, %0 \n\t" - "movzb (%0, %6), %6 \n\t" - "add %9, %6 \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c12(%7)", "%c13(%7)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%15") - - "mov %1, %6 \n\t" - "test $1, %4 \n\t" - " jz 4f \n\t" - -#ifdef BROKEN_RELOCATIONS - "movzb %c14(%15, %q6), %6\n\t" -#else - "movzb "MANGLE(ff_h264_cabac_tables)"+%c14(%6), %6\n\t" -#endif - "add %11, %6 \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c12(%7)", "%c13(%7)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%15") - - "mov %2, %0 \n\t" - "mov %1, %6 \n\t" - "mov %k6, (%0) \n\t" - - "test $1, %4 \n\t" - " jnz 5f \n\t" - - "add"FF_OPSIZE" $4, %2 \n\t" - - "4: \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" - "mov %k6, (%0) \n\t" - "5: \n\t" - "addl %8, %k0 \n\t" - "shr $2, %k0 \n\t" - : "=&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), - 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 - : "%"FF_REG_c, "memory" - ); - return coeff_count; -} -#endif /* HAVE_7REGS && BROKEN_COMPILER */ - -#endif /* HAVE_INLINE_ASM */ -#endif /* AVCODEC_X86_H264_I386_H */ diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred.asm b/media/ffvpx/libavcodec/x86/h264_intrapred.asm index c88d91b49..f3aa3172f 100644 --- a/media/ffvpx/libavcodec/x86/h264_intrapred.asm +++ b/media/ffvpx/libavcodec/x86/h264_intrapred.asm @@ -49,7 +49,7 @@ cextern pw_17 cextern pw_32 ;----------------------------------------------------------------------------- -; void ff_pred16x16_vertical_8(uint8_t *src, int stride) +; void ff_pred16x16_vertical_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -85,7 +85,7 @@ cglobal pred16x16_vertical_8, 2,3 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred16x16_horizontal_8(uint8_t *src, int stride) +; void ff_pred16x16_horizontal_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_H 0 @@ -126,7 +126,7 @@ INIT_XMM ssse3 PRED16x16_H ;----------------------------------------------------------------------------- -; void ff_pred16x16_dc_8(uint8_t *src, int stride) +; void ff_pred16x16_dc_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_DC 0 @@ -188,7 +188,7 @@ INIT_XMM ssse3 PRED16x16_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_tm_vp8_8(uint8_t *src, int stride) +; void ff_pred16x16_tm_vp8_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_TM 0 @@ -268,8 +268,45 @@ cglobal pred16x16_tm_vp8_8, 2,6,6 jg .loop REP_RET +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal pred16x16_tm_vp8_8, 2, 4, 5, dst, stride, stride3, iteration + sub dstq, strideq + pmovzxbw m0, [dstq] + vpbroadcastb xm1, [r0-1] + pmovzxbw m1, xm1 + psubw m0, m1 + mov iterationd, 4 + lea stride3q, [strideq*3] +.loop: + vpbroadcastb xm1, [dstq+strideq*1-1] + vpbroadcastb xm2, [dstq+strideq*2-1] + vpbroadcastb xm3, [dstq+stride3q-1] + vpbroadcastb xm4, [dstq+strideq*4-1] + pmovzxbw m1, xm1 + pmovzxbw m2, xm2 + pmovzxbw m3, xm3 + pmovzxbw m4, xm4 + paddw m1, m0 + paddw m2, m0 + paddw m3, m0 + paddw m4, m0 + vpackuswb m1, m1, m2 + vpackuswb m3, m3, m4 + vpermq m1, m1, q3120 + vpermq m3, m3, q3120 + movdqa [dstq+strideq*1], xm1 + vextracti128 [dstq+strideq*2], m1, 1 + movdqa [dstq+stride3q*1], xm3 + vextracti128 [dstq+strideq*4], m3, 1 + lea dstq, [dstq+strideq*4] + dec iterationd + jg .loop + REP_RET +%endif + ;----------------------------------------------------------------------------- -; void ff_pred16x16_plane_*_8(uint8_t *src, int stride) +; void ff_pred16x16_plane_*_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro H264_PRED16x16_PLANE 1 @@ -550,7 +587,7 @@ H264_PRED16x16_PLANE rv40 H264_PRED16x16_PLANE svq3 ;----------------------------------------------------------------------------- -; void ff_pred8x8_plane_8(uint8_t *src, int stride) +; void ff_pred8x8_plane_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro H264_PRED8x8_PLANE 0 @@ -724,7 +761,7 @@ INIT_XMM ssse3 H264_PRED8x8_PLANE ;----------------------------------------------------------------------------- -; void ff_pred8x8_vertical_8(uint8_t *src, int stride) +; void ff_pred8x8_vertical_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -741,7 +778,7 @@ cglobal pred8x8_vertical_8, 2,2 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_horizontal_8(uint8_t *src, int stride) +; void ff_pred8x8_horizontal_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8_H 0 @@ -769,7 +806,7 @@ INIT_MMX ssse3 PRED8x8_H ;----------------------------------------------------------------------------- -; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, int stride) +; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred8x8_top_dc_8, 2,5 @@ -803,7 +840,7 @@ cglobal pred8x8_top_dc_8, 2,5 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_dc_8_mmxext(uint8_t *src, int stride) +; void ff_pred8x8_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -864,7 +901,7 @@ cglobal pred8x8_dc_8, 2,5 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_dc_rv40_8(uint8_t *src, int stride) +; void ff_pred8x8_dc_rv40_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -901,7 +938,7 @@ cglobal pred8x8_dc_rv40_8, 2,7 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_tm_vp8_8(uint8_t *src, int stride) +; void ff_pred8x8_tm_vp8_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8_TM 0 @@ -1014,7 +1051,7 @@ cglobal pred8x8_tm_vp8_8, 2,3,6 ;----------------------------------------------------------------------------- ; void ff_pred8x8l_top_dc_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_TOP_DC 0 cglobal pred8x8l_top_dc_8, 4,4 @@ -1070,7 +1107,7 @@ PRED8x8L_TOP_DC ;----------------------------------------------------------------------------- ; void ff_pred8x8l_dc_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DC 0 @@ -1174,7 +1211,7 @@ PRED8x8L_DC ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL 0 @@ -1246,7 +1283,7 @@ PRED8x8L_HORIZONTAL ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL 0 @@ -1297,7 +1334,7 @@ PRED8x8L_VERTICAL ;----------------------------------------------------------------------------- ; void ff_pred8x8l_down_left_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1498,7 +1535,7 @@ PRED8x8L_DOWN_LEFT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_down_right_8_mmxext(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1750,7 +1787,7 @@ PRED8x8L_DOWN_RIGHT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_right_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1978,7 +2015,7 @@ PRED8x8L_VERTICAL_RIGHT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_left_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL_LEFT 0 @@ -2068,7 +2105,7 @@ PRED8x8L_VERTICAL_LEFT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_up_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL_UP 0 @@ -2156,7 +2193,7 @@ PRED8x8L_HORIZONTAL_UP ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_down_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2404,7 +2441,8 @@ INIT_MMX ssse3 PRED8x8L_HORIZONTAL_DOWN ;------------------------------------------------------------------------------- -; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, int stride) +; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- INIT_MMX mmxext @@ -2435,7 +2473,7 @@ cglobal pred4x4_dc_8, 3,5 ;----------------------------------------------------------------------------- ; void ff_pred4x4_tm_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_TM 0 @@ -2514,7 +2552,7 @@ cglobal pred4x4_tm_vp8_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_vertical_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2535,7 +2573,7 @@ cglobal pred4x4_vertical_vp8_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_down_left_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred4x4_down_left_8, 3,3 @@ -2562,7 +2600,7 @@ cglobal pred4x4_down_left_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_vertical_left_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2588,7 +2626,7 @@ cglobal pred4x4_vertical_left_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_horizontal_up_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2622,7 +2660,8 @@ cglobal pred4x4_horizontal_up_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_horizontal_down_8_mmxext(uint8_t *src, -; const uint8_t *topright, int stride) +; const uint8_t *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2658,7 +2697,8 @@ cglobal pred4x4_horizontal_down_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_vertical_right_8_mmxext(uint8_t *src, -; const uint8_t *topright, int stride) +; const uint8_t *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2689,7 +2729,7 @@ cglobal pred4x4_vertical_right_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_down_right_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm b/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm index 9e40cfe24..629e0a72e 100644 --- a/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm +++ b/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm @@ -51,7 +51,8 @@ SECTION .text %endmacro ;----------------------------------------------------------------------------- -; void ff_pred4x4_down_right(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_down_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_DR 0 cglobal pred4x4_down_right_10, 3, 3 @@ -89,7 +90,8 @@ PRED4x4_DR %endif ;------------------------------------------------------------------------------ -; void ff_pred4x4_vertical_right(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_vertical_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------ %macro PRED4x4_VR 0 cglobal pred4x4_vertical_right_10, 3, 3, 6 @@ -128,7 +130,8 @@ PRED4x4_VR %endif ;------------------------------------------------------------------------------- -; void ff_pred4x4_horizontal_down(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_horizontal_down_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- %macro PRED4x4_HD 0 cglobal pred4x4_horizontal_down_10, 3, 3 @@ -170,7 +173,7 @@ PRED4x4_HD %endif ;----------------------------------------------------------------------------- -; void ff_pred4x4_dc(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_dc_10(pixel *src, const pixel *topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -195,7 +198,8 @@ cglobal pred4x4_dc_10, 3, 3 RET ;----------------------------------------------------------------------------- -; void ff_pred4x4_down_left(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_down_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_DL 0 cglobal pred4x4_down_left_10, 3, 3 @@ -225,7 +229,8 @@ PRED4x4_DL %endif ;----------------------------------------------------------------------------- -; void ff_pred4x4_vertical_left(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_vertical_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_VL 0 cglobal pred4x4_vertical_left_10, 3, 3 @@ -254,7 +259,8 @@ PRED4x4_VL %endif ;----------------------------------------------------------------------------- -; void ff_pred4x4_horizontal_up(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_horizontal_up_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred4x4_horizontal_up_10, 3, 3 @@ -288,7 +294,7 @@ cglobal pred4x4_horizontal_up_10, 3, 3 ;----------------------------------------------------------------------------- -; void ff_pred8x8_vertical(pixel *src, int stride) +; void ff_pred8x8_vertical_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_vertical_10, 2, 2 @@ -304,7 +310,7 @@ cglobal pred8x8_vertical_10, 2, 2 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_horizontal(pixel *src, int stride) +; void ff_pred8x8_horizontal_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_horizontal_10, 2, 3 @@ -324,7 +330,7 @@ cglobal pred8x8_horizontal_10, 2, 3 REP_RET ;----------------------------------------------------------------------------- -; void ff_predict_8x8_dc(pixel *src, int stride) +; void ff_predict_8x8_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro MOV8 2-3 ; sort of a hack, but it works @@ -411,7 +417,7 @@ INIT_XMM sse2 PRED8x8_DC pshuflw ;----------------------------------------------------------------------------- -; void ff_pred8x8_top_dc(pixel *src, int stride) +; void ff_pred8x8_top_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_top_dc_10, 2, 4 @@ -438,7 +444,7 @@ cglobal pred8x8_top_dc_10, 2, 4 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_plane(pixel *src, int stride) +; void ff_pred8x8_plane_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_plane_10, 2, 7, 7 @@ -501,8 +507,8 @@ cglobal pred8x8_plane_10, 2, 7, 7 ;----------------------------------------------------------------------------- -; void ff_pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_128_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_128_DC 0 cglobal pred8x8l_128_dc_10, 4, 4 @@ -526,8 +532,8 @@ INIT_XMM sse2 PRED8x8L_128_DC ;----------------------------------------------------------------------------- -; void ff_pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_top_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_TOP_DC 0 cglobal pred8x8l_top_dc_10, 4, 4, 6 @@ -566,7 +572,8 @@ PRED8x8L_TOP_DC %endif ;------------------------------------------------------------------------------- -; void ff_pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride) +; void ff_pred8x8l_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- ;TODO: see if scalar is faster %macro PRED8x8L_DC 0 @@ -625,8 +632,8 @@ PRED8x8L_DC %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_vertical(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_vertical_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL 0 cglobal pred8x8l_vertical_10, 4, 4, 6 @@ -661,8 +668,8 @@ PRED8x8L_VERTICAL %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_horizontal_10(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL 0 cglobal pred8x8l_horizontal_10, 4, 4, 5 @@ -718,8 +725,8 @@ PRED8x8L_HORIZONTAL %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_down_left(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_down_left_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DOWN_LEFT 0 cglobal pred8x8l_down_left_10, 4, 4, 7 @@ -787,8 +794,8 @@ PRED8x8L_DOWN_LEFT %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_down_right(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_down_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DOWN_RIGHT 0 ; standard forbids this when has_topleft is false @@ -862,8 +869,8 @@ PRED8x8L_DOWN_RIGHT %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_vertical_right(pixel *src, int has_topleft, -; int has_topright, int stride) +; void ff_pred8x8l_vertical_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL_RIGHT 0 ; likewise with 8x8l_down_right @@ -933,8 +940,8 @@ PRED8x8L_VERTICAL_RIGHT %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_horizontal_up(pixel *src, int has_topleft, -; int has_topright, int stride) +; void ff_pred8x8l_horizontal_up_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL_UP 0 cglobal pred8x8l_horizontal_up_10, 4, 4, 6 @@ -996,7 +1003,7 @@ PRED8x8L_HORIZONTAL_UP ;----------------------------------------------------------------------------- -; void ff_pred16x16_vertical(pixel *src, int stride) +; void ff_pred16x16_vertical_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro MOV16 3-5 mova [%1+ 0], %2 @@ -1032,7 +1039,7 @@ INIT_XMM sse2 PRED16x16_VERTICAL ;----------------------------------------------------------------------------- -; void ff_pred16x16_horizontal(pixel *src, int stride) +; void ff_pred16x16_horizontal_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_HORIZONTAL 0 cglobal pred16x16_horizontal_10, 2, 3 @@ -1056,7 +1063,7 @@ INIT_XMM sse2 PRED16x16_HORIZONTAL ;----------------------------------------------------------------------------- -; void ff_pred16x16_dc(pixel *src, int stride) +; void ff_pred16x16_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_DC 0 cglobal pred16x16_dc_10, 2, 6 @@ -1102,7 +1109,7 @@ INIT_XMM sse2 PRED16x16_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_top_dc(pixel *src, int stride) +; void ff_pred16x16_top_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_TOP_DC 0 cglobal pred16x16_top_dc_10, 2, 3 @@ -1134,7 +1141,7 @@ INIT_XMM sse2 PRED16x16_TOP_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_left_dc(pixel *src, int stride) +; void ff_pred16x16_left_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_LEFT_DC 0 cglobal pred16x16_left_dc_10, 2, 6 @@ -1171,7 +1178,7 @@ INIT_XMM sse2 PRED16x16_LEFT_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_128_dc(pixel *src, int stride) +; void ff_pred16x16_128_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_128_DC 0 cglobal pred16x16_128_dc_10, 2,3 diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred_init.c b/media/ffvpx/libavcodec/x86/h264_intrapred_init.c index 528b92e49..bdd5125d6 100644 --- a/media/ffvpx/libavcodec/x86/h264_intrapred_init.c +++ b/media/ffvpx/libavcodec/x86/h264_intrapred_init.c @@ -127,6 +127,7 @@ PRED16x16(plane_svq3, 8, ssse3) PRED16x16(tm_vp8, 8, mmx) PRED16x16(tm_vp8, 8, mmxext) PRED16x16(tm_vp8, 8, sse2) +PRED16x16(tm_vp8, 8, avx2) PRED8x8(top_dc, 8, mmxext) PRED8x8(dc_rv40, 8, mmxext) @@ -323,6 +324,12 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } } + + if(EXTERNAL_AVX2(cpu_flags)){ + if (codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_avx2; + } + } } else if (bit_depth == 10) { if (EXTERNAL_MMXEXT(cpu_flags)) { h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; diff --git a/media/ffvpx/libavcodec/x86/videodsp.asm b/media/ffvpx/libavcodec/x86/videodsp.asm index a807d3b88..e23786070 100644 --- a/media/ffvpx/libavcodec/x86/videodsp.asm +++ b/media/ffvpx/libavcodec/x86/videodsp.asm @@ -114,7 +114,7 @@ cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w .x_loop: ; do { movu [dstq+wq*2], m0 ; write($reg, $mmsize) add wq, mmsize/2 ; w -= $mmsize/2 - cmp wq, -mmsize/2 ; } while (w > $mmsize/2) + cmp wq, -(mmsize/2) ; } while (w > $mmsize/2) jl .x_loop movu [dstq-mmsize], m0 ; write($reg, $mmsize) add dstq, dst_strideq ; dst += dst_stride diff --git a/media/ffvpx/libavcodec/x86/videodsp_init.c b/media/ffvpx/libavcodec/x86/videodsp_init.c index 26e072bb1..eeebb4154 100644 --- a/media/ffvpx/libavcodec/x86/videodsp_init.c +++ b/media/ffvpx/libavcodec/x86/videodsp_init.c @@ -29,7 +29,7 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/videodsp.h" -#if HAVE_YASM +#if HAVE_X86ASM typedef void emu_edge_vfix_func(uint8_t *dst, x86_reg dst_stride, const uint8_t *src, x86_reg src_stride, x86_reg start_y, x86_reg end_y, x86_reg bh); @@ -271,14 +271,14 @@ static av_noinline void emulated_edge_mc_avx2(uint8_t *buf, const uint8_t *src, hfixtbl_avx2, &ff_emu_edge_hvar_avx2); } #endif /* HAVE_AVX2_EXTERNAL */ -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h); void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h); av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); #if ARCH_X86_32 @@ -305,5 +305,5 @@ av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) ctx->emulated_edge_mc = emulated_edge_mc_avx2; } #endif -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp8dsp.asm b/media/ffvpx/libavcodec/x86/vp8dsp.asm index 538b3f4a9..e303b8029 100644 --- a/media/ffvpx/libavcodec/x86/vp8dsp.asm +++ b/media/ffvpx/libavcodec/x86/vp8dsp.asm @@ -156,8 +156,8 @@ SECTION .text ;------------------------------------------------------------------------------- ; subpel MC functions: ; -; void ff_put_vp8_epel_hv_(uint8_t *dst, int deststride, -; uint8_t *src, int srcstride, +; void ff_put_vp8_epel_hv_(uint8_t *dst, ptrdiff_t deststride, +; uint8_t *src, ptrdiff_t srcstride, ; int height, int mx, int my); ;------------------------------------------------------------------------------- @@ -884,7 +884,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height REP_RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add_(uint8_t *dst, int16_t block[16], int stride); +; void ff_vp8_idct_dc_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- %macro ADD_DC 4 @@ -906,6 +906,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height %4 [dst2q+strideq+%3], m5 %endmacro +%if ARCH_X86_32 INIT_MMX mmx cglobal vp8_idct_dc_add, 3, 3, 0, dst, block, stride ; load data @@ -929,8 +930,9 @@ cglobal vp8_idct_dc_add, 3, 3, 0, dst, block, stride lea dst2q, [dst1q+strideq*2] ADD_DC m0, m1, 0, movh RET +%endif -INIT_XMM sse4 +%macro VP8_IDCT_DC_ADD 0 cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride ; load data movd m0, [blockq] @@ -956,13 +958,28 @@ cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride paddw m4, m0 packuswb m2, m4 movd [dst1q], m2 +%if cpuflag(sse4) pextrd [dst1q+strideq], m2, 1 pextrd [dst2q], m2, 2 pextrd [dst2q+strideq], m2, 3 +%else + psrldq m2, 4 + movd [dst1q+strideq], m2 + psrldq m2, 4 + movd [dst2q], m2 + psrldq m2, 4 + movd [dst2q+strideq], m2 +%endif RET +%endmacro + +INIT_XMM sse2 +VP8_IDCT_DC_ADD +INIT_XMM sse4 +VP8_IDCT_DC_ADD ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add4y_(uint8_t *dst, int16_t block[4][16], int stride); +; void ff_vp8_idct_dc_add4y_(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); ;----------------------------------------------------------------------------- %if ARCH_X86_32 @@ -1035,7 +1052,7 @@ cglobal vp8_idct_dc_add4y, 3, 3, 6, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add4uv_(uint8_t *dst, int16_t block[4][16], int stride); +; void ff_vp8_idct_dc_add4uv_(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -1077,7 +1094,7 @@ cglobal vp8_idct_dc_add4uv, 3, 3, 0, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_add_(uint8_t *dst, int16_t block[16], int stride); +; void ff_vp8_idct_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- ; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2) diff --git a/media/ffvpx/libavcodec/x86/vp8dsp_init.c b/media/ffvpx/libavcodec/x86/vp8dsp_init.c index 897d5a0e7..397b2518c 100644 --- a/media/ffvpx/libavcodec/x86/vp8dsp_init.c +++ b/media/ffvpx/libavcodec/x86/vp8dsp_init.c @@ -26,7 +26,7 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/vp8dsp.h" -#if HAVE_YASM +#if HAVE_X86ASM /* * MC functions @@ -233,6 +233,8 @@ HVBILIN(ssse3, 8, 16, 16) void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse2(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16], ptrdiff_t stride); void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16], @@ -288,7 +290,7 @@ DECLARE_LOOP_FILTER(sse2) DECLARE_LOOP_FILTER(ssse3) DECLARE_LOOP_FILTER(sse4) -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ #define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \ c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \ @@ -316,7 +318,7 @@ DECLARE_LOOP_FILTER(sse4) av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(cpu_flags)) { @@ -346,7 +348,7 @@ av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse; } - if (HAVE_SSE2_EXTERNAL && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) { + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { VP8_LUMA_MC_FUNC(0, 16, sse2); VP8_MC_FUNC(1, 8, sse2); VP8_BILINEAR_MC_FUNC(0, 16, sse2); @@ -361,18 +363,18 @@ av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) VP8_BILINEAR_MC_FUNC(1, 8, ssse3); VP8_BILINEAR_MC_FUNC(2, 4, ssse3); } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(cpu_flags)) { - c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx; #if ARCH_X86_32 + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx; c->vp8_idct_add = ff_vp8_idct_add_mmx; c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmx; @@ -416,7 +418,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_sse; } - if (HAVE_SSE2_EXTERNAL && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) { + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2; c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2; @@ -427,6 +429,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) } if (EXTERNAL_SSE2(cpu_flags)) { + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse2; c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_sse2; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; @@ -460,5 +463,5 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse4; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse4; } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm b/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm index 98bb6696a..caeb40526 100644 --- a/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm +++ b/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm @@ -43,7 +43,7 @@ cextern pb_80 SECTION .text ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_simple_(uint8_t *dst, int stride, int flim); +; void ff_vp8_h/v_loop_filter_simple_(uint8_t *dst, ptrdiff_t stride, int flim); ;----------------------------------------------------------------------------- ; macro called with 7 mm register indexes as argument, and 4 regular registers @@ -429,7 +429,7 @@ INIT_XMM sse4 SIMPLE_LOOPFILTER h, 5 ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_inner_(uint8_t *dst, [uint8_t *v,] int stride, +; void ff_vp8_h/v_loop_filter_inner_(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, ; int flimE, int flimI, int hev_thr); ;----------------------------------------------------------------------------- @@ -921,7 +921,7 @@ INNER_LOOPFILTER v, 8 INNER_LOOPFILTER h, 8 ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_mbedge_(uint8_t *dst, [uint8_t *v,] int stride, +; void ff_vp8_h/v_loop_filter_mbedge_(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, ; int flimE, int flimI, int hev_thr); ;----------------------------------------------------------------------------- diff --git a/media/ffvpx/libavcodec/x86/vp9dsp_init.c b/media/ffvpx/libavcodec/x86/vp9dsp_init.c index cc781a009..837cce850 100644 --- a/media/ffvpx/libavcodec/x86/vp9dsp_init.c +++ b/media/ffvpx/libavcodec/x86/vp9dsp_init.c @@ -27,7 +27,7 @@ #include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" -#if HAVE_YASM +#if HAVE_X86ASM decl_fpel_func(put, 4, , mmx); decl_fpel_func(put, 8, , mmx); @@ -114,7 +114,7 @@ itxfm_func(idct, idct, 32, sse2); itxfm_func(idct, idct, 32, ssse3); itxfm_func(idct, idct, 32, avx); itxfm_func(iwht, iwht, 4, mmx); -itxfm_func(idct, idct, 16, avx2); +itxfm_funcs(16, avx2); itxfm_func(idct, idct, 32, avx2); #undef itxfm_func @@ -212,11 +212,11 @@ ipred_func(32, tm, avx2); #undef ipred_dir_tm_funcs #undef ipred_dc_funcs -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags; if (bpp == 10) { @@ -391,6 +391,12 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) if (ARCH_X86_64) { #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx2; init_subpel3_32_64(0, put, 8, avx2); init_subpel3_32_64(1, avg, 8, avx2); @@ -406,5 +412,5 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) #undef init_subpel2 #undef init_subpel3 -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c index eb67499c9..60d10a12a 100644 --- a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c +++ b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c @@ -27,7 +27,7 @@ #include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" -#if HAVE_YASM +#if HAVE_X86ASM decl_fpel_func(put, 8, , mmx); decl_fpel_func(avg, 8, _16, mmxext); @@ -51,6 +51,10 @@ decl_ipred_fns(h, 16, mmxext, sse2); decl_ipred_fns(dc, 16, mmxext, sse2); decl_ipred_fns(dc_top, 16, mmxext, sse2); decl_ipred_fns(dc_left, 16, mmxext, sse2); +decl_ipred_fn(dl, 16, 16, avx2); +decl_ipred_fn(dl, 32, 16, avx2); +decl_ipred_fn(dr, 16, 16, avx2); +decl_ipred_fn(dr, 32, 16, avx2); #define decl_ipred_dir_funcs(type) \ decl_ipred_fns(type, 16, sse2, sse2); \ @@ -63,11 +67,11 @@ decl_ipred_dir_funcs(vl); decl_ipred_dir_funcs(vr); decl_ipred_dir_funcs(hu); decl_ipred_dir_funcs(hd); -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(cpu_flags)) { @@ -133,7 +137,13 @@ av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) init_fpel_func(2, 1, 32, avg, _16, avx2); init_fpel_func(1, 1, 64, avg, _16, avx2); init_fpel_func(0, 1, 128, avg, _16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 16, 16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 32, 16, avx2); + init_ipred_func(dr, DIAG_DOWN_RIGHT, 16, 16, avx2); +#if ARCH_X86_64 + init_ipred_func(dr, DIAG_DOWN_RIGHT, 32, 16, avx2); +#endif } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c index 4840b2844..b56afc7f5 100644 --- a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c +++ b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c @@ -27,7 +27,7 @@ #include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" -#if HAVE_YASM +#if HAVE_X86ASM extern const int16_t ff_filters_16bpp[3][15][4][16]; @@ -137,11 +137,11 @@ decl_itxfm_func(iadst, iadst, 4, BPC, sse2); decl_itxfm_funcs(8, BPC, sse2); decl_itxfm_funcs(16, BPC, sse2); decl_itxfm_func(idct, idct, 32, BPC, sse2); -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ av_cold void INIT_FUNC(VP9DSPContext *dsp, int bitexact) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); #define init_lpf_8_func(idx1, idx2, dir, wd, bpp, opt) \ @@ -234,7 +234,7 @@ av_cold void INIT_FUNC(VP9DSPContext *dsp, int bitexact) #endif } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ ff_vp9dsp_init_16bpp_x86(dsp); } diff --git a/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm b/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm index c0ac16d3e..32b698243 100644 --- a/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm +++ b/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm @@ -847,6 +847,108 @@ DL_FUNCS INIT_XMM avx DL_FUNCS +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dl_16x16_16, 2, 4, 5, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefghijklmnop + vpbroadcastw xm1, [aq+30] ; pppppppp + vperm2i128 m2, m0, m1, q0201 ; ijklmnoppppppppp + vpalignr m3, m2, m0, 2 ; bcdefghijklmnopp + vpalignr m4, m2, m0, 4 ; cdefghijklmnoppp + LOWPASS 0, 3, 4 ; BCDEFGHIJKLMNOPp + vperm2i128 m2, m0, m1, q0201 ; JKLMNOPppppppppp + DEFINE_ARGS dst, stride, stride3, cnt + mov cntd, 2 + lea stride3q, [strideq*3] + +.loop: + mova [dstq+strideq*0], m0 + vpalignr m3, m2, m0, 2 + vpalignr m4, m2, m0, 4 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 6 + vpalignr m4, m2, m0, 8 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m4 + vpalignr m3, m2, m0, 10 + vpalignr m4, m2, m0, 12 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 14 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova m0, m2 + vperm2i128 m2, m2, m2, q0101 ; pppppppppppppppp + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dl_32x32_16, 2, 6, 7, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq+mmsize*0+ 0] ; abcdefghijklmnop + mova m1, [aq+mmsize*1+ 0] ; qrstuvwxyz012345 + vpbroadcastw xm4, [aq+mmsize*1+30] ; 55555555 + vperm2i128 m5, m0, m1, q0201 ; ijklmnopqrstuvwx + vpalignr m2, m5, m0, 2 ; bcdefghijklmnopq + vpalignr m3, m5, m0, 4 ; cdefghijklmnopqr + LOWPASS 0, 2, 3 ; BCDEFGHIJKLMNOPQ + vperm2i128 m5, m1, m4, q0201 ; yz01234555555555 + vpalignr m2, m5, m1, 2 ; rstuvwxyz0123455 + vpalignr m3, m5, m1, 4 ; stuvwxyz01234555 + LOWPASS 1, 2, 3 ; RSTUVWXYZ......5 + vperm2i128 m2, m1, m4, q0201 ; Z......555555555 + vperm2i128 m5, m0, m1, q0201 ; JKLMNOPQRSTUVWXY + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 + +.loop: + mova [dstq+strideq*0 + 0], m0 + mova [dstq+strideq*0 +32], m1 + vpalignr m3, m5, m0, 2 + vpalignr m4, m2, m1, 2 + mova [dstq+strideq*1 + 0], m3 + mova [dstq+strideq*1 +32], m4 + vpalignr m3, m5, m0, 4 + vpalignr m4, m2, m1, 4 + mova [dstq+strideq*2 + 0], m3 + mova [dstq+strideq*2 +32], m4 + vpalignr m3, m5, m0, 6 + vpalignr m4, m2, m1, 6 + mova [dstq+stride3q*1+ 0], m3 + mova [dstq+stride3q*1+32], m4 + lea dstq, [dstq+strideq*4] + vpalignr m3, m5, m0, 8 + vpalignr m4, m2, m1, 8 + mova [dstq+strideq*0 + 0], m3 + mova [dstq+strideq*0 +32], m4 + vpalignr m3, m5, m0, 10 + vpalignr m4, m2, m1, 10 + mova [dstq+strideq*1 + 0], m3 + mova [dstq+strideq*1 +32], m4 + vpalignr m3, m5, m0, 12 + vpalignr m4, m2, m1, 12 + mova [dstq+strideq*2+ 0], m3 + mova [dstq+strideq*2+32], m4 + vpalignr m3, m5, m0, 14 + vpalignr m4, m2, m1, 14 + mova [dstq+stride3q+ 0], m3 + mova [dstq+stride3q+ 32], m4 + vpalignr m3, m5, m0, 16 + vpalignr m4, m2, m1, 16 + vperm2i128 m5, m3, m4, q0201 + vperm2i128 m2, m4, m4, q0101 + mova m0, m3 + mova m1, m4 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endif + %macro DR_FUNCS 1 ; stack_mem_for_32x32_32bit_function cglobal vp9_ipred_dr_4x4_16, 4, 4, 3, dst, stride, l, a movh m0, [lq] ; wxyz.... @@ -1068,6 +1170,161 @@ DR_FUNCS 2 INIT_XMM avx DR_FUNCS 2 +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dr_16x16_16, 4, 5, 6, dst, stride, l, a + mova m0, [lq] ; klmnopqrstuvwxyz + movu m1, [aq-2] ; *abcdefghijklmno + mova m2, [aq] ; abcdefghijklmnop + vperm2i128 m4, m2, m2, q2001 ; ijklmnop........ + vpalignr m5, m4, m2, 2 ; bcdefghijklmnop. + vperm2i128 m3, m0, m1, q0201 ; stuvwxyz*abcdefg + LOWPASS 1, 2, 5 ; ABCDEFGHIJKLMNO. + vpalignr m4, m3, m0, 2 ; lmnopqrstuvwxyz* + vpalignr m5, m3, m0, 4 ; mnopqrstuvwxyz*a + LOWPASS 0, 4, 5 ; LMNOPQRSTUVWXYZ# + vperm2i128 m5, m0, m1, q0201 ; TUVWXYZ#ABCDEFGH + DEFINE_ARGS dst, stride, stride3, stride5, dst3 + lea dst3q, [dstq+strideq*4] + lea stride3q, [strideq*3] + lea stride5q, [stride3q+strideq*2] + + vpalignr m3, m5, m0, 2 + vpalignr m4, m1, m5, 2 + mova [dst3q+stride5q*2], m3 ; 14 + mova [ dstq+stride3q*2], m4 ; 6 + vpalignr m3, m5, m0, 4 + vpalignr m4, m1, m5, 4 + sub dst3q, strideq + mova [dst3q+stride5q*2], m3 ; 13 + mova [dst3q+strideq*2 ], m4 ; 5 + mova [dst3q+stride3q*4], m0 ; 15 + vpalignr m3, m5, m0, 6 + vpalignr m4, m1, m5, 6 + mova [dstq+stride3q*4], m3 ; 12 + mova [dst3q+strideq*1], m4 ; 4 + vpalignr m3, m5, m0, 8 + vpalignr m4, m1, m5, 8 + mova [dst3q+strideq*8], m3 ; 11 + mova [dst3q+strideq*0], m4 ; 3 + vpalignr m3, m5, m0, 10 + vpalignr m4, m1, m5, 10 + mova [dstq+stride5q*2], m3 ; 10 + mova [dstq+strideq*2 ], m4 ; 2 + vpalignr m3, m5, m0, 12 + vpalignr m4, m1, m5, 12 + mova [dst3q+stride3q*2], m3 ; 9 + mova [dstq+strideq*1 ], m4 ; 1 + vpalignr m3, m5, m0, 14 + vpalignr m4, m1, m5, 14 + mova [dstq+strideq*8], m3 ; 8 + mova [dstq+strideq*0], m4 ; 0 + mova [dst3q+strideq*4], m5 ; 7 + RET + +%if ARCH_X86_64 +cglobal vp9_ipred_dr_32x32_16, 4, 7, 10, dst, stride, l, a + mova m0, [lq+mmsize*0+0] ; l[0-15] + mova m1, [lq+mmsize*1+0] ; l[16-31] + movu m2, [aq+mmsize*0-2] ; *abcdefghijklmno + mova m3, [aq+mmsize*0+0] ; abcdefghijklmnop + mova m4, [aq+mmsize*1+0] ; qrstuvwxyz012345 + vperm2i128 m5, m0, m1, q0201 ; lmnopqrstuvwxyz0 + vpalignr m6, m5, m0, 2 ; mnopqrstuvwxyz01 + vpalignr m7, m5, m0, 4 ; nopqrstuvwxyz012 + LOWPASS 0, 6, 7 ; L[0-15] + vperm2i128 m7, m1, m2, q0201 ; stuvwxyz*abcdefg + vpalignr m5, m7, m1, 2 ; lmnopqrstuvwxyz* + vpalignr m6, m7, m1, 4 ; mnopqrstuvwxyz*a + LOWPASS 1, 5, 6 ; L[16-31]# + vperm2i128 m5, m3, m4, q0201 ; ijklmnopqrstuvwx + vpalignr m6, m5, m3, 2 ; bcdefghijklmnopq + LOWPASS 2, 3, 6 ; A[0-15] + movu m3, [aq+mmsize*1-2] ; pqrstuvwxyz01234 + vperm2i128 m6, m4, m4, q2001 ; yz012345........ + vpalignr m7, m6, m4, 2 ; rstuvwxyz012345. + LOWPASS 3, 4, 7 ; A[16-31]. + vperm2i128 m4, m1, m2, q0201 ; TUVWXYZ#ABCDEFGH + vperm2i128 m5, m0, m1, q0201 ; L[7-15]L[16-23] + vperm2i128 m8, m2, m3, q0201 ; IJKLMNOPQRSTUVWX + DEFINE_ARGS dst8, stride, stride3, stride7, stride5, dst24, cnt + lea stride3q, [strideq*3] + lea stride5q, [stride3q+strideq*2] + lea stride7q, [strideq*4+stride3q] + lea dst24q, [dst8q+stride3q*8] + lea dst8q, [dst8q+strideq*8] + mov cntd, 2 + +.loop: + mova [dst24q+stride7q+0 ], m0 ; 31 23 15 7 + mova [dst24q+stride7q+32], m1 + mova [dst8q+stride7q+0], m1 + mova [dst8q+stride7q+32], m2 + vpalignr m6, m4, m1, 2 + vpalignr m7, m5, m0, 2 + vpalignr m9, m8, m2, 2 + mova [dst24q+stride3q*2+0], m7 ; 30 22 14 6 + mova [dst24q+stride3q*2+32], m6 + mova [dst8q+stride3q*2+0], m6 + mova [dst8q+stride3q*2+32], m9 + vpalignr m6, m4, m1, 4 + vpalignr m7, m5, m0, 4 + vpalignr m9, m8, m2, 4 + mova [dst24q+stride5q+0], m7 ; 29 21 13 5 + mova [dst24q+stride5q+32], m6 + mova [dst8q+stride5q+0], m6 + mova [dst8q+stride5q+32], m9 + vpalignr m6, m4, m1, 6 + vpalignr m7, m5, m0, 6 + vpalignr m9, m8, m2, 6 + mova [dst24q+strideq*4+0 ], m7 ; 28 20 12 4 + mova [dst24q+strideq*4+32], m6 + mova [dst8q+strideq*4+0], m6 + mova [dst8q+strideq*4+32], m9 + vpalignr m6, m4, m1, 8 + vpalignr m7, m5, m0, 8 + vpalignr m9, m8, m2, 8 + mova [dst24q+stride3q+0 ], m7 ; 27 19 11 3 + mova [dst24q+stride3q+32], m6 + mova [dst8q+stride3q+0], m6 + mova [dst8q+stride3q+32], m9 + vpalignr m6, m4, m1, 10 + vpalignr m7, m5, m0, 10 + vpalignr m9, m8, m2, 10 + mova [dst24q+strideq*2+0 ], m7 ; 26 18 10 2 + mova [dst24q+strideq*2+32], m6 + mova [dst8q+strideq*2+0], m6 + mova [dst8q+strideq*2+32], m9 + vpalignr m6, m4, m1, 12 + vpalignr m7, m5, m0, 12 + vpalignr m9, m8, m2, 12 + mova [dst24q+strideq+0 ], m7 ; 25 17 9 1 + mova [dst24q+strideq+32], m6 + mova [dst8q+strideq+0], m6 + mova [dst8q+strideq+32], m9 + vpalignr m6, m4, m1, 14 + vpalignr m7, m5, m0, 14 + vpalignr m9, m8, m2, 14 + mova [dst24q+strideq*0+0 ], m7 ; 24 16 8 0 + mova [dst24q+strideq*0+32], m6 + mova [dst8q+strideq*0+0], m6 + mova [dst8q+strideq*0+32], m9 + mova m0, m5 + mova m5, m1 + mova m1, m4 + mova m4, m2 + mova m2, m8 + mova m8, m3 + sub dst24q, stride7q + sub dst24q, strideq + sub dst8q, stride7q + sub dst8q, strideq + dec cntd + jg .loop + RET +%endif +%endif + %macro VL_FUNCS 1 ; stack_mem_for_32x32_32bit_function cglobal vp9_ipred_vl_4x4_16, 2, 4, 3, dst, stride, l, a movifnidn aq, amp diff --git a/media/ffvpx/libavcodec/x86/vp9itxfm.asm b/media/ffvpx/libavcodec/x86/vp9itxfm.asm index 57d6d353b..2c63fe514 100644 --- a/media/ffvpx/libavcodec/x86/vp9itxfm.asm +++ b/media/ffvpx/libavcodec/x86/vp9itxfm.asm @@ -1581,33 +1581,30 @@ cglobal vp9_idct_idct_16x16_add, 4, 4, 16, dst, stride, block, eob VP9_IDCT16_YMM_1D mova [blockq+224], m7 - mova [blockq+480], m15 - pxor m15, m15 ; store - VP9_IDCT8_WRITEx2 0, 1, 6, 7, 15, [pw_512], 6 + VP9_IDCT8_WRITEx2 0, 1, 6, 7, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 2, 3, 6, 7, 15, [pw_512], 6 + VP9_IDCT8_WRITEx2 2, 3, 6, 7, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 4, 5, 6, 7, 15, [pw_512], 6 + VP9_IDCT8_WRITEx2 4, 5, 6, 7, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] mova m6, [blockq+192] mova m7, [blockq+224] - SWAP 0, 15 - mova m15, [blockq+480] - VP9_IDCT8_WRITEx2 6, 7, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 6, 7, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 8, 9, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 8, 9, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 10, 11, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 10, 11, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 12, 13, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 12, 13, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 14, 15, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 14, 15, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] ; at the end of the loop, m0 should still be zero ; use that to zero out block coefficients + pxor m0, m0 ZERO_BLOCK blockq, 32, 16, m0 RET %endif @@ -1987,6 +1984,173 @@ IADST16_FN idct, IDCT16, iadst, IADST16, avx IADST16_FN iadst, IADST16, idct, IDCT16, avx IADST16_FN iadst, IADST16, iadst, IADST16, avx +; in: data in m[0-15] except m0/m4, which are in [blockq+0] and [blockq+128] +; out: m[0-15] except m6, which is in [blockq+192] +; uses blockq as scratch space +%macro VP9_IADST16_YMM_1D 0 + mova [blockq+ 32], m3 + mova [blockq+ 64], m7 + mova [blockq+ 96], m8 + + ; first half of round 1 + VP9_UNPACK_MULSUB_2D_4X 9, 6, 0, 3, 13160, 9760 ; m9/x=t7[d], m6/x=t6[d] + VP9_UNPACK_MULSUB_2D_4X 1, 14, 4, 7, 2404, 16207 ; m1/x=t15[d], m14/x=t14[d] + VP9_RND_SH_SUMSUB_BA 14, 6, 7, 3, 8, [pd_8192] ; m14=t6[w], m6=t14[w] + VP9_RND_SH_SUMSUB_BA 1, 9, 4, 0, 8, [pd_8192] ; m1=t7[w], m9=t15[w] + + VP9_UNPACK_MULSUB_2D_4X 13, 2, 4, 7, 15893, 3981 ; m13/x=t3[d], m2/x=t2[d] + VP9_UNPACK_MULSUB_2D_4X 5, 10, 0, 3, 8423, 14053 ; m5/x=t11[d], m10/x=t10[d] + VP9_RND_SH_SUMSUB_BA 10, 2, 3, 7, 8, [pd_8192] ; m10=t2[w], m2=t10[w] + VP9_RND_SH_SUMSUB_BA 5, 13, 0, 4, 8, [pd_8192] ; m5=t3[w], m13=t11[w] + + ; half of round 2 t8-15 + VP9_UNPACK_MULSUB_2D_4X 2, 13, 4, 7, 9102, 13623 ; m2/x=t11[d], m13/x=t10[d] + VP9_UNPACK_MULSUB_2D_4X 9, 6, 3, 0, 13623, 9102 ; m9/x=t14[d], m6/x=t15[d] + VP9_RND_SH_SUMSUB_BA 9, 13, 3, 7, 8, [pd_8192] ; m9=t10[w], m13=t14[w] + VP9_RND_SH_SUMSUB_BA 6, 2, 0, 4, 8, [pd_8192] ; m6=t11[w], m2=t15[w] + + SUMSUB_BA w, 14, 10, 8 ; m14=t2, m10=t6 + SUMSUB_BA w, 1, 5, 8 ; m1=t3, m5=t7 + + mova m0, [blockq+ 0] + mova m4, [blockq+128] + mova m3, [blockq+ 32] + mova m7, [blockq+ 64] + mova m8, [blockq+ 96] + mova [blockq+ 0], m1 + mova [blockq+128], m14 + mova [blockq+ 32], m6 + mova [blockq+ 64], m9 + mova [blockq+ 96], m10 + + ; second half of round 1 + VP9_UNPACK_MULSUB_2D_4X 15, 0, 1, 9, 16364, 804 ; m15/x=t1[d], m0/x=t0[d] + VP9_UNPACK_MULSUB_2D_4X 7, 8, 10, 6, 11003, 12140 ; m7/x=t9[d], m8/x=t8[d] + VP9_RND_SH_SUMSUB_BA 8, 0, 6, 9, 14, [pd_8192] ; m8=t0[w], m0=t8[w] + VP9_RND_SH_SUMSUB_BA 7, 15, 10, 1, 14, [pd_8192] ; m7=t1[w], m15=t9[w] + + VP9_UNPACK_MULSUB_2D_4X 11, 4, 10, 6, 14811, 7005 ; m11/x=t5[d], m4/x=t4[d] + VP9_UNPACK_MULSUB_2D_4X 3, 12, 1, 9, 5520, 15426 ; m3/x=t13[d], m12/x=t12[d] + VP9_RND_SH_SUMSUB_BA 12, 4, 9, 6, 14, [pd_8192] ; m12=t4[w], m4=t12[w] + VP9_RND_SH_SUMSUB_BA 3, 11, 1, 10, 14, [pd_8192] ; m3=t5[w], m11=t13[w] + + ; second half of round 2 t8-15 + VP9_UNPACK_MULSUB_2D_4X 0, 15, 6, 10, 16069, 3196 ; m15/x=t8[d], m0/x=t9[d] + VP9_UNPACK_MULSUB_2D_4X 11, 4, 9, 1, 3196, 16069 ; m11/x=t12[d], m4/x=t13[d] + VP9_RND_SH_SUMSUB_BA 11, 15, 9, 10, 14, [pd_8192] ; m11=t8[w], m15=t12[w] + VP9_RND_SH_SUMSUB_BA 4, 0, 1, 6, 14, [pd_8192] ; m4=t9[w], m0=t13[w] + + SUMSUB_BA w, 12, 8, 14 ; m12=t0, m8=t4 + SUMSUB_BA w, 3, 7, 14 ; m3=t1, m7=t5 + + mova m10, [blockq+ 96] + mova [blockq+ 96], m12 + + ; round 3 + VP9_UNPACK_MULSUB_2D_4X 15, 0, 9, 12, 15137, 6270 ; m15/x=t13[d], m0/x=t12[d] + VP9_UNPACK_MULSUB_2D_4X 2, 13, 1, 6, 6270, 15137 ; m2/x=t14[d], m13/x=t15[d] + VP9_RND_SH_SUMSUB_BA 2, 0, 1, 12, 14, [pd_8192] ; m2=out2[w], m0=t14a[w] + VP9_RND_SH_SUMSUB_BA 13, 15, 6, 9, 14, [pd_8192] + PSIGNW m13, [pw_m1] ; m13=out13[w], m15=t15a[w] + + VP9_UNPACK_MULSUB_2D_4X 8, 7, 12, 9, 15137, 6270 ; m8/x=t5[d], m7/x=t4[d] + VP9_UNPACK_MULSUB_2D_4X 5, 10, 1, 6, 6270, 15137 ; m5/x=t6[d], m10/x=t7[d] + VP9_RND_SH_SUMSUB_BA 5, 7, 1, 9, 14, [pd_8192] + PSIGNW m5, [pw_m1] ; m5=out3[w], m7=t6[w] + VP9_RND_SH_SUMSUB_BA 10, 8, 6, 12, 14, [pd_8192] ; m10=out12[w], m8=t7[w] + + mova m1, [blockq+ 0] + mova m14, [blockq+128] + mova m6, [blockq+ 32] + mova m9, [blockq+ 64] + mova m12, [blockq+ 96] + mova [blockq+ 0], m10 + mova [blockq+128], m5 + + SUMSUB_BA w, 14, 12, 5 ; m14=out0, m12=t2a + SUMSUB_BA w, 1, 3, 5 + PSIGNW m1, [pw_m1] ; m1=out15, m3=t3a + + SUMSUB_BA w, 9, 11, 5 + PSIGNW m9, [pw_m1] ; m9=out1, m11=t10 + SUMSUB_BA w, 6, 4, 5 ; m6=out14, m4=t11 + + VP9_UNPACK_MULSUB_2W_4X 4, 11, 11585, 11585, [pd_8192], 5, 10 ; m4=out9, m11=out6 + mova m5, [blockq+128] + mova [blockq+192], m11 + PSIGNW m15, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 15, 0, 11585, 11585, [pd_8192], 10, 11 ; m15=out5, m0=out10 + + PSIGNW m3, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 3, 12, 11585, 11585, [pd_8192], 10, 11 ; m3=out7,m12=out8 + VP9_UNPACK_MULSUB_2W_4X 8, 7, 11585, 11585, [pd_8192], 10, 11 ; m8=out11,m7=out4 + + mova m10, [blockq+ 0] + + SWAP 0, 14, 6, 11, 8, 12, 10 + SWAP 1, 9, 15, 4, 7, 3, 5 + SWAP 5, 9, 15 +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +%macro IADST16_YMM_FN 4 +INIT_YMM avx2 +cglobal vp9_%1_%3_16x16_add, 4, 4, 16, dst, stride, block, eob + mova m1, [blockq+ 32] + mova m2, [blockq+ 64] + mova m3, [blockq+ 96] + mova m5, [blockq+160] + mova m6, [blockq+192] + mova m7, [blockq+224] + mova m8, [blockq+256] + mova m9, [blockq+288] + mova m10, [blockq+320] + mova m11, [blockq+352] + mova m12, [blockq+384] + mova m13, [blockq+416] + mova m14, [blockq+448] + mova m15, [blockq+480] + + VP9_%2_YMM_1D + TRANSPOSE16x16W 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ + [blockq+192], [blockq+128], 1 + mova [blockq+ 0], m0 + VP9_%4_YMM_1D + + mova [blockq+224], m7 + + ; store + VP9_IDCT8_WRITEx2 0, 1, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 2, 3, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 4, 5, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + mova m6, [blockq+192] + mova m7, [blockq+224] + VP9_IDCT8_WRITEx2 6, 7, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 8, 9, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 10, 11, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 12, 13, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 14, 15, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + pxor m0, m0 + ZERO_BLOCK blockq, 32, 16, m0 + RET +%endmacro + +IADST16_YMM_FN idct, IDCT16, iadst, IADST16 +IADST16_YMM_FN iadst, IADST16, idct, IDCT16 +IADST16_YMM_FN iadst, IADST16, iadst, IADST16 +%endif + ;--------------------------------------------------------------------------------------------- ; void vp9_idct_idct_32x32_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); ;--------------------------------------------------------------------------------------------- diff --git a/media/ffvpx/libavcodec/x86/vp9mc.asm b/media/ffvpx/libavcodec/x86/vp9mc.asm index 9152ba541..f64161b2c 100644 --- a/media/ffvpx/libavcodec/x86/vp9mc.asm +++ b/media/ffvpx/libavcodec/x86/vp9mc.asm @@ -1,5 +1,5 @@ ;****************************************************************************** -;* VP9 MC SIMD optimizations +;* VP9 motion compensation SIMD optimizations ;* ;* Copyright (c) 2013 Ronald S. Bultje ;* @@ -440,9 +440,8 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 4, 7, 11, dst, dstride, src, sstride, f mova m10, [filteryq+96] %endif .loop: - ; FIXME maybe reuse loads from previous rows, or just - ; more generally unroll this to prevent multiple loads of - ; the same data? + ; FIXME maybe reuse loads from previous rows, or just more generally + ; unroll this to prevent multiple loads of the same data? movh m0, [srcq] movh m1, [srcq+sstrideq] movh m2, [srcq+sstrideq*2] -- cgit v1.2.3 From ccdde52530d10077a0a2489e256ff033d656630c Mon Sep 17 00:00:00 2001 From: trav90 Date: Thu, 26 Apr 2018 16:50:57 -0500 Subject: [ffvpx] Remove some files we don't need --- media/ffvpx/libavcodec/dct.h | 69 -------------------------------------------- 1 file changed, 69 deletions(-) delete mode 100644 media/ffvpx/libavcodec/dct.h (limited to 'media/ffvpx/libavcodec') diff --git a/media/ffvpx/libavcodec/dct.h b/media/ffvpx/libavcodec/dct.h deleted file mode 100644 index 0a03e256d..000000000 --- a/media/ffvpx/libavcodec/dct.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (I)DCT Transforms - * Copyright (c) 2009 Peter Ross - * Copyright (c) 2010 Alex Converse - * Copyright (c) 2010 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined(AVCODEC_DCT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT) -#define AVCODEC_DCT_H - -#include -#include - -#include "rdft.h" - -struct DCTContext { - int nbits; - int inverse; - RDFTContext rdft; - const float *costab; - FFTSample *csc2; - void (*dct_calc)(struct DCTContext *s, FFTSample *data); - void (*dct32)(FFTSample *out, const FFTSample *in); -}; - -/** - * Set up DCT. - * @param nbits size of the input array: - * (1 << nbits) for DCT-II, DCT-III and DST-I - * (1 << nbits) + 1 for DCT-I - * - * @note the first element of the input of DST-I is ignored - */ -int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type); -void ff_dct_end (DCTContext *s); - -void ff_dct_init_x86(DCTContext *s); - -void ff_fdct_ifast(int16_t *data); -void ff_fdct_ifast248(int16_t *data); -void ff_jpeg_fdct_islow_8(int16_t *data); -void ff_jpeg_fdct_islow_10(int16_t *data); -void ff_fdct248_islow_8(int16_t *data); -void ff_fdct248_islow_10(int16_t *data); - -void ff_j_rev_dct(int16_t *data); -void ff_j_rev_dct4(int16_t *data); -void ff_j_rev_dct2(int16_t *data); -void ff_j_rev_dct1(int16_t *data); -void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); - -#endif /* AVCODEC_DCT_H */ -- cgit v1.2.3