From b441a4517be7d399417548738ed8f2671dd0c4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 27 Aug 2012 15:55:43 +0300 Subject: [PATCH 01/15] vf_hqdn3d: Remove a duplicate inline declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compilation seems to fail on GCC 3.4 due to this duplicate declaration. Signed-off-by: Martin Storsjö --- libavfilter/vf_hqdn3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 5bb896cc98..71b670d3f1 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -56,7 +56,7 @@ void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16 : AV_WN16A(dst+(x)*2, RIGHTSHIFT(val, 16-depth))) av_always_inline -static inline uint32_t lowpass(int prev, int cur, int16_t *coef, int depth) +static uint32_t lowpass(int prev, int cur, int16_t *coef, int depth) { int d = (prev - cur) >> (8 - LUT_BITS); return cur + coef[d]; From b42be2d56a5abbc8645eac7d4d30f9e3b486dcc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 27 Aug 2012 14:07:12 +0300 Subject: [PATCH 02/15] avprobe: Get rid of ugly casts in the options table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also makes sure the function pointers are stored via the same union member as they are accessed via. Signed-off-by: Martin Storsjö --- avprobe.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/avprobe.c b/avprobe.c index 00e0ad09e0..cb610d89f9 100644 --- a/avprobe.c +++ b/avprobe.c @@ -877,34 +877,35 @@ void show_help_default(const char *opt, const char *arg) show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM); } -static void opt_pretty(void) +static int opt_pretty(const char *opt, const char *arg) { show_value_unit = 1; use_value_prefix = 1; use_byte_value_binary_prefix = 1; use_value_sexagesimal_format = 1; + return 0; } static const OptionDef real_options[] = { #include "cmdutils_common_opts.h" - { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" }, - { "of", HAS_ARG, {(void*)&opt_output_format}, "output the document either as ini or json", "output_format" }, - { "unit", OPT_BOOL, {(void*)&show_value_unit}, + { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" }, + { "of", HAS_ARG, {.func_arg = opt_output_format}, "output the document either as ini or json", "output_format" }, + { "unit", OPT_BOOL, {&show_value_unit}, "show unit of the displayed values" }, - { "prefix", OPT_BOOL, {(void*)&use_value_prefix}, + { "prefix", OPT_BOOL, {&use_value_prefix}, "use SI prefixes for the displayed values" }, - { "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix}, + { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix}, "use binary prefixes for byte units" }, - { "sexagesimal", OPT_BOOL, {(void*)&use_value_sexagesimal_format}, + { "sexagesimal", OPT_BOOL, {&use_value_sexagesimal_format}, "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" }, - { "pretty", 0, {(void*)&opt_pretty}, + { "pretty", 0, {.func_arg = opt_pretty}, "prettify the format of displayed values, make it more human readable" }, - { "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" }, - { "show_format_entry", HAS_ARG, {(void*)opt_show_format_entry}, + { "show_format", OPT_BOOL, {&do_show_format} , "show format/container info" }, + { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry}, "show a particular entry from the format/container info", "entry" }, - { "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" }, - { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" }, - { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, + { "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" }, + { "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" }, + { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" }, { NULL, }, }; From 49df339f4b5de7910b7028d4f3063019bff03d3d Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sun, 26 Aug 2012 13:46:57 +0200 Subject: [PATCH 03/15] mss1: merge decode_intra() and decode_inter() They have most of their code in common. --- libavcodec/mss1.c | 64 +++++++++++------------------------------------ 1 file changed, 14 insertions(+), 50 deletions(-) diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c index e499cfcae2..4cd828d977 100644 --- a/libavcodec/mss1.c +++ b/libavcodec/mss1.c @@ -80,6 +80,7 @@ typedef struct MSS1Context { int mask_linesize; uint32_t pal[256]; int free_colours; + int keyframe; Model intra_region, inter_region; Model pivot, edge_mode, split_mode; PixContext intra_pix_ctx, inter_pix_ctx; @@ -607,44 +608,6 @@ static int decode_region_intra(MSS1Context *ctx, ArithCoder *acoder, return 0; } -static int decode_intra(MSS1Context *ctx, ArithCoder *acoder, - int x, int y, int width, int height) -{ - int mode, pivot; - - if (ctx->corrupted) - return -1; - - mode = arith_get_model_sym(acoder, &ctx->split_mode); - - switch (mode) { - case SPLIT_VERT: - pivot = decode_pivot(ctx, acoder, height); - if (ctx->corrupted) - return -1; - if (decode_intra(ctx, acoder, x, y, width, pivot)) - return -1; - if (decode_intra(ctx, acoder, x, y + pivot, width, height - pivot)) - return -1; - break; - case SPLIT_HOR: - pivot = decode_pivot(ctx, acoder, width); - if (ctx->corrupted) - return -1; - if (decode_intra(ctx, acoder, x, y, pivot, height)) - return -1; - if (decode_intra(ctx, acoder, x + pivot, y, width - pivot, height)) - return -1; - break; - case SPLIT_NONE: - return decode_region_intra(ctx, acoder, x, y, width, height); - default: - return -1; - } - - return 0; -} - static int decode_region_inter(MSS1Context *ctx, ArithCoder *acoder, int x, int y, int width, int height) { @@ -674,8 +637,8 @@ static int decode_region_inter(MSS1Context *ctx, ArithCoder *acoder, return 0; } -static int decode_inter(MSS1Context *ctx, ArithCoder *acoder, - int x, int y, int width, int height) +static int decode_rect(MSS1Context *ctx, ArithCoder *acoder, + int x, int y, int width, int height) { int mode, pivot; @@ -687,20 +650,23 @@ static int decode_inter(MSS1Context *ctx, ArithCoder *acoder, switch (mode) { case SPLIT_VERT: pivot = decode_pivot(ctx, acoder, height); - if (decode_inter(ctx, acoder, x, y, width, pivot)) + if (decode_rect(ctx, acoder, x, y, width, pivot)) return -1; - if (decode_inter(ctx, acoder, x, y + pivot, width, height - pivot)) + if (decode_rect(ctx, acoder, x, y + pivot, width, height - pivot)) return -1; break; case SPLIT_HOR: pivot = decode_pivot(ctx, acoder, width); - if (decode_inter(ctx, acoder, x, y, pivot, height)) + if (decode_rect(ctx, acoder, x, y, pivot, height)) return -1; - if (decode_inter(ctx, acoder, x + pivot, y, width - pivot, height)) + if (decode_rect(ctx, acoder, x + pivot, y, width - pivot, height)) return -1; break; case SPLIT_NONE: - return decode_region_inter(ctx, acoder, x, y, width, height); + if (ctx->keyframe) + return decode_region_intra(ctx, acoder, x, y, width, height); + else + return decode_region_inter(ctx, acoder, x, y, width, height); default: return -1; } @@ -732,21 +698,19 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, c->pic_start = c->pic.data[0] + c->pic.linesize[0] * (avctx->height - 1); c->pic_stride = -c->pic.linesize[0]; - if (!arith_get_bit(&acoder)) { + c->keyframe = !arith_get_bit(&acoder); + if (c->keyframe) { codec_reset(c); pal_changed = decode_pal(c, &acoder); - c->corrupted = decode_intra(c, &acoder, 0, 0, - avctx->width, avctx->height); c->pic.key_frame = 1; c->pic.pict_type = AV_PICTURE_TYPE_I; } else { if (c->corrupted) return AVERROR_INVALIDDATA; - c->corrupted = decode_inter(c, &acoder, 0, 0, - avctx->width, avctx->height); c->pic.key_frame = 0; c->pic.pict_type = AV_PICTURE_TYPE_P; } + c->corrupted = decode_rect(c, &acoder, 0, 0, avctx->width, avctx->height); if (c->corrupted) return AVERROR_INVALIDDATA; memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); From 0de4a563e4f301c1abc2032d5c13c3cbb39e430c Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sun, 26 Aug 2012 14:16:07 +0200 Subject: [PATCH 04/15] mss1: move code that will be reused by MSS2 decoder into separate file --- libavcodec/Makefile | 2 +- libavcodec/mss1.c | 621 ++------------------------------------------ libavcodec/mss12.c | 581 +++++++++++++++++++++++++++++++++++++++++ libavcodec/mss12.h | 83 ++++++ 4 files changed, 691 insertions(+), 596 deletions(-) create mode 100644 libavcodec/mss12.c create mode 100644 libavcodec/mss12.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 394966e2fd..87f716ce36 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -270,7 +270,7 @@ OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ mpeg4videodec.o OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o OBJS-$(CONFIG_MSA1_DECODER) += mss3.o mss34dsp.o -OBJS-$(CONFIG_MSS1_DECODER) += mss1.o +OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o OBJS-$(CONFIG_MTS2_DECODER) += mss4.o mss34dsp.o diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c index 4cd828d977..fe8ee10840 100644 --- a/libavcodec/mss1.c +++ b/libavcodec/mss1.c @@ -27,74 +27,13 @@ #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" -#include "get_bits.h" - -enum SplitMode { - SPLIT_VERT = 0, - SPLIT_HOR, - SPLIT_NONE -}; - -typedef struct ArithCoder { - int low, high, value; - GetBitContext *gb; -} ArithCoder; - -#define MODEL_MIN_SYMS 2 -#define MODEL_MAX_SYMS 256 -#define THRESH_ADAPTIVE -1 -#define THRESH_LOW 15 -#define THRESH_HIGH 50 - -typedef struct Model { - int cum_prob[MODEL_MAX_SYMS + 1]; - int weights[MODEL_MAX_SYMS + 1]; - int idx2sym[MODEL_MAX_SYMS + 1]; - int sym2idx[MODEL_MAX_SYMS + 1]; - int num_syms; - int thr_weight, threshold; -} Model; - -static const int sec_order_sizes[4] = { 1, 7, 6, 1 }; - -enum ContextDirection { - TOP_LEFT = 0, - TOP, - TOP_RIGHT, - LEFT -}; - -typedef struct PixContext { - int cache_size, num_syms; - uint8_t cache[12]; - Model cache_model, full_model; - Model sec_models[4][8][4]; -} PixContext; +#include "mss12.h" typedef struct MSS1Context { - AVCodecContext *avctx; + MSS12Context ctx; AVFrame pic; - uint8_t *pic_start; - int pic_stride; - uint8_t *mask; - int mask_linesize; - uint32_t pal[256]; - int free_colours; - int keyframe; - Model intra_region, inter_region; - Model pivot, edge_mode, split_mode; - PixContext intra_pix_ctx, inter_pix_ctx; - int corrupted; } MSS1Context; -static void arith_init(ArithCoder *c, GetBitContext *gb) -{ - c->low = 0; - c->high = 0xFFFF; - c->value = get_bits(gb, 16); - c->gb = gb; -} - static void arith_normalise(ArithCoder *c) { for (;;) { @@ -179,88 +118,6 @@ static int arith_get_prob(ArithCoder *c, int *probs) return sym; } -static int model_calc_threshold(Model *m) -{ - int thr; - - if (m->thr_weight == -1) { - thr = 2 * m->weights[m->num_syms] - 1; - thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr; - } else { - thr = m->num_syms * m->thr_weight; - } - - return FFMIN(thr, 0x3FFF); -} - -static void model_reset(Model *m) -{ - int i; - - for (i = 0; i <= m->num_syms; i++) { - m->weights[i] = 1; - m->cum_prob[i] = m->num_syms - i; - } - m->weights[0] = -1; - m->idx2sym[0] = -1; - m->sym2idx[m->num_syms] = -1; - for (i = 0; i < m->num_syms; i++) { - m->sym2idx[i] = i + 1; - m->idx2sym[i + 1] = i; - } -} - -static av_cold void model_init(Model *m, int num_syms, int thr_weight) -{ - m->num_syms = num_syms; - m->thr_weight = thr_weight; - m->threshold = model_calc_threshold(m); - model_reset(m); -} - -static void model_rescale_weights(Model *m) -{ - int i; - int cum_prob; - - if (m->thr_weight == -1) - m->threshold = model_calc_threshold(m); - while (m->cum_prob[0] > m->threshold) { - cum_prob = 0; - for (i = m->num_syms; i >= 0; i--) { - m->cum_prob[i] = cum_prob; - m->weights[i] = (m->weights[i] + 1) >> 1; - cum_prob += m->weights[i]; - } - } -} - -static void model_update(Model *m, int val) -{ - int i; - - if (m->weights[val] == m->weights[val - 1]) { - for (i = val; m->weights[i - 1] == m->weights[val]; i--); - if (i != val) { - int sym1, sym2; - - sym1 = m->idx2sym[val]; - sym2 = m->idx2sym[i]; - - m->idx2sym[val] = sym2; - m->idx2sym[i] = sym1; - m->sym2idx[sym1] = i; - m->sym2idx[sym2] = val; - - val = i; - } - } - m->weights[val]++; - for (i = val - 1; i >= 0; i--) - m->cum_prob[i]++; - model_rescale_weights(m); -} - static int arith_get_model_sym(ArithCoder *c, Model *m) { int idx, val; @@ -268,289 +125,33 @@ static int arith_get_model_sym(ArithCoder *c, Model *m) idx = arith_get_prob(c, m->cum_prob); val = m->idx2sym[idx]; - model_update(m, idx); + ff_mss12_model_update(m, idx); arith_normalise(c); return val; } -static void pixctx_reset(PixContext *ctx) +static void arith_init(ArithCoder *c, GetBitContext *gb) { - int i, j, k; + c->low = 0; + c->high = 0xFFFF; + c->value = get_bits(gb, 16); + c->gb = gb; - for (i = 0; i < ctx->cache_size; i++) - ctx->cache[i] = i; - - model_reset(&ctx->cache_model); - model_reset(&ctx->full_model); - - for (i = 0; i < 4; i++) - for (j = 0; j < sec_order_sizes[i]; j++) - for (k = 0; k < 4; k++) - model_reset(&ctx->sec_models[i][j][k]); -} - -static av_cold void pixctx_init(PixContext *ctx, int cache_size) -{ - int i, j, k; - - ctx->cache_size = cache_size + 4; - ctx->num_syms = cache_size; - - for (i = 0; i < ctx->cache_size; i++) - ctx->cache[i] = i; - - model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW); - model_init(&ctx->full_model, 256, THRESH_HIGH); - - for (i = 0; i < 4; i++) { - for (j = 0; j < sec_order_sizes[i]; j++) { - for (k = 0; k < 4; k++) { - model_init(&ctx->sec_models[i][j][k], 2 + i, - i ? THRESH_LOW : THRESH_ADAPTIVE); - } - } - } -} - -static int decode_top_left_pixel(ArithCoder *acoder, PixContext *pctx) -{ - int i, val, pix; - - val = arith_get_model_sym(acoder, &pctx->cache_model); - if (val < pctx->num_syms) { - pix = pctx->cache[val]; - } else { - pix = arith_get_model_sym(acoder, &pctx->full_model); - for (i = 0; i < pctx->cache_size - 1; i++) - if (pctx->cache[i] == pix) - break; - val = i; - } - if (val) { - for (i = val; i > 0; i--) - pctx->cache[i] = pctx->cache[i - 1]; - pctx->cache[0] = pix; - } - - return pix; -} - -static int decode_pixel(ArithCoder *acoder, PixContext *pctx, - uint8_t *ngb, int num_ngb) -{ - int i, val, pix; - - val = arith_get_model_sym(acoder, &pctx->cache_model); - if (val < pctx->num_syms) { - int idx, j; - - - idx = 0; - for (i = 0; i < pctx->cache_size; i++) { - for (j = 0; j < num_ngb; j++) - if (pctx->cache[i] == ngb[j]) - break; - if (j == num_ngb) { - if (idx == val) - break; - idx++; - } - } - val = FFMIN(i, pctx->cache_size - 1); - pix = pctx->cache[val]; - } else { - pix = arith_get_model_sym(acoder, &pctx->full_model); - for (i = 0; i < pctx->cache_size - 1; i++) - if (pctx->cache[i] == pix) - break; - val = i; - } - if (val) { - for (i = val; i > 0; i--) - pctx->cache[i] = pctx->cache[i - 1]; - pctx->cache[0] = pix; - } - - return pix; -} - -static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, - uint8_t *src, int stride, int x, int y, - int has_right) -{ - uint8_t neighbours[4]; - uint8_t ref_pix[4]; - int nlen; - int layer = 0, sub; - int pix; - int i, j; - - if (!y) { - memset(neighbours, src[-1], 4); - } else { - neighbours[TOP] = src[-stride]; - if (!x) { - neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP]; - } else { - neighbours[TOP_LEFT] = src[-stride - 1]; - neighbours[ LEFT] = src[-1]; - } - if (has_right) - neighbours[TOP_RIGHT] = src[-stride + 1]; - else - neighbours[TOP_RIGHT] = neighbours[TOP]; - } - - sub = 0; - if (x >= 2 && src[-2] == neighbours[LEFT]) - sub = 1; - if (y >= 2 && src[-2 * stride] == neighbours[TOP]) - sub |= 2; - - nlen = 1; - ref_pix[0] = neighbours[0]; - for (i = 1; i < 4; i++) { - for (j = 0; j < nlen; j++) - if (ref_pix[j] == neighbours[i]) - break; - if (j == nlen) - ref_pix[nlen++] = neighbours[i]; - } - - switch (nlen) { - case 1: - case 4: - layer = 0; - break; - case 2: - if (neighbours[TOP] == neighbours[TOP_LEFT]) { - if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) - layer = 3; - else if (neighbours[LEFT] == neighbours[TOP_LEFT]) - layer = 2; - else - layer = 4; - } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) { - if (neighbours[LEFT] == neighbours[TOP_LEFT]) - layer = 1; - else - layer = 5; - } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) { - layer = 6; - } else { - layer = 0; - } - break; - case 3: - if (neighbours[TOP] == neighbours[TOP_LEFT]) - layer = 0; - else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) - layer = 1; - else if (neighbours[LEFT] == neighbours[TOP_LEFT]) - layer = 2; - else if (neighbours[TOP_RIGHT] == neighbours[TOP]) - layer = 3; - else if (neighbours[TOP] == neighbours[LEFT]) - layer = 4; - else - layer = 5; - break; - } - - pix = arith_get_model_sym(acoder, &pctx->sec_models[nlen - 1][layer][sub]); - if (pix < nlen) - return ref_pix[pix]; - else - return decode_pixel(acoder, pctx, ref_pix, nlen); -} - -static int decode_region(MSS1Context *ctx, ArithCoder *acoder, uint8_t *dst, - int x, int y, int width, int height, int stride, - PixContext *pctx) -{ - int i, j; - - dst += x + y * stride; - - dst[0] = decode_top_left_pixel(acoder, pctx); - for (j = 0; j < height; j++) { - for (i = 0; i < width; i++) { - if (!i && !j) - continue; - - dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride, - i, j, width - i - 1); - } - dst += stride; - } - - return 0; -} - -static int decode_region_masked(MSS1Context *ctx, ArithCoder *acoder, - uint8_t *dst, int stride, uint8_t *mask, - int mask_stride, int x, int y, - int width, int height, - PixContext *pctx) -{ - int i, j; - - dst += x + y * stride; - mask += x + y * mask_stride; - - if (mask[0] == 0xFF) - dst[0] = decode_top_left_pixel(acoder, pctx); - for (j = 0; j < height; j++) { - for (i = 0; i < width; i++) { - if (!i && !j || mask[i] != 0xFF) - continue; - - dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride, - i, j, width - i - 1); - } - dst += stride; - mask += mask_stride; - } - - return 0; -} - -static av_cold void codec_init(MSS1Context *ctx) -{ - model_init(&ctx->intra_region, 2, THRESH_ADAPTIVE); - model_init(&ctx->inter_region, 2, THRESH_ADAPTIVE); - model_init(&ctx->split_mode, 3, THRESH_HIGH); - model_init(&ctx->edge_mode, 2, THRESH_HIGH); - model_init(&ctx->pivot, 3, THRESH_LOW); - pixctx_init(&ctx->intra_pix_ctx, 8); - pixctx_init(&ctx->inter_pix_ctx, 2); - ctx->corrupted = 1; -} - -static void codec_reset(MSS1Context *ctx) -{ - model_reset(&ctx->intra_region); - model_reset(&ctx->inter_region); - model_reset(&ctx->split_mode); - model_reset(&ctx->edge_mode); - model_reset(&ctx->pivot); - pixctx_reset(&ctx->intra_pix_ctx); - pixctx_reset(&ctx->inter_pix_ctx); - - ctx->corrupted = 0; + c->get_model_sym = arith_get_model_sym; + c->get_number = arith_get_number; } static int decode_pal(MSS1Context *ctx, ArithCoder *acoder) { int i, ncol, r, g, b; - uint32_t *pal = ctx->pal + 256 - ctx->free_colours; + uint32_t *pal = ctx->ctx.pal + 256 - ctx->ctx.free_colours; - if (!ctx->free_colours) + if (!ctx->ctx.free_colours) return 0; - ncol = arith_get_number(acoder, ctx->free_colours + 1); + ncol = arith_get_number(acoder, ctx->ctx.free_colours + 1); for (i = 0; i < ncol; i++) { r = arith_get_bits(acoder, 8); g = arith_get_bits(acoder, 8); @@ -561,119 +162,6 @@ static int decode_pal(MSS1Context *ctx, ArithCoder *acoder) return !!ncol; } -static int decode_pivot(MSS1Context *ctx, ArithCoder *acoder, int base) -{ - int val, inv; - - inv = arith_get_model_sym(acoder, &ctx->edge_mode); - val = arith_get_model_sym(acoder, &ctx->pivot) + 1; - - if (val > 2) { - if ((base + 1) / 2 - 2 <= 0) { - ctx->corrupted = 1; - return 0; - } - val = arith_get_number(acoder, (base + 1) / 2 - 2) + 3; - } - - if (val == base) { - ctx->corrupted = 1; - return 0; - } - - return inv ? base - val : val; -} - -static int decode_region_intra(MSS1Context *ctx, ArithCoder *acoder, - int x, int y, int width, int height) -{ - int mode; - - mode = arith_get_model_sym(acoder, &ctx->intra_region); - - if (!mode) { - int i, pix; - int stride = ctx->pic_stride; - uint8_t *dst = ctx->pic_start + x + y * stride; - - pix = decode_top_left_pixel(acoder, &ctx->intra_pix_ctx); - for (i = 0; i < height; i++, dst += stride) - memset(dst, pix, width); - } else { - return decode_region(ctx, acoder, ctx->pic_start, - x, y, width, height, ctx->pic_stride, - &ctx->intra_pix_ctx); - } - - return 0; -} - -static int decode_region_inter(MSS1Context *ctx, ArithCoder *acoder, - int x, int y, int width, int height) -{ - int mode; - - mode = arith_get_model_sym(acoder, &ctx->inter_region); - - if (!mode) { - mode = decode_top_left_pixel(acoder, &ctx->inter_pix_ctx); - if (mode != 0xFF) { - return 0; - } else { - return decode_region_intra(ctx, acoder, x, y, width, height); - } - } else { - if (decode_region(ctx, acoder, ctx->mask, - x, y, width, height, ctx->mask_linesize, - &ctx->inter_pix_ctx) < 0) - return -1; - return decode_region_masked(ctx, acoder, ctx->pic_start, - -ctx->pic.linesize[0], ctx->mask, - ctx->mask_linesize, - x, y, width, height, - &ctx->intra_pix_ctx); - } - - return 0; -} - -static int decode_rect(MSS1Context *ctx, ArithCoder *acoder, - int x, int y, int width, int height) -{ - int mode, pivot; - - if (ctx->corrupted) - return -1; - - mode = arith_get_model_sym(acoder, &ctx->split_mode); - - switch (mode) { - case SPLIT_VERT: - pivot = decode_pivot(ctx, acoder, height); - if (decode_rect(ctx, acoder, x, y, width, pivot)) - return -1; - if (decode_rect(ctx, acoder, x, y + pivot, width, height - pivot)) - return -1; - break; - case SPLIT_HOR: - pivot = decode_pivot(ctx, acoder, width); - if (decode_rect(ctx, acoder, x, y, pivot, height)) - return -1; - if (decode_rect(ctx, acoder, x + pivot, y, width - pivot, height)) - return -1; - break; - case SPLIT_NONE: - if (ctx->keyframe) - return decode_region_intra(ctx, acoder, x, y, width, height); - else - return decode_region_inter(ctx, acoder, x, y, width, height); - default: - return -1; - } - - return 0; -} - static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { @@ -696,24 +184,25 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return ret; } - c->pic_start = c->pic.data[0] + c->pic.linesize[0] * (avctx->height - 1); - c->pic_stride = -c->pic.linesize[0]; - c->keyframe = !arith_get_bit(&acoder); - if (c->keyframe) { - codec_reset(c); + c->ctx.pic_start = c->pic.data[0] + c->pic.linesize[0] * (avctx->height - 1); + c->ctx.pic_stride = -c->pic.linesize[0]; + c->ctx.keyframe = !arith_get_bit(&acoder); + if (c->ctx.keyframe) { + ff_mss12_codec_reset(&c->ctx); pal_changed = decode_pal(c, &acoder); c->pic.key_frame = 1; c->pic.pict_type = AV_PICTURE_TYPE_I; } else { - if (c->corrupted) + if (c->ctx.corrupted) return AVERROR_INVALIDDATA; c->pic.key_frame = 0; c->pic.pict_type = AV_PICTURE_TYPE_P; } - c->corrupted = decode_rect(c, &acoder, 0, 0, avctx->width, avctx->height); - if (c->corrupted) + c->ctx.corrupted = ff_mss12_decode_rect(&c->ctx, &acoder, 0, 0, + avctx->width, avctx->height); + if (c->ctx.corrupted) return AVERROR_INVALIDDATA; - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); + memcpy(c->pic.data[1], c->ctx.pal, AVPALETTE_SIZE); c->pic.palette_has_changed = pal_changed; *data_size = sizeof(AVFrame); @@ -726,69 +215,11 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, static av_cold int mss1_decode_init(AVCodecContext *avctx) { MSS1Context * const c = avctx->priv_data; - int i; - - c->avctx = avctx; - - if (avctx->extradata_size < 52 + 256 * 3) { - av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n", - avctx->extradata_size); - return AVERROR_INVALIDDATA; - } - - if (AV_RB32(avctx->extradata) < avctx->extradata_size) { - av_log(avctx, AV_LOG_ERROR, - "Insufficient extradata size: expected %d got %d\n", - AV_RB32(avctx->extradata), - avctx->extradata_size); - return AVERROR_INVALIDDATA; - } - - av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n", - AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8)); - c->free_colours = AV_RB32(avctx->extradata + 48); - if ((unsigned)c->free_colours > 256) { - av_log(avctx, AV_LOG_ERROR, - "Incorrect number of changeable palette entries: %d\n", - c->free_colours); - return AVERROR_INVALIDDATA; - } - av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours); - avctx->coded_width = AV_RB32(avctx->extradata + 20); - avctx->coded_height = AV_RB32(avctx->extradata + 24); - - av_log(avctx, AV_LOG_DEBUG, "Display dimensions %dx%d\n", - AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16)); - av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n", - avctx->coded_width, avctx->coded_height); - av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n", - av_int2float(AV_RB32(avctx->extradata + 28))); - av_log(avctx, AV_LOG_DEBUG, "Bitrate %d bps\n", - AV_RB32(avctx->extradata + 32)); - av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n", - av_int2float(AV_RB32(avctx->extradata + 36))); - av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n", - av_int2float(AV_RB32(avctx->extradata + 40))); - av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n", - av_int2float(AV_RB32(avctx->extradata + 44))); - - for (i = 0; i < 256; i++) - c->pal[i] = AV_RB24(avctx->extradata + 52 + i * 3); - - avctx->pix_fmt = PIX_FMT_PAL8; - - c->mask_linesize = FFALIGN(avctx->width, 16); - c->mask = av_malloc(c->mask_linesize * avctx->height); - if (!c->mask) { - av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n"); - return AVERROR(ENOMEM); - } + c->ctx.avctx = avctx; avctx->coded_frame = &c->pic; - codec_init(c); - - return 0; + return ff_mss12_decode_init(avctx, 0); } static av_cold int mss1_decode_end(AVCodecContext *avctx) @@ -797,7 +228,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx) if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); - av_freep(&c->mask); + ff_mss12_decode_end(avctx); return 0; } diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c new file mode 100644 index 0000000000..8b4f52bf5f --- /dev/null +++ b/libavcodec/mss12.c @@ -0,0 +1,581 @@ +/* + * Copyright (c) 2012 Konstantin Shishkov + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Common functions for Microsoft Screen 1 and 2 + */ + +#include "libavutil/intfloat.h" +#include "libavutil/intreadwrite.h" +#include "avcodec.h" +#include "mss12.h" + +enum SplitMode { + SPLIT_VERT = 0, + SPLIT_HOR, + SPLIT_NONE +}; + +static const int sec_order_sizes[4] = { 1, 7, 6, 1 }; + +enum ContextDirection { + TOP_LEFT = 0, + TOP, + TOP_RIGHT, + LEFT +}; + +static int model_calc_threshold(Model *m) +{ + int thr; + + if (m->thr_weight == -1) { + thr = 2 * m->weights[m->num_syms] - 1; + thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr; + } else { + thr = m->num_syms * m->thr_weight; + } + + return FFMIN(thr, 0x3FFF); +} + +static void model_reset(Model *m) +{ + int i; + + for (i = 0; i <= m->num_syms; i++) { + m->weights[i] = 1; + m->cum_prob[i] = m->num_syms - i; + } + m->weights[0] = -1; + m->idx2sym[0] = -1; + m->sym2idx[m->num_syms] = -1; + for (i = 0; i < m->num_syms; i++) { + m->sym2idx[i] = i + 1; + m->idx2sym[i + 1] = i; + } +} + +static av_cold void model_init(Model *m, int num_syms, int thr_weight) +{ + m->num_syms = num_syms; + m->thr_weight = thr_weight; + m->threshold = model_calc_threshold(m); + model_reset(m); +} + +static void model_rescale_weights(Model *m) +{ + int i; + int cum_prob; + + if (m->thr_weight == -1) + m->threshold = model_calc_threshold(m); + while (m->cum_prob[0] > m->threshold) { + cum_prob = 0; + for (i = m->num_syms; i >= 0; i--) { + m->cum_prob[i] = cum_prob; + m->weights[i] = (m->weights[i] + 1) >> 1; + cum_prob += m->weights[i]; + } + } +} + +void ff_mss12_model_update(Model *m, int val) +{ + int i; + + if (m->weights[val] == m->weights[val - 1]) { + for (i = val; m->weights[i - 1] == m->weights[val]; i--); + if (i != val) { + int sym1, sym2; + + sym1 = m->idx2sym[val]; + sym2 = m->idx2sym[i]; + + m->idx2sym[val] = sym2; + m->idx2sym[i] = sym1; + m->sym2idx[sym1] = i; + m->sym2idx[sym2] = val; + + val = i; + } + } + m->weights[val]++; + for (i = val - 1; i >= 0; i--) + m->cum_prob[i]++; + model_rescale_weights(m); +} + +static void pixctx_reset(PixContext *ctx) +{ + int i, j, k; + + for (i = 0; i < ctx->cache_size; i++) + ctx->cache[i] = i; + + model_reset(&ctx->cache_model); + model_reset(&ctx->full_model); + + for (i = 0; i < 4; i++) + for (j = 0; j < sec_order_sizes[i]; j++) + for (k = 0; k < 4; k++) + model_reset(&ctx->sec_models[i][j][k]); +} + +static av_cold void pixctx_init(PixContext *ctx, int cache_size) +{ + int i, j, k; + + ctx->cache_size = cache_size + 4; + ctx->num_syms = cache_size; + + for (i = 0; i < ctx->cache_size; i++) + ctx->cache[i] = i; + + model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW); + model_init(&ctx->full_model, 256, THRESH_HIGH); + + for (i = 0; i < 4; i++) { + for (j = 0; j < sec_order_sizes[i]; j++) { + for (k = 0; k < 4; k++) { + model_init(&ctx->sec_models[i][j][k], 2 + i, + i ? THRESH_LOW : THRESH_ADAPTIVE); + } + } + } +} + +static int decode_top_left_pixel(ArithCoder *acoder, PixContext *pctx) +{ + int i, val, pix; + + val = acoder->get_model_sym(acoder, &pctx->cache_model); + if (val < pctx->num_syms) { + pix = pctx->cache[val]; + } else { + pix = acoder->get_model_sym(acoder, &pctx->full_model); + for (i = 0; i < pctx->cache_size - 1; i++) + if (pctx->cache[i] == pix) + break; + val = i; + } + if (val) { + for (i = val; i > 0; i--) + pctx->cache[i] = pctx->cache[i - 1]; + pctx->cache[0] = pix; + } + + return pix; +} + +static int decode_pixel(ArithCoder *acoder, PixContext *pctx, + uint8_t *ngb, int num_ngb) +{ + int i, val, pix; + + val = acoder->get_model_sym(acoder, &pctx->cache_model); + if (val < pctx->num_syms) { + int idx, j; + + + idx = 0; + for (i = 0; i < pctx->cache_size; i++) { + for (j = 0; j < num_ngb; j++) + if (pctx->cache[i] == ngb[j]) + break; + if (j == num_ngb) { + if (idx == val) + break; + idx++; + } + } + val = FFMIN(i, pctx->cache_size - 1); + pix = pctx->cache[val]; + } else { + pix = acoder->get_model_sym(acoder, &pctx->full_model); + for (i = 0; i < pctx->cache_size - 1; i++) + if (pctx->cache[i] == pix) + break; + val = i; + } + if (val) { + for (i = val; i > 0; i--) + pctx->cache[i] = pctx->cache[i - 1]; + pctx->cache[0] = pix; + } + + return pix; +} + +static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, + uint8_t *src, int stride, int x, int y, + int has_right) +{ + uint8_t neighbours[4]; + uint8_t ref_pix[4]; + int nlen; + int layer = 0, sub; + int pix; + int i, j; + + if (!y) { + memset(neighbours, src[-1], 4); + } else { + neighbours[TOP] = src[-stride]; + if (!x) { + neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP]; + } else { + neighbours[TOP_LEFT] = src[-stride - 1]; + neighbours[ LEFT] = src[-1]; + } + if (has_right) + neighbours[TOP_RIGHT] = src[-stride + 1]; + else + neighbours[TOP_RIGHT] = neighbours[TOP]; + } + + sub = 0; + if (x >= 2 && src[-2] == neighbours[LEFT]) + sub = 1; + if (y >= 2 && src[-2 * stride] == neighbours[TOP]) + sub |= 2; + + nlen = 1; + ref_pix[0] = neighbours[0]; + for (i = 1; i < 4; i++) { + for (j = 0; j < nlen; j++) + if (ref_pix[j] == neighbours[i]) + break; + if (j == nlen) + ref_pix[nlen++] = neighbours[i]; + } + + switch (nlen) { + case 1: + case 4: + layer = 0; + break; + case 2: + if (neighbours[TOP] == neighbours[TOP_LEFT]) { + if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) + layer = 3; + else if (neighbours[LEFT] == neighbours[TOP_LEFT]) + layer = 2; + else + layer = 4; + } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) { + if (neighbours[LEFT] == neighbours[TOP_LEFT]) + layer = 1; + else + layer = 5; + } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) { + layer = 6; + } else { + layer = 0; + } + break; + case 3: + if (neighbours[TOP] == neighbours[TOP_LEFT]) + layer = 0; + else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) + layer = 1; + else if (neighbours[LEFT] == neighbours[TOP_LEFT]) + layer = 2; + else if (neighbours[TOP_RIGHT] == neighbours[TOP]) + layer = 3; + else if (neighbours[TOP] == neighbours[LEFT]) + layer = 4; + else + layer = 5; + break; + } + + pix = acoder->get_model_sym(acoder, &pctx->sec_models[nlen - 1][layer][sub]); + if (pix < nlen) + return ref_pix[pix]; + else + return decode_pixel(acoder, pctx, ref_pix, nlen); +} + +static int decode_region(MSS12Context *ctx, ArithCoder *acoder, uint8_t *dst, + int x, int y, int width, int height, int stride, + PixContext *pctx) +{ + int i, j; + + dst += x + y * stride; + + dst[0] = decode_top_left_pixel(acoder, pctx); + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + if (!i && !j) + continue; + + dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride, + i, j, width - i - 1); + } + dst += stride; + } + + return 0; +} + +static int decode_region_masked(MSS12Context *ctx, ArithCoder *acoder, + uint8_t *dst, int stride, uint8_t *mask, + int mask_stride, int x, int y, + int width, int height, + PixContext *pctx) +{ + int i, j; + + dst += x + y * stride; + mask += x + y * mask_stride; + + if (mask[0] == 0xFF) + dst[0] = decode_top_left_pixel(acoder, pctx); + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + if (!i && !j || mask[i] != 0xFF) + continue; + + dst[i] = decode_pixel_in_context(acoder, pctx, dst + i, stride, + i, j, width - i - 1); + } + dst += stride; + mask += mask_stride; + } + + return 0; +} + +static av_cold void codec_init(MSS12Context *ctx) +{ + model_init(&ctx->intra_region, 2, THRESH_ADAPTIVE); + model_init(&ctx->inter_region, 2, THRESH_ADAPTIVE); + model_init(&ctx->split_mode, 3, THRESH_HIGH); + model_init(&ctx->edge_mode, 2, THRESH_HIGH); + model_init(&ctx->pivot, 3, THRESH_LOW); + pixctx_init(&ctx->intra_pix_ctx, 8); + pixctx_init(&ctx->inter_pix_ctx, 2); + ctx->corrupted = 1; +} + +void ff_mss12_codec_reset(MSS12Context *ctx) +{ + model_reset(&ctx->intra_region); + model_reset(&ctx->inter_region); + model_reset(&ctx->split_mode); + model_reset(&ctx->edge_mode); + model_reset(&ctx->pivot); + pixctx_reset(&ctx->intra_pix_ctx); + pixctx_reset(&ctx->inter_pix_ctx); + + ctx->corrupted = 0; +} + +static int decode_pivot(MSS12Context *ctx, ArithCoder *acoder, int base) +{ + int val, inv; + + inv = acoder->get_model_sym(acoder, &ctx->edge_mode); + val = acoder->get_model_sym(acoder, &ctx->pivot) + 1; + + if (val > 2) { + if ((base + 1) / 2 - 2 <= 0) { + ctx->corrupted = 1; + return 0; + } + val = acoder->get_number(acoder, (base + 1) / 2 - 2) + 3; + } + + if (val == base) { + ctx->corrupted = 1; + return 0; + } + + return inv ? base - val : val; +} + +static int decode_region_intra(MSS12Context *ctx, ArithCoder *acoder, + int x, int y, int width, int height) +{ + int mode; + + mode = acoder->get_model_sym(acoder, &ctx->intra_region); + + if (!mode) { + int i, pix; + int stride = ctx->pic_stride; + uint8_t *dst = ctx->pic_start + x + y * stride; + + pix = decode_top_left_pixel(acoder, &ctx->intra_pix_ctx); + for (i = 0; i < height; i++, dst += stride) + memset(dst, pix, width); + } else { + return decode_region(ctx, acoder, ctx->pic_start, + x, y, width, height, ctx->pic_stride, + &ctx->intra_pix_ctx); + } + + return 0; +} + +static int decode_region_inter(MSS12Context *ctx, ArithCoder *acoder, + int x, int y, int width, int height) +{ + int mode; + + mode = acoder->get_model_sym(acoder, &ctx->inter_region); + + if (!mode) { + mode = decode_top_left_pixel(acoder, &ctx->inter_pix_ctx); + if (mode != 0xFF) { + return 0; + } else { + return decode_region_intra(ctx, acoder, x, y, width, height); + } + } else { + if (decode_region(ctx, acoder, ctx->mask, + x, y, width, height, ctx->mask_linesize, + &ctx->inter_pix_ctx) < 0) + return -1; + return decode_region_masked(ctx, acoder, ctx->pic_start, + ctx->pic_stride, ctx->mask, + ctx->mask_linesize, + x, y, width, height, + &ctx->intra_pix_ctx); + } + + return 0; +} + +int ff_mss12_decode_rect(MSS12Context *ctx, ArithCoder *acoder, + int x, int y, int width, int height) +{ + int mode, pivot; + + if (ctx->corrupted) + return -1; + + mode = acoder->get_model_sym(acoder, &ctx->split_mode); + + switch (mode) { + case SPLIT_VERT: + pivot = decode_pivot(ctx, acoder, height); + if (ff_mss12_decode_rect(ctx, acoder, x, y, width, pivot)) + return -1; + if (ff_mss12_decode_rect(ctx, acoder, x, y + pivot, width, height - pivot)) + return -1; + break; + case SPLIT_HOR: + pivot = decode_pivot(ctx, acoder, width); + if (ff_mss12_decode_rect(ctx, acoder, x, y, pivot, height)) + return -1; + if (ff_mss12_decode_rect(ctx, acoder, x + pivot, y, width - pivot, height)) + return -1; + break; + case SPLIT_NONE: + if (ctx->keyframe) + return decode_region_intra(ctx, acoder, x, y, width, height); + else + return decode_region_inter(ctx, acoder, x, y, width, height); + default: + return -1; + } + + return 0; +} + +av_cold int ff_mss12_decode_init(AVCodecContext *avctx, int version) +{ + MSS12Context * const c = avctx->priv_data; + int i; + + c->avctx = avctx; + + if (avctx->extradata_size < 52 + 256 * 3) { + av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n", + avctx->extradata_size); + return AVERROR_INVALIDDATA; + } + + if (AV_RB32(avctx->extradata) < avctx->extradata_size) { + av_log(avctx, AV_LOG_ERROR, + "Insufficient extradata size: expected %d got %d\n", + AV_RB32(avctx->extradata), + avctx->extradata_size); + return AVERROR_INVALIDDATA; + } + + av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n", + AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8)); + c->free_colours = AV_RB32(avctx->extradata + 48); + if ((unsigned)c->free_colours > 256) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect number of changeable palette entries: %d\n", + c->free_colours); + return AVERROR_INVALIDDATA; + } + av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours); + avctx->coded_width = AV_RB32(avctx->extradata + 20); + avctx->coded_height = AV_RB32(avctx->extradata + 24); + + av_log(avctx, AV_LOG_DEBUG, "Display dimensions %dx%d\n", + AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16)); + av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n", + avctx->coded_width, avctx->coded_height); + av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n", + av_int2float(AV_RB32(avctx->extradata + 28))); + av_log(avctx, AV_LOG_DEBUG, "Bitrate %d bps\n", + AV_RB32(avctx->extradata + 32)); + av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n", + av_int2float(AV_RB32(avctx->extradata + 36))); + av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n", + av_int2float(AV_RB32(avctx->extradata + 40))); + av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n", + av_int2float(AV_RB32(avctx->extradata + 44))); + + for (i = 0; i < 256; i++) + c->pal[i] = AV_RB24(avctx->extradata + 52 + i * 3); + + avctx->pix_fmt = PIX_FMT_PAL8; + + c->mask_linesize = FFALIGN(avctx->width, 16); + c->mask = av_malloc(c->mask_linesize * avctx->height); + if (!c->mask) { + av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n"); + return AVERROR(ENOMEM); + } + + codec_init(c); + + return 0; +} + +av_cold int ff_mss12_decode_end(AVCodecContext *avctx) +{ + MSS12Context * const c = avctx->priv_data; + + av_freep(&c->mask); + + return 0; +} diff --git a/libavcodec/mss12.h b/libavcodec/mss12.h new file mode 100644 index 0000000000..383d86c904 --- /dev/null +++ b/libavcodec/mss12.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012 Konstantin Shishkov + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Common header for Microsoft Screen 1 and 2 + */ + +#ifndef AVCODEC_MSS12_H +#define AVCODEC_MSS12_H + +#include "avcodec.h" +#include "get_bits.h" + +#define MODEL_MIN_SYMS 2 +#define MODEL_MAX_SYMS 256 +#define THRESH_ADAPTIVE -1 +#define THRESH_LOW 15 +#define THRESH_HIGH 50 + +typedef struct Model { + int cum_prob[MODEL_MAX_SYMS + 1]; + int weights[MODEL_MAX_SYMS + 1]; + int idx2sym[MODEL_MAX_SYMS + 1]; + int sym2idx[MODEL_MAX_SYMS + 1]; + int num_syms; + int thr_weight, threshold; +} Model; + +typedef struct ArithCoder { + int low, high, value; + GetBitContext *gb; + int (*get_model_sym)(struct ArithCoder *c, Model *m); + int (*get_number) (struct ArithCoder *c, int n); +} ArithCoder; + +typedef struct PixContext { + int cache_size, num_syms; + uint8_t cache[12]; + Model cache_model, full_model; + Model sec_models[4][8][4]; +} PixContext; + +typedef struct MSS12Context { + AVCodecContext *avctx; + uint8_t *pic_start; + int pic_stride; + uint8_t *mask; + int mask_linesize; + uint32_t pal[256]; + int free_colours; + int keyframe; + Model intra_region, inter_region; + Model pivot, edge_mode, split_mode; + PixContext intra_pix_ctx, inter_pix_ctx; + int corrupted; +} MSS12Context; + +int ff_mss12_decode_rect(MSS12Context *ctx, ArithCoder *acoder, + int x, int y, int width, int height); +void ff_mss12_model_update(Model *m, int val); +void ff_mss12_codec_reset(MSS12Context *ctx); +av_cold int ff_mss12_decode_init(AVCodecContext *avctx, int version); +av_cold int ff_mss12_decode_end(AVCodecContext *avctx); + +#endif /* AVCODEC_MSS12_H */ From 5395d882b4c06825f43239d2e8869c82275bb3b6 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Sun, 26 Aug 2012 20:57:08 -0400 Subject: [PATCH 05/15] vp56: Don't use DECLARE_ALIGN on a typedef name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, use it on the first member, since by definition, if any member is aligned, the whole struct must be, in order to maintain that alignment. Fixes compilation with some finicky compilers. Idea for fix from Måns Rullgård. Signed-off-by: Derek Buitenhuis --- libavcodec/vp56.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index d03b733d19..000dfe0098 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -36,9 +36,9 @@ typedef struct vp56_context VP56Context; typedef struct { - int16_t x; + DECLARE_ALIGNED(4, int16_t, x); int16_t y; -} DECLARE_ALIGNED(4, , VP56mv); +} VP56mv; typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, VP56mv *vect); From d5683aba5a4ca142ce9d446b565f7310107872c3 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sun, 26 Aug 2012 16:23:06 -0400 Subject: [PATCH 06/15] configure: Fix shared library creation for OpenBSD OpenBSD does not expect or require symlinked shared libraries with just the major version in the name. Signed-off-by: Diego Biurrun --- configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure b/configure index 12052c0056..5a626b2a55 100755 --- a/configure +++ b/configure @@ -2590,6 +2590,8 @@ case $target_os in enable pic disable symver SHFLAGS='-shared' + SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBVERSION)' + SLIB_INSTALL_LINKS= oss_indev_extralibs="-lossaudio" oss_outdev_extralibs="-lossaudio" ;; From 8f7c26e39297c8ecc8670a04936e47fbfc33439b Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 27 Aug 2012 05:09:29 +0200 Subject: [PATCH 07/15] build: Use portable abstraction for linker/hostcc output file syntax --- Makefile | 4 ++-- common.mak | 2 +- library.mak | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index d2aed23cd4..a2d89c5f68 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ FF_DEP_LIBS := $(DEP_LIBS) all: $(PROGS) $(TOOLS): %$(EXESUF): %.o - $(LD) $(LDFLAGS) -o $@ $< $(ELIBS) + $(LD) $(LDFLAGS) $(LD_O) $< $(ELIBS) tools/cws2fws$(EXESUF): ELIBS = -lz @@ -135,7 +135,7 @@ endef $(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P)))) $(PROGS): %$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS) - $(LD) $(LDFLAGS) -o $@ $(OBJS-$*) cmdutils.o $(FF_EXTRALIBS) + $(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) cmdutils.o $(FF_EXTRALIBS) OBJDIRS += tools diff --git a/common.mak b/common.mak index f94a43d35a..ae87e76bbd 100644 --- a/common.mak +++ b/common.mak @@ -38,7 +38,7 @@ $(HOSTOBJS): %.o: %.c $(call COMPILE,HOSTCC) $(HOSTPROGS): %$(HOSTEXESUF): %.o - $(HOSTCC) $(HOSTLDFLAGS) -o $@ $< $(HOSTLIBS) + $(HOSTCC) $(HOSTLDFLAGS) $(HOSTCC_O) $< $(HOSTLIBS) $(OBJS): | $(sort $(dir $(OBJS))) $(HOSTOBJS): | $(sort $(dir $(HOSTOBJS))) diff --git a/library.mak b/library.mak index 9742ac4b7b..165a78204f 100644 --- a/library.mak +++ b/library.mak @@ -35,14 +35,14 @@ install-libs-$(CONFIG_SHARED): install-lib$(NAME)-shared define RULES $(EXAMPLES) $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o - $$(LD) $(LDFLAGS) -o $$@ $$^ -l$(FULLNAME) $(FFEXTRALIBS) $$(ELIBS) + $$(LD) $(LDFLAGS) $$(LD_O) $$^ -l$(FULLNAME) $(FFEXTRALIBS) $$(ELIBS) $(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR) $(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME) $(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver $(DEP_LIBS) $(SLIB_CREATE_DEF_CMD) - $$(LD) $(SHFLAGS) $(LDFLAGS) -o $$@ $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS) + $$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS) $(SLIB_EXTRA_CMD) clean:: From 55498543354335697bf1c5616a2ba94c64fbdcf1 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 26 Aug 2012 17:27:12 +0200 Subject: [PATCH 08/15] celp_math: Move ff_cos() to the only place it is used --- libavcodec/Makefile | 4 ++-- libavcodec/celp_math.c | 25 ------------------------- libavcodec/celp_math.h | 8 -------- libavcodec/lsp.c | 24 ++++++++++++++++++++++++ 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 87f716ce36..d491fc2a8c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -171,7 +171,7 @@ OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o OBJS-$(CONFIG_FRWU_DECODER) += frwu.o OBJS-$(CONFIG_G723_1_DECODER) += g723_1.o acelp_vectors.o \ - celp_filters.o celp_math.o + celp_filters.o OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o OBJS-$(CONFIG_GIF_ENCODER) += gif.o lzwenc.o OBJS-$(CONFIG_GSM_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o @@ -367,7 +367,7 @@ OBJS-$(CONFIG_TRUESPEECH_DECODER) += truespeech.o OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o OBJS-$(CONFIG_TTA_DECODER) += tta.o -OBJS-$(CONFIG_TWINVQ_DECODER) += twinvq.o celp_math.o +OBJS-$(CONFIG_TWINVQ_DECODER) += twinvq.o OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o OBJS-$(CONFIG_ULTI_DECODER) += ulti.o OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o diff --git a/libavcodec/celp_math.c b/libavcodec/celp_math.c index a34508f85c..b28c51b52d 100644 --- a/libavcodec/celp_math.c +++ b/libavcodec/celp_math.c @@ -28,21 +28,6 @@ #include "celp_math.h" #include "libavutil/common.h" -/** - * Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64) - */ -static const int16_t tab_cos[65] = -{ - 32767, 32738, 32617, 32421, 32145, 31793, 31364, 30860, - 30280, 29629, 28905, 28113, 27252, 26326, 25336, 24285, - 23176, 22011, 20793, 19525, 18210, 16851, 15451, 14014, - 12543, 11043, 9515, 7965, 6395, 4810, 3214, 1609, - 1, -1607, -3211, -4808, -6393, -7962, -9513, -11040, - -12541, -14012, -15449, -16848, -18207, -19523, -20791, -22009, - -23174, -24283, -25334, -26324, -27250, -28111, -28904, -29627, - -30279, -30858, -31363, -31792, -32144, -32419, -32616, -32736, -32768, -}; - static const uint16_t exp2a[]= { 0, 1435, 2901, 4400, 5931, 7496, 9096, 10730, @@ -59,16 +44,6 @@ static const uint16_t exp2b[]= 17176, 17898, 18620, 19343, 20066, 20790, 21514, 22238, }; -int16_t ff_cos(uint16_t arg) -{ - uint8_t offset= arg; - uint8_t ind = arg >> 8; - - assert(arg <= 0x3fff); - - return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8); -} - int ff_exp2(uint16_t power) { unsigned int result= exp2a[power>>10] + 0x10000; diff --git a/libavcodec/celp_math.h b/libavcodec/celp_math.h index 4a502ca04b..92cc2abf7e 100644 --- a/libavcodec/celp_math.h +++ b/libavcodec/celp_math.h @@ -25,14 +25,6 @@ #include -/** - * fixed-point implementation of cosine in [0; PI) domain. - * @param arg fixed-point cosine argument, 0 <= arg < 0x4000 - * - * @return value of (1<<15) * cos(arg * PI / (1<<14)), -0x8000 <= result <= 0x7fff - */ -int16_t ff_cos(uint16_t arg); - /** * fixed-point implementation of exp2(x) in [0; 1] domain. * @param power argument to exp2, 0 <= power <= 0x7fff diff --git a/libavcodec/lsp.c b/libavcodec/lsp.c index 2adc9cfa39..b501bfb7b8 100644 --- a/libavcodec/lsp.c +++ b/libavcodec/lsp.c @@ -55,6 +55,30 @@ void ff_set_min_dist_lsf(float *lsf, double min_spacing, int size) prev = lsf[i] = FFMAX(lsf[i], prev + min_spacing); } + +/* Cosine table: base_cos[i] = (1 << 15) * cos(i * PI / 64) */ +static const int16_t tab_cos[65] = +{ + 32767, 32738, 32617, 32421, 32145, 31793, 31364, 30860, + 30280, 29629, 28905, 28113, 27252, 26326, 25336, 24285, + 23176, 22011, 20793, 19525, 18210, 16851, 15451, 14014, + 12543, 11043, 9515, 7965, 6395, 4810, 3214, 1609, + 1, -1607, -3211, -4808, -6393, -7962, -9513, -11040, + -12541, -14012, -15449, -16848, -18207, -19523, -20791, -22009, + -23174, -24283, -25334, -26324, -27250, -28111, -28904, -29627, + -30279, -30858, -31363, -31792, -32144, -32419, -32616, -32736, -32768, +}; + +static int16_t ff_cos(uint16_t arg) +{ + uint8_t offset= arg; + uint8_t ind = arg >> 8; + + assert(arg <= 0x3fff); + + return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8); +} + void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order) { int i; From dafcbfe44361b0d3caa22b15bc95e38ba80af7e6 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 26 Aug 2012 11:29:39 +0200 Subject: [PATCH 09/15] celp_math: Replace duplicate ff_dot_productf() by ff_scalarproduct_c() --- libavcodec/Makefile | 12 ++++++------ libavcodec/acelp_pitch_delay.c | 3 +-- libavcodec/acelp_vectors.c | 6 +++--- libavcodec/amrnbdec.c | 20 +++++++++++--------- libavcodec/amrwbdec.c | 33 +++++++++++++++++++-------------- libavcodec/celp_math.c | 11 ----------- libavcodec/celp_math.h | 10 ---------- libavcodec/dsputil.c | 4 ++-- libavcodec/dsputil.h | 11 +++++++++++ libavcodec/lsp.c | 1 - libavcodec/qcelpdec.c | 13 ++++++------- libavcodec/ra288.c | 5 ++--- libavcodec/sipr.c | 9 ++++----- libavcodec/sipr16k.c | 7 ++++--- libavcodec/wmavoice.c | 15 ++++++++------- 15 files changed, 77 insertions(+), 83 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index d491fc2a8c..c022e16aa9 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -84,11 +84,11 @@ OBJS-$(CONFIG_ALAC_DECODER) += alac.o OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o OBJS-$(CONFIG_ALS_DECODER) += alsdec.o bgmc.o mpeg4audio.o OBJS-$(CONFIG_AMRNB_DECODER) += amrnbdec.o celp_filters.o \ - celp_math.o acelp_filters.o \ + acelp_filters.o \ acelp_vectors.o \ acelp_pitch_delay.o OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \ - celp_math.o acelp_filters.o \ + acelp_filters.o \ acelp_vectors.o \ acelp_pitch_delay.o OBJS-$(CONFIG_AMV_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o @@ -298,7 +298,7 @@ OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o OBJS-$(CONFIG_PRORES_DECODER) += proresdec.o proresdata.o proresdsp.o OBJS-$(CONFIG_PRORES_ENCODER) += proresenc.o proresdata.o proresdsp.o OBJS-$(CONFIG_PTX_DECODER) += ptx.o -OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o celp_math.o \ +OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \ celp_filters.o acelp_vectors.o \ acelp_filters.o OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o @@ -311,7 +311,7 @@ OBJS-$(CONFIG_R210_DECODER) += r210dec.o OBJS-$(CONFIG_RA_144_DECODER) += ra144dec.o ra144.o celp_filters.o OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o \ audio_frame_queue.o -OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_math.o celp_filters.o +OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_filters.o OBJS-$(CONFIG_RALF_DECODER) += ralf.o OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o @@ -332,7 +332,7 @@ OBJS-$(CONFIG_SGI_DECODER) += sgidec.o OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o OBJS-$(CONFIG_SHORTEN_DECODER) += shorten.o OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \ - celp_math.o acelp_vectors.o \ + acelp_vectors.o \ acelp_filters.o celp_filters.o \ sipr16k.o OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o @@ -408,7 +408,7 @@ OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o OBJS-$(CONFIG_WMAV2_DECODER) += wmadec.o wma.o wma_common.o aactab.o OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \ - celp_math.o celp_filters.o \ + celp_filters.o \ acelp_vectors.o acelp_filters.o OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o \ diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c index 8aa500869b..1c8485047f 100644 --- a/libavcodec/acelp_pitch_delay.c +++ b/libavcodec/acelp_pitch_delay.c @@ -25,7 +25,6 @@ #include "avcodec.h" #include "dsputil.h" #include "acelp_pitch_delay.h" -#include "celp_math.h" int ff_acelp_decode_8bit_to_1st_delay3(int ac_index) { @@ -120,7 +119,7 @@ float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy, // Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)). float val = fixed_gain_factor * exp2f(M_LOG2_10 * 0.05 * - (ff_dot_productf(pred_table, prediction_error, 4) + + (ff_scalarproduct_float_c(pred_table, prediction_error, 4) + energy_mean)) / sqrtf(fixed_mean_energy); diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c index 4b378cab65..b50c5f3ffe 100644 --- a/libavcodec/acelp_vectors.c +++ b/libavcodec/acelp_vectors.c @@ -24,8 +24,8 @@ #include "libavutil/common.h" #include "avcodec.h" +#include "dsputil.h" #include "acelp_vectors.h" -#include "celp_math.h" const uint8_t ff_fc_2pulses_9bits_track1[16] = { @@ -183,7 +183,7 @@ void ff_adaptive_gain_control(float *out, const float *in, float speech_energ, int size, float alpha, float *gain_mem) { int i; - float postfilter_energ = ff_dot_productf(in, in, size); + float postfilter_energ = ff_scalarproduct_float_c(in, in, size); float gain_scale_factor = 1.0; float mem = *gain_mem; @@ -204,7 +204,7 @@ void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, float sum_of_squares, const int n) { int i; - float scalefactor = ff_dot_productf(in, in, n); + float scalefactor = ff_scalarproduct_float_c(in, in, n); if (scalefactor) scalefactor = sqrt(sum_of_squares / scalefactor); for (i = 0; i < n; i++) diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index 28f30216e2..d0ad76c7ea 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -44,8 +44,8 @@ #include #include "avcodec.h" +#include "dsputil.h" #include "libavutil/common.h" -#include "celp_math.h" #include "celp_filters.h" #include "acelp_filters.h" #include "acelp_vectors.h" @@ -784,8 +784,8 @@ static int synthesis(AMRContext *p, float *lpc, // emphasize pitch vector contribution if (p->pitch_gain[4] > 0.5 && !overflow) { - float energy = ff_dot_productf(excitation, excitation, - AMR_SUBFRAME_SIZE); + float energy = ff_scalarproduct_float_c(excitation, excitation, + AMR_SUBFRAME_SIZE); float pitch_factor = p->pitch_gain[4] * (p->cur_frame_mode == MODE_12k2 ? @@ -861,8 +861,8 @@ static float tilt_factor(float *lpc_n, float *lpc_d) ff_celp_lp_synthesis_filterf(hf, lpc_d, hf, AMR_TILT_RESPONSE, LP_FILTER_ORDER); - rh0 = ff_dot_productf(hf, hf, AMR_TILT_RESPONSE); - rh1 = ff_dot_productf(hf, hf + 1, AMR_TILT_RESPONSE - 1); + rh0 = ff_scalarproduct_float_c(hf, hf, AMR_TILT_RESPONSE); + rh1 = ff_scalarproduct_float_c(hf, hf + 1, AMR_TILT_RESPONSE - 1); // The spec only specifies this check for 12.2 and 10.2 kbit/s // modes. But in the ref source the tilt is always non-negative. @@ -882,8 +882,8 @@ static void postfilter(AMRContext *p, float *lpc, float *buf_out) int i; float *samples = p->samples_in + LP_FILTER_ORDER; // Start of input - float speech_gain = ff_dot_productf(samples, samples, - AMR_SUBFRAME_SIZE); + float speech_gain = ff_scalarproduct_float_c(samples, samples, + AMR_SUBFRAME_SIZE); float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER]; // Output of pole filter const float *gamma_n, *gamma_d; // Formant filter factor table @@ -988,8 +988,10 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, p->fixed_gain[4] = ff_amr_set_fixed_gain(fixed_gain_factor, - ff_dot_productf(p->fixed_vector, p->fixed_vector, - AMR_SUBFRAME_SIZE)/AMR_SUBFRAME_SIZE, + ff_scalarproduct_float_c(p->fixed_vector, + p->fixed_vector, + AMR_SUBFRAME_SIZE) / + AMR_SUBFRAME_SIZE, p->prediction_error, energy_mean[p->cur_frame_mode], energy_pred_fac); diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index a90a27abe1..18b34cff9b 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -28,8 +28,8 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "dsputil.h" #include "lsp.h" -#include "celp_math.h" #include "celp_filters.h" #include "acelp_filters.h" #include "acelp_vectors.h" @@ -585,10 +585,12 @@ static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector) static float voice_factor(float *p_vector, float p_gain, float *f_vector, float f_gain) { - double p_ener = (double) ff_dot_productf(p_vector, p_vector, - AMRWB_SFR_SIZE) * p_gain * p_gain; - double f_ener = (double) ff_dot_productf(f_vector, f_vector, - AMRWB_SFR_SIZE) * f_gain * f_gain; + double p_ener = (double) ff_scalarproduct_float_c(p_vector, p_vector, + AMRWB_SFR_SIZE) * + p_gain * p_gain; + double f_ener = (double) ff_scalarproduct_float_c(f_vector, f_vector, + AMRWB_SFR_SIZE) * + f_gain * f_gain; return (p_ener - f_ener) / (p_ener + f_ener); } @@ -756,8 +758,8 @@ static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation, /* emphasize pitch vector contribution in low bitrate modes */ if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) { int i; - float energy = ff_dot_productf(excitation, excitation, - AMRWB_SFR_SIZE); + float energy = ff_scalarproduct_float_c(excitation, excitation, + AMRWB_SFR_SIZE); // XXX: Weird part in both ref code and spec. A unknown parameter // {beta} seems to be identical to the current pitch gain @@ -816,8 +818,9 @@ static void upsample_5_4(float *out, const float *in, int o_size) i++; for (k = 1; k < 5; k++) { - out[i] = ff_dot_productf(in0 + int_part, upsample_fir[4 - frac_part], - UPS_MEM_SIZE); + out[i] = ff_scalarproduct_float_c(in0 + int_part, + upsample_fir[4 - frac_part], + UPS_MEM_SIZE); int_part++; frac_part--; i++; @@ -843,8 +846,8 @@ static float find_hb_gain(AMRWBContext *ctx, const float *synth, if (ctx->fr_cur_mode == MODE_23k85) return qua_hb_gain[hb_idx] * (1.0f / (1 << 14)); - tilt = ff_dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) / - ff_dot_productf(synth, synth, AMRWB_SFR_SIZE); + tilt = ff_scalarproduct_float_c(synth, synth + 1, AMRWB_SFR_SIZE - 1) / + ff_scalarproduct_float_c(synth, synth, AMRWB_SFR_SIZE); /* return gain bounded by [0.1, 1.0] */ return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0); @@ -863,7 +866,7 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc, const float *synth_exc, float hb_gain) { int i; - float energy = ff_dot_productf(synth_exc, synth_exc, AMRWB_SFR_SIZE); + float energy = ff_scalarproduct_float_c(synth_exc, synth_exc, AMRWB_SFR_SIZE); /* Generate a white-noise excitation */ for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) @@ -1156,8 +1159,10 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, ctx->fixed_gain[0] = ff_amr_set_fixed_gain(fixed_gain_factor, - ff_dot_productf(ctx->fixed_vector, ctx->fixed_vector, - AMRWB_SFR_SIZE) / AMRWB_SFR_SIZE, + ff_scalarproduct_float_c(ctx->fixed_vector, + ctx->fixed_vector, + AMRWB_SFR_SIZE) / + AMRWB_SFR_SIZE, ctx->prediction_error, ENERGY_MEAN, energy_pred_fac); diff --git a/libavcodec/celp_math.c b/libavcodec/celp_math.c index b28c51b52d..c3d12e982e 100644 --- a/libavcodec/celp_math.c +++ b/libavcodec/celp_math.c @@ -86,14 +86,3 @@ int ff_log2(uint32_t value) return (power_int << 15) + value; } - -float ff_dot_productf(const float* a, const float* b, int length) -{ - float sum = 0; - int i; - - for(i=0; iscalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c; c->apply_window_int16 = apply_window_int16_c; c->vector_clip_int32 = vector_clip_int32_c; - c->scalarproduct_float = scalarproduct_float_c; + c->scalarproduct_float = ff_scalarproduct_float_c; c->butterflies_float = butterflies_float_c; c->butterflies_float_interleave = butterflies_float_interleave_c; c->vector_fmul_scalar = vector_fmul_scalar_c; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index e1b7efc45b..e90c7cbd0f 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -549,6 +549,17 @@ void ff_dsputil_init(DSPContext* p, AVCodecContext *avctx); int ff_check_alignment(void); +/** + * Return the scalar product of two vectors. + * + * @param v1 first input vector + * @param v2 first input vector + * @param len number of elements + * + * @return sum of elementwise products + */ +float ff_scalarproduct_float_c(const float *v1, const float *v2, int len); + /** * permute block according to permuatation. * @param last last non zero element in scantable order diff --git a/libavcodec/lsp.c b/libavcodec/lsp.c index b501bfb7b8..8a05aede62 100644 --- a/libavcodec/lsp.c +++ b/libavcodec/lsp.c @@ -27,7 +27,6 @@ #define FRAC_BITS 14 #include "mathops.h" #include "lsp.h" -#include "celp_math.h" void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order) { diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index c598d6bf65..edb1d24603 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -32,10 +32,8 @@ #include "avcodec.h" #include "internal.h" #include "get_bits.h" - +#include "dsputil.h" #include "qcelpdata.h" - -#include "celp_math.h" #include "celp_filters.h" #include "acelp_filters.h" #include "acelp_vectors.h" @@ -401,8 +399,9 @@ static void apply_gain_ctrl(float *v_out, const float *v_ref, const float *v_in) for (i = 0; i < 160; i += 40) ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, - ff_dot_productf(v_ref + i, - v_ref + i, 40), + ff_scalarproduct_float_c(v_ref + i, + v_ref + i, + 40), 40); } @@ -678,8 +677,8 @@ static void postfilter(QCELPContext *q, float *samples, float *lpc) ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160); ff_adaptive_gain_control(samples, pole_out + 10, - ff_dot_productf(q->formant_mem + 10, - q->formant_mem + 10, 160), + ff_scalarproduct_float_c(q->formant_mem + 10, + q->formant_mem + 10, 160), 160, 0.9375, &q->postfilter_agc_mem); } diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index c13d0e633e..1d02c7bf41 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -25,7 +25,6 @@ #include "get_bits.h" #include "ra288.h" #include "lpc.h" -#include "celp_math.h" #include "celp_filters.h" #define MAX_BACKWARD_FILTER_ORDER 36 @@ -74,7 +73,7 @@ static av_cold int ra288_decode_init(AVCodecContext *avctx) static void convolve(float *tgt, const float *src, int len, int n) { for (; n >= 0; n--) - tgt[n] = ff_dot_productf(src, src - n, len); + tgt[n] = ff_scalarproduct_float_c(src, src - n, len); } @@ -103,7 +102,7 @@ static void decode(RA288Context *ractx, float gain, int cb_coef) for (i=0; i < 5; i++) buffer[i] = codetable[cb_coef][i] * sumsum; - sum = ff_dot_productf(buffer, buffer, 5) * ((1<<24)/5.); + sum = ff_scalarproduct_float_c(buffer, buffer, 5) * ((1 << 24) / 5.); sum = FFMAX(sum, 1); diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index a14b7c7151..971d05bde8 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -32,7 +32,6 @@ #include "dsputil.h" #include "lsp.h" -#include "celp_math.h" #include "acelp_vectors.h" #include "acelp_pitch_delay.h" #include "acelp_filters.h" @@ -411,7 +410,7 @@ static void decode_frame(SiprContext *ctx, SiprParameters *params, SUBFR_SIZE); avg_energy = - (0.01 + ff_dot_productf(fixed_vector, fixed_vector, SUBFR_SIZE))/ + (0.01 + ff_scalarproduct_float_c(fixed_vector, fixed_vector, SUBFR_SIZE)) / SUBFR_SIZE; ctx->past_pitch_gain = pitch_gain = gain_cb[params->gc_index[i]][0]; @@ -453,9 +452,9 @@ static void decode_frame(SiprContext *ctx, SiprParameters *params, if (ctx->mode == MODE_5k0) { for (i = 0; i < subframe_count; i++) { - float energy = ff_dot_productf(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i*SUBFR_SIZE, - ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i*SUBFR_SIZE, - SUBFR_SIZE); + float energy = ff_scalarproduct_float_c(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE, + ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE, + SUBFR_SIZE); ff_adaptive_gain_control(&synth[i * SUBFR_SIZE], &synth[i * SUBFR_SIZE], energy, SUBFR_SIZE, 0.9, &ctx->postfilter_agc); diff --git a/libavcodec/sipr16k.c b/libavcodec/sipr16k.c index bd0600c7b3..bff739e44f 100644 --- a/libavcodec/sipr16k.c +++ b/libavcodec/sipr16k.c @@ -26,8 +26,9 @@ #include "sipr.h" #include "libavutil/common.h" #include "libavutil/mathematics.h" +#include "dsputil.h" #include "lsp.h" -#include "celp_math.h" +#include "celp_filters.h" #include "acelp_vectors.h" #include "acelp_pitch_delay.h" #include "acelp_filters.h" @@ -163,10 +164,10 @@ static float acelp_decode_gain_codef(float gain_corr_factor, const float *fc_v, int subframe_size, int ma_pred_order) { mr_energy += - ff_dot_productf(quant_energy, ma_prediction_coeff, ma_pred_order); + ff_scalarproduct_float_c(quant_energy, ma_prediction_coeff, ma_pred_order); mr_energy = gain_corr_factor * exp(M_LN10 / 20. * mr_energy) / - sqrt((0.01 + ff_dot_productf(fc_v, fc_v, subframe_size))); + sqrt((0.01 + ff_scalarproduct_float_c(fc_v, fc_v, subframe_size))); return mr_energy; } diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index ca5bbeef05..4a7ba6dabc 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -28,11 +28,12 @@ #define UNCHECKED_BITSTREAM_READER 1 #include + +#include "dsputil.h" #include "avcodec.h" #include "get_bits.h" #include "put_bits.h" #include "wmavoice_data.h" -#include "celp_math.h" #include "celp_filters.h" #include "acelp_vectors.h" #include "acelp_filters.h" @@ -518,7 +519,7 @@ static int kalman_smoothen(WMAVoiceContext *s, int pitch, /* find best fitting point in history */ do { - dot = ff_dot_productf(in, ptr, size); + dot = ff_scalarproduct_float_c(in, ptr, size); if (dot > optimal_gain) { optimal_gain = dot; best_hist_ptr = ptr; @@ -527,7 +528,7 @@ static int kalman_smoothen(WMAVoiceContext *s, int pitch, if (optimal_gain <= 0) return -1; - dot = ff_dot_productf(best_hist_ptr, best_hist_ptr, size); + dot = ff_scalarproduct_float_c(best_hist_ptr, best_hist_ptr, size); if (dot <= 0) // would be 1.0 return -1; @@ -557,8 +558,8 @@ static float tilt_factor(const float *lpcs, int n_lpcs) { float rh0, rh1; - rh0 = 1.0 + ff_dot_productf(lpcs, lpcs, n_lpcs); - rh1 = lpcs[0] + ff_dot_productf(lpcs, &lpcs[1], n_lpcs - 1); + rh0 = 1.0 + ff_scalarproduct_float_c(lpcs, lpcs, n_lpcs); + rh1 = lpcs[0] + ff_scalarproduct_float_c(lpcs, &lpcs[1], n_lpcs - 1); return rh1 / rh0; } @@ -651,7 +652,7 @@ static void calc_input_response(WMAVoiceContext *s, float *lpcs, -1.8 * tilt_factor(coeffs, remainder - 1), coeffs, remainder); } - sq = (1.0 / 64.0) * sqrtf(1 / ff_dot_productf(coeffs, coeffs, remainder)); + sq = (1.0 / 64.0) * sqrtf(1 / ff_scalarproduct_float_c(coeffs, coeffs, remainder)); for (n = 0; n < remainder; n++) coeffs[n] *= sq; } @@ -1315,7 +1316,7 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, /* Calculate gain for adaptive & fixed codebook signal. * see ff_amr_set_fixed_gain(). */ idx = get_bits(gb, 7); - fcb_gain = expf(ff_dot_productf(s->gain_pred_err, gain_coeff, 6) - + fcb_gain = expf(ff_scalarproduct_float_c(s->gain_pred_err, gain_coeff, 6) - 5.2409161640 + wmavoice_gain_codebook_fcb[idx]); acb_gain = wmavoice_gain_codebook_acb[idx]; pred_err = av_clipf(wmavoice_gain_codebook_fcb[idx], From 3d868fe542e3f960f54d18c4baf87fc8e36c497c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 27 Aug 2012 21:05:52 +0200 Subject: [PATCH 10/15] build: Restore dependency of acelp_filters.o on celp_math.o --- libavcodec/Makefile | 6 +++--- libavcodec/acelp_pitch_delay.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index c022e16aa9..adbe1a3e55 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -84,11 +84,11 @@ OBJS-$(CONFIG_ALAC_DECODER) += alac.o OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o OBJS-$(CONFIG_ALS_DECODER) += alsdec.o bgmc.o mpeg4audio.o OBJS-$(CONFIG_AMRNB_DECODER) += amrnbdec.o celp_filters.o \ - acelp_filters.o \ + celp_math.o acelp_filters.o \ acelp_vectors.o \ acelp_pitch_delay.o OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \ - acelp_filters.o \ + celp_math.o acelp_filters.o \ acelp_vectors.o \ acelp_pitch_delay.o OBJS-$(CONFIG_AMV_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o @@ -332,7 +332,7 @@ OBJS-$(CONFIG_SGI_DECODER) += sgidec.o OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o OBJS-$(CONFIG_SHORTEN_DECODER) += shorten.o OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \ - acelp_vectors.o \ + celp_math.o acelp_vectors.o \ acelp_filters.o celp_filters.o \ sipr16k.o OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c index 1c8485047f..c091301474 100644 --- a/libavcodec/acelp_pitch_delay.c +++ b/libavcodec/acelp_pitch_delay.c @@ -25,6 +25,7 @@ #include "avcodec.h" #include "dsputil.h" #include "acelp_pitch_delay.h" +#include "celp_math.h" int ff_acelp_decode_8bit_to_1st_delay3(int ac_index) { From dbc9f84ea6723c3d73dc9ec2aebacabc99a8d949 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 25 Aug 2012 12:34:55 +0100 Subject: [PATCH 11/15] Revert "dsputil: make {add/put/put_signed}_pixels_clamped() non-static." This reverts commit 484a337cd7cd8bb180c4a1bd3321881f1c874a92. These functions were used in f8bed30 "VC1: merge idct8x8, coeff adjustments and put_pixels" which was reverted in 18b6a69. Signed-off-by: Mans Rullgard --- libavcodec/dsputil.c | 28 ++++++++++++++-------------- libavcodec/dsputil.h | 4 ---- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index e754ffe2f8..c78fe40c72 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -359,8 +359,8 @@ static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1, } -void ff_put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) +static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) { int i; @@ -380,9 +380,9 @@ void ff_put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, } } -void ff_put_signed_pixels_clamped_c(const DCTELEM *block, - uint8_t *restrict pixels, - int line_size) +static void put_signed_pixels_clamped_c(const DCTELEM *block, + uint8_t *restrict pixels, + int line_size) { int i, j; @@ -401,8 +401,8 @@ void ff_put_signed_pixels_clamped_c(const DCTELEM *block, } } -void ff_add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) +static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) { int i; @@ -2606,22 +2606,22 @@ void ff_wmv2_idct_c(short * block){ static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block) { ff_wmv2_idct_c(block); - ff_put_pixels_clamped_c(block, dest, line_size); + put_pixels_clamped_c(block, dest, line_size); } static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block) { ff_wmv2_idct_c(block); - ff_add_pixels_clamped_c(block, dest, line_size); + add_pixels_clamped_c(block, dest, line_size); } static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block) { ff_j_rev_dct (block); - ff_put_pixels_clamped_c(block, dest, line_size); + put_pixels_clamped_c(block, dest, line_size); } static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block) { ff_j_rev_dct (block); - ff_add_pixels_clamped_c(block, dest, line_size); + add_pixels_clamped_c(block, dest, line_size); } static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; } @@ -2720,9 +2720,9 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) } c->diff_pixels = diff_pixels_c; - c->put_pixels_clamped = ff_put_pixels_clamped_c; - c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_c; - c->add_pixels_clamped = ff_add_pixels_clamped_c; + c->put_pixels_clamped = put_pixels_clamped_c; + c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; + c->add_pixels_clamped = add_pixels_clamped_c; c->sum_abs_dctelem = sum_abs_dctelem_c; c->gmc1 = gmc1_c; c->gmc = ff_gmc_c; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index e90c7cbd0f..e818fb092f 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -197,10 +197,6 @@ EMULATED_EDGE(8) EMULATED_EDGE(9) EMULATED_EDGE(10) -void ff_add_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int linesize); -void ff_put_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int linesize); -void ff_put_signed_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int linesize); - /** * DSPContext. */ From 29b64b682766c9d08c72b5a6d8de69c905f32855 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 27 Aug 2012 22:04:25 +0100 Subject: [PATCH 12/15] configure: use LD_O setting in check_ld() Signed-off-by: Mans Rullgard --- configure | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 5a626b2a55..550524508d 100755 --- a/configure +++ b/configure @@ -678,6 +678,10 @@ check_yasm(){ check_cmd $yasmexe $YASMFLAGS "$@" -o $TMPO $TMPS } +ld_o(){ + eval printf '%s\\n' $LD_O +} + check_ld(){ log check_ld "$@" flags='' @@ -688,7 +692,7 @@ check_ld(){ check_cc $($cflags_filter $flags) || return flags=$($ldflags_filter $flags) libs=$($ldflags_filter $libs) - check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $libs $extralibs + check_cmd $ld $LDFLAGS $flags $(ld_o $TMPE) $TMPO $libs $extralibs } check_code(){ From df0d63413801830b2b920259d4cefc85af1a8de4 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 27 Aug 2012 22:19:06 +0100 Subject: [PATCH 13/15] configure: use AS_O setting in check_as Signed-off-by: Mans Rullgard --- configure | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 550524508d..6a338c057a 100755 --- a/configure +++ b/configure @@ -652,11 +652,15 @@ check_cpp(){ check_cmd $cc $CPPFLAGS $CFLAGS "$@" $(cc_e $TMPO) $TMPC } +as_o(){ + eval printf '%s\\n' $AS_O +} + check_as(){ log check_as "$@" cat > $TMPC log_file $TMPC - check_cmd $as $CPPFLAGS $ASFLAGS "$@" $AS_C -o $TMPO $TMPC + check_cmd $as $CPPFLAGS $ASFLAGS "$@" $AS_C $(as_o $TMPO) $TMPC } check_inline_asm(){ From ae43c4c0c09fee63bc7ec9385b3fd381be7ba1d5 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 27 Aug 2012 22:19:42 +0100 Subject: [PATCH 14/15] configure: use HOSTCC_C/O in check_host_cc Signed-off-by: Mans Rullgard --- configure | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 6a338c057a..5bada007c0 100755 --- a/configure +++ b/configure @@ -906,11 +906,15 @@ require_pkg_config(){ add_extralibs $(get_safe ${pkg}_libs) } +hostcc_o(){ + eval printf '%s\\n' $HOSTCC_O +} + check_host_cc(){ log check_host_cc "$@" cat > $TMPC log_file $TMPC - check_cmd $host_cc $host_cflags "$@" -c -o $TMPO $TMPC + check_cmd $host_cc $host_cflags "$@" $HOSTCC_C $(hostcc_o $TMPO) $TMPC } check_host_cflags(){ From 7627c35a81241c98768d2d1f13d576591cac0b1c Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Mon, 27 Aug 2012 19:21:00 +0200 Subject: [PATCH 15/15] vc1: export some functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a preparatory step for the MSS2 decoder which needs to use the WMV9 decoder to decode some kinds of frames. From the patch by Alberto Delmás --- libavcodec/vc1.h | 5 +++++ libavcodec/vc1dec.c | 51 +++++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 5806b80f2f..fe21f2f6b7 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -451,4 +451,9 @@ int ff_vc1_parse_frame_header (VC1Context *v, GetBitContext *gb); int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb); int ff_vc1_init_common(VC1Context *v); +av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v); +av_cold void ff_vc1_init_transposed_scantables(VC1Context *v); +av_cold int ff_vc1_decode_end(AVCodecContext *avctx); +void ff_vc1_decode_blocks(VC1Context *v); + #endif /* AVCODEC_VC1_H */ diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 7b0b8c9207..63c0949ccd 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -4732,7 +4732,7 @@ static void vc1_decode_skip_blocks(VC1Context *v) s->pict_type = AV_PICTURE_TYPE_P; } -static void vc1_decode_blocks(VC1Context *v) +void ff_vc1_decode_blocks(VC1Context *v) { v->s.esc3_level_length = 0; @@ -5046,7 +5046,7 @@ static void vc1_sprite_flush(AVCodecContext *avctx) #endif -static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) +av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) { MpegEncContext *s = &v->s; int i; @@ -5112,6 +5112,21 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) return 0; } +av_cold void ff_vc1_init_transposed_scantables(VC1Context *v) +{ + int i; + for (i = 0; i < 64; i++) { +#define transpose(x) ((x >> 3) | ((x & 7) << 3)) + v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]); + v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]); + v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]); + v->zz_8x8[3][i] = transpose(ff_wmv1_scantable[3][i]); + v->zzi_8x8[i] = transpose(ff_vc1_adv_interlaced_8x8_zz[i]); + } + v->left_blk_sh = 0; + v->top_blk_sh = 3; +} + /** Initialize a VC1/WMV3 decoder * @todo TODO: Handle VC-1 IDUs (Transport level?) * @todo TODO: Decypher remaining bits in extra_data @@ -5121,7 +5136,6 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; GetBitContext gb; - int i; /* save the container output size for WMImage */ v->output_width = avctx->width; @@ -5224,16 +5238,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) s->mb_height = (avctx->coded_height + 15) >> 4; if (v->profile == PROFILE_ADVANCED || v->res_fasttx) { - for (i = 0; i < 64; i++) { -#define transpose(x) ((x >> 3) | ((x & 7) << 3)) - v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]); - v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]); - v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]); - v->zz_8x8[3][i] = transpose(ff_wmv1_scantable[3][i]); - v->zzi_8x8[i] = transpose(ff_vc1_adv_interlaced_8x8_zz[i]); - } - v->left_blk_sh = 0; - v->top_blk_sh = 3; + ff_vc1_init_transposed_scantables(v); } else { memcpy(v->zz_8x8, ff_wmv1_scantable, 4*64); v->left_blk_sh = 3; @@ -5259,7 +5264,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) /** Close a VC1/WMV3 decoder * @warning Initial try at using MpegEncContext stuff */ -static av_cold int vc1_decode_end(AVCodecContext *avctx) +av_cold int ff_vc1_decode_end(AVCodecContext *avctx) { VC1Context *v = avctx->priv_data; int i; @@ -5448,11 +5453,11 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (s->context_initialized && (s->width != avctx->coded_width || s->height != avctx->coded_height)) { - vc1_decode_end(avctx); + ff_vc1_decode_end(avctx); } if (!s->context_initialized) { - if (ff_msmpeg4_decode_init(avctx) < 0 || vc1_decode_init_alloc_tables(v) < 0) + if (ff_msmpeg4_decode_init(avctx) < 0 || ff_vc1_decode_init_alloc_tables(v) < 0) return -1; s->low_delay = !avctx->has_b_frames || v->res_sprite; @@ -5597,7 +5602,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); else s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); - vc1_decode_blocks(v); + ff_vc1_decode_blocks(v); if (i != n_slices) s->gb = slices[i].gb; } @@ -5675,7 +5680,7 @@ AVCodec ff_vc1_decoder = { .id = AV_CODEC_ID_VC1, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), @@ -5690,7 +5695,7 @@ AVCodec ff_wmv3_decoder = { .id = AV_CODEC_ID_WMV3, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), @@ -5706,7 +5711,7 @@ AVCodec ff_wmv3_vdpau_decoder = { .id = AV_CODEC_ID_WMV3, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"), @@ -5722,7 +5727,7 @@ AVCodec ff_vc1_vdpau_decoder = { .id = AV_CODEC_ID_VC1, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"), @@ -5738,7 +5743,7 @@ AVCodec ff_wmv3image_decoder = { .id = AV_CODEC_ID_WMV3IMAGE, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1, .flush = vc1_sprite_flush, @@ -5754,7 +5759,7 @@ AVCodec ff_vc1image_decoder = { .id = AV_CODEC_ID_VC1IMAGE, .priv_data_size = sizeof(VC1Context), .init = vc1_decode_init, - .close = vc1_decode_end, + .close = ff_vc1_decode_end, .decode = vc1_decode_frame, .capabilities = CODEC_CAP_DR1, .flush = vc1_sprite_flush,