Merge remote-tracking branch 'qatar/master'
* qatar/master: vc1: export some functions configure: use HOSTCC_C/O in check_host_cc configure: use AS_O setting in check_as configure: use LD_O setting in check_ld() Revert "dsputil: make {add/put/put_signed}_pixels_clamped() non-static." build: Restore dependency of acelp_filters.o on celp_math.o celp_math: Replace duplicate ff_dot_productf() by ff_scalarproduct_c() celp_math: Move ff_cos() to the only place it is used build: Use portable abstraction for linker/hostcc output file syntax configure: Fix shared library creation for OpenBSD vp56: Don't use DECLARE_ALIGN on a typedef name mss1: move code that will be reused by MSS2 decoder into separate file mss1: merge decode_intra() and decode_inter() avprobe: Get rid of ugly casts in the options table vf_hqdn3d: Remove a duplicate inline declaration Conflicts: Makefile configure ffprobe.c libavcodec/Makefile libavcodec/amrnbdec.c libavcodec/amrwbdec.c libavcodec/celp_math.c libavcodec/celp_math.h libavcodec/dsputil.c libavcodec/lsp.c libavcodec/mss1.c libavcodec/ra288.c libavcodec/vc1dec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
416d2f7a12
4
Makefile
4
Makefile
@ -57,7 +57,7 @@ $(PROGS): %$(EXESUF): %_g$(EXESUF)
|
||||
$(STRIP) $@
|
||||
|
||||
$(TOOLS): %$(EXESUF): %.o
|
||||
$(LD) $(LDFLAGS) -o $@ $< $(ELIBS)
|
||||
$(LD) $(LDFLAGS) $(LD_O) $< $(ELIBS)
|
||||
|
||||
tools/cws2fws$(EXESUF): ELIBS = -lz
|
||||
|
||||
@ -102,7 +102,7 @@ endef
|
||||
$(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P))))
|
||||
|
||||
%$(PROGSSUF)_g$(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
|
||||
|
||||
|
@ -109,7 +109,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)))
|
||||
|
19
configure
vendored
19
configure
vendored
@ -709,11 +709,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(){
|
||||
@ -735,6 +739,10 @@ check_yasm(){
|
||||
check_cmd $yasmexe $YASMFLAGS "$@" -o $TMPO $TMPS
|
||||
}
|
||||
|
||||
ld_o(){
|
||||
eval printf '%s\\n' $LD_O
|
||||
}
|
||||
|
||||
check_ld(){
|
||||
log check_ld "$@"
|
||||
type=$1
|
||||
@ -747,7 +755,7 @@ check_ld(){
|
||||
check_$type $($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(){
|
||||
@ -1004,11 +1012,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(){
|
||||
@ -2887,6 +2899,7 @@ case $target_os in
|
||||
disable symver
|
||||
SHFLAGS='-shared'
|
||||
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBVERSION)'
|
||||
SLIB_INSTALL_LINKS=
|
||||
oss_indev_extralibs="-lossaudio"
|
||||
oss_outdev_extralibs="-lossaudio"
|
||||
;;
|
||||
|
22
ffprobe.c
22
ffprobe.c
@ -2100,26 +2100,26 @@ static int opt_show_versions(const char *opt, const char *arg)
|
||||
|
||||
static const OptionDef real_options[] = {
|
||||
#include "cmdutils_common_opts.h"
|
||||
{ "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
|
||||
{ "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" },
|
||||
{ "prefix", OPT_BOOL, {(void*)&use_value_prefix}, "use SI prefixes for the displayed values" },
|
||||
{ "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix},
|
||||
{ "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
|
||||
{ "unit", OPT_BOOL, {&show_value_unit}, "show unit of the displayed values" },
|
||||
{ "prefix", OPT_BOOL, {&use_value_prefix}, "use SI prefixes for the displayed values" },
|
||||
{ "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" },
|
||||
{ "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format},
|
||||
"set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
|
||||
{ "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" },
|
||||
{ "show_data", OPT_BOOL, {(void*)&do_show_data}, "show packets data" },
|
||||
{ "show_error", OPT_BOOL, {(void*)&do_show_error} , "show probing error" },
|
||||
{ "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
|
||||
{ "show_format", OPT_BOOL, {&do_show_format} , "show format/container info" },
|
||||
{ "show_frames", OPT_BOOL, {(void*)&do_show_frames} , "show frames info" },
|
||||
{ "show_format_entry", HAS_ARG, {(void*)opt_show_format_entry},
|
||||
{ "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" },
|
||||
{ "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" },
|
||||
{ "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" },
|
||||
{ "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" },
|
||||
{ "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" },
|
||||
{ "show_program_version", OPT_BOOL, {(void*)&do_show_program_version}, "show ffprobe version" },
|
||||
@ -2127,7 +2127,7 @@ static const OptionDef real_options[] = {
|
||||
{ "show_versions", 0, {(void*)&opt_show_versions}, "show program and library versions" },
|
||||
{ "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" },
|
||||
{ "private", OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" },
|
||||
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
|
||||
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
|
||||
{ "i", HAS_ARG, {(void *)opt_input_file}, "read specified file", "input_file"},
|
||||
{ NULL, },
|
||||
};
|
||||
|
@ -194,7 +194,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_G723_1_ENCODER) += g723_1.o acelp_vectors.o celp_math.o
|
||||
OBJS-$(CONFIG_G729_DECODER) += g729dec.o lsp.o celp_math.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
|
||||
OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o
|
||||
@ -307,7 +307,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_MSVIDEO1_ENCODER) += msvideo1enc.o elbg.o
|
||||
OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o
|
||||
@ -341,7 +341,7 @@ OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_ANATOLIY_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_KOSTYA_ENCODER) += proresenc_kostya.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
|
||||
@ -356,7 +356,7 @@ OBJS-$(CONFIG_R210_ENCODER) += r210enc.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
|
||||
@ -423,7 +423,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
|
||||
@ -468,7 +468,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 \
|
||||
|
@ -131,7 +131,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);
|
||||
|
||||
|
@ -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] =
|
||||
{
|
||||
@ -203,7 +203,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;
|
||||
|
||||
@ -224,7 +224,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++)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "celp_math.h"
|
||||
@ -798,7 +799,7 @@ static int synthesis(AMRContext *p, float *lpc,
|
||||
// emphasize pitch vector contribution
|
||||
if (p->pitch_gain[4] > 0.5 && !overflow) {
|
||||
float energy = p->celpm_ctx.dot_productf(excitation, excitation,
|
||||
AMR_SUBFRAME_SIZE);
|
||||
AMR_SUBFRAME_SIZE);
|
||||
float pitch_factor =
|
||||
p->pitch_gain[4] *
|
||||
(p->cur_frame_mode == MODE_12k2 ?
|
||||
@ -899,7 +900,7 @@ static void postfilter(AMRContext *p, float *lpc, float *buf_out)
|
||||
float *samples = p->samples_in + LP_FILTER_ORDER; // Start of input
|
||||
|
||||
float speech_gain = p->celpm_ctx.dot_productf(samples, samples,
|
||||
AMR_SUBFRAME_SIZE);
|
||||
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
|
||||
@ -1005,8 +1006,10 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
p->fixed_gain[4] =
|
||||
ff_amr_set_fixed_gain(fixed_gain_factor,
|
||||
p->celpm_ctx.dot_productf(p->fixed_vector, p->fixed_vector,
|
||||
AMR_SUBFRAME_SIZE)/AMR_SUBFRAME_SIZE,
|
||||
p->celpm_ctx.dot_productf(p->fixed_vector,
|
||||
p->fixed_vector,
|
||||
AMR_SUBFRAME_SIZE) /
|
||||
AMR_SUBFRAME_SIZE,
|
||||
p->prediction_error,
|
||||
energy_mean[p->cur_frame_mode], energy_pred_fac);
|
||||
|
||||
|
@ -28,9 +28,10 @@
|
||||
#include "libavutil/lfg.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "lsp.h"
|
||||
#include "celp_math.h"
|
||||
#include "celp_filters.h"
|
||||
#include "celp_math.h"
|
||||
#include "acelp_filters.h"
|
||||
#include "acelp_vectors.h"
|
||||
#include "acelp_pitch_delay.h"
|
||||
@ -600,9 +601,11 @@ static float voice_factor(float *p_vector, float p_gain,
|
||||
CELPMContext *ctx)
|
||||
{
|
||||
double p_ener = (double) ctx->dot_productf(p_vector, p_vector,
|
||||
AMRWB_SFR_SIZE) * p_gain * p_gain;
|
||||
AMRWB_SFR_SIZE) *
|
||||
p_gain * p_gain;
|
||||
double f_ener = (double) ctx->dot_productf(f_vector, f_vector,
|
||||
AMRWB_SFR_SIZE) * f_gain * f_gain;
|
||||
AMRWB_SFR_SIZE) *
|
||||
f_gain * f_gain;
|
||||
|
||||
return (p_ener - f_ener) / (p_ener + f_ener);
|
||||
}
|
||||
@ -771,7 +774,7 @@ static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation,
|
||||
if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
|
||||
int i;
|
||||
float energy = ctx->celpm_ctx.dot_productf(excitation, excitation,
|
||||
AMRWB_SFR_SIZE);
|
||||
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
|
||||
@ -832,8 +835,8 @@ static void upsample_5_4(float *out, const float *in, int o_size, CELPMContext *
|
||||
|
||||
for (k = 1; k < 5; k++) {
|
||||
out[i] = ctx->dot_productf(in0 + int_part,
|
||||
upsample_fir[4 - frac_part],
|
||||
UPS_MEM_SIZE);
|
||||
upsample_fir[4 - frac_part],
|
||||
UPS_MEM_SIZE);
|
||||
int_part++;
|
||||
frac_part--;
|
||||
i++;
|
||||
@ -1175,8 +1178,10 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
ctx->fixed_gain[0] =
|
||||
ff_amr_set_fixed_gain(fixed_gain_factor,
|
||||
ctx->celpm_ctx.dot_productf(ctx->fixed_vector, ctx->fixed_vector,
|
||||
AMRWB_SFR_SIZE) / AMRWB_SFR_SIZE,
|
||||
ctx->celpm_ctx.dot_productf(ctx->fixed_vector,
|
||||
ctx->fixed_vector,
|
||||
AMRWB_SFR_SIZE) /
|
||||
AMRWB_SFR_SIZE,
|
||||
ctx->prediction_error,
|
||||
ENERGY_MEAN, energy_pred_fac);
|
||||
|
||||
|
@ -29,97 +29,6 @@
|
||||
#include "celp_math.h"
|
||||
#include "libavutil/common.h"
|
||||
|
||||
#ifdef G729_BITEXACT
|
||||
/**
|
||||
* Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64)
|
||||
*/
|
||||
static const int16_t base_cos[64] =
|
||||
{
|
||||
32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
|
||||
30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
|
||||
23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
|
||||
12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
|
||||
0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
|
||||
-12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
|
||||
-23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
|
||||
-30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729
|
||||
};
|
||||
|
||||
/**
|
||||
* Slope used to compute cos(x)
|
||||
*
|
||||
* cos(ind*64+offset) = base_cos[ind]+offset*slope_cos[ind]
|
||||
* values multiplied by 1<<19
|
||||
*/
|
||||
static const int16_t slope_cos[64] =
|
||||
{
|
||||
-632, -1893, -3150, -4399, -5638, -6863, -8072, -9261,
|
||||
-10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744,
|
||||
-18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526,
|
||||
-24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726,
|
||||
-25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009,
|
||||
-23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637,
|
||||
-17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428,
|
||||
-9261, -8072, -6863, -5638, -4399, -3150, -1893, -632
|
||||
};
|
||||
|
||||
/**
|
||||
* Table used to compute exp2(x)
|
||||
*
|
||||
* tab_exp2[i] = (1<<14) * exp2(i/32) = 2^(i/32) i=0..32
|
||||
*/
|
||||
static const uint16_t tab_exp2[33] =
|
||||
{
|
||||
16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
|
||||
20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
|
||||
25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
|
||||
31379, 32066, 32767
|
||||
};
|
||||
|
||||
int16_t ff_cos(uint16_t arg)
|
||||
{
|
||||
uint8_t offset= arg;
|
||||
uint8_t ind = arg >> 8;
|
||||
|
||||
av_assert2(arg < 0x4000);
|
||||
|
||||
return FFMAX(base_cos[ind] + ((slope_cos[ind] * offset) >> 12), -0x8000);
|
||||
}
|
||||
|
||||
int ff_exp2(uint16_t power)
|
||||
{
|
||||
uint16_t frac_x0;
|
||||
uint16_t frac_dx;
|
||||
int result;
|
||||
|
||||
av_assert2(power <= 0x7fff);
|
||||
|
||||
frac_x0 = power >> 10;
|
||||
frac_dx = (power & 0x03ff) << 5;
|
||||
|
||||
result = tab_exp2[frac_x0] << 15;
|
||||
result += frac_dx * (tab_exp2[frac_x0+1] - tab_exp2[frac_x0]);
|
||||
|
||||
return result >> 10;
|
||||
}
|
||||
|
||||
#else // G729_BITEXACT
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -136,16 +45,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;
|
||||
|
||||
av_assert2(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;
|
||||
@ -156,8 +55,6 @@ int ff_exp2(uint16_t power)
|
||||
return result + ((result*(power&31)*89)>>22);
|
||||
}
|
||||
|
||||
#endif // else G729_BITEXACT
|
||||
|
||||
/**
|
||||
* Table used to compute log2(x)
|
||||
*
|
||||
|
@ -44,14 +44,6 @@ typedef struct CELPMContext {
|
||||
void ff_celp_math_init(CELPMContext *c);
|
||||
void ff_celp_math_init_mips(CELPMContext *c);
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -374,8 +374,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;
|
||||
|
||||
@ -427,9 +427,9 @@ static void put_pixels_clamped2_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;
|
||||
|
||||
@ -448,8 +448,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;
|
||||
|
||||
@ -2546,7 +2546,7 @@ static void butterflies_float_interleave_c(float *dst, const float *src0,
|
||||
}
|
||||
}
|
||||
|
||||
static float scalarproduct_float_c(const float *v1, const float *v2, int len)
|
||||
float ff_scalarproduct_float_c(const float *v1, const float *v2, int len)
|
||||
{
|
||||
float p = 0.0;
|
||||
int i;
|
||||
@ -2728,22 +2728,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 ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *block)
|
||||
@ -2890,9 +2890,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;
|
||||
@ -3047,7 +3047,7 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
|
||||
c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;
|
||||
c->apply_window_int16 = apply_window_int16_c;
|
||||
c->vector_clip_int32 = vector_clip_int32_c;
|
||||
c->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;
|
||||
|
@ -206,10 +206,6 @@ EMULATED_EDGE(10)
|
||||
EMULATED_EDGE(12)
|
||||
EMULATED_EDGE(14)
|
||||
|
||||
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.
|
||||
*/
|
||||
@ -560,6 +556,17 @@ attribute_deprecated void dsputil_init(DSPContext* c, 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
|
||||
|
@ -27,11 +27,9 @@
|
||||
#define FRAC_BITS 14
|
||||
#include "mathops.h"
|
||||
#include "lsp.h"
|
||||
#include "celp_math.h"
|
||||
#include "libavcodec/mips/lsp_mips.h"
|
||||
#include "libavutil/avassert.h"
|
||||
|
||||
|
||||
void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order)
|
||||
{
|
||||
int i, j;
|
||||
@ -58,6 +56,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;
|
||||
|
@ -27,73 +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;
|
||||
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 (;;) {
|
||||
@ -178,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;
|
||||
@ -267,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);
|
||||
@ -560,154 +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 ((unsigned)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_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)
|
||||
{
|
||||
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_inter(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_inter(ctx, acoder, x, y, width, pivot))
|
||||
return -1;
|
||||
if (decode_inter(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))
|
||||
return -1;
|
||||
if (decode_inter(ctx, acoder, x + pivot, y, width - pivot, height))
|
||||
return -1;
|
||||
break;
|
||||
case SPLIT_NONE:
|
||||
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)
|
||||
{
|
||||
@ -730,26 +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];
|
||||
if (!arith_get_bit(&acoder)) {
|
||||
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->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)
|
||||
if (c->ctx.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;
|
||||
}
|
||||
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);
|
||||
@ -762,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] = 0xFF << 24 | 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)
|
||||
@ -833,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;
|
||||
}
|
||||
|
581
libavcodec/mss12.c
Normal file
581
libavcodec/mss12.c
Normal file
@ -0,0 +1,581 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
* 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 ((unsigned)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] = 0xFF << 24 | 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;
|
||||
}
|
83
libavcodec/mss12.h
Normal file
83
libavcodec/mss12.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
* 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 */
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
sum = ff_scalarproduct_float_c(buffer, buffer, 5);
|
||||
|
||||
sum = FFMAX(sum, 5. / (1<<24));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -452,4 +452,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 */
|
||||
|
@ -4734,7 +4734,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;
|
||||
@ -5048,7 +5048,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;
|
||||
@ -5114,6 +5114,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
|
||||
@ -5123,7 +5138,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;
|
||||
@ -5226,16 +5240,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;
|
||||
@ -5261,7 +5266,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;
|
||||
@ -5453,11 +5458,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;
|
||||
@ -5612,7 +5617,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y);
|
||||
continue;
|
||||
}
|
||||
vc1_decode_blocks(v);
|
||||
ff_vc1_decode_blocks(v);
|
||||
if (i != n_slices)
|
||||
s->gb = slices[i].gb;
|
||||
}
|
||||
@ -5693,7 +5698,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"),
|
||||
@ -5708,7 +5713,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"),
|
||||
@ -5724,7 +5729,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"),
|
||||
@ -5740,7 +5745,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"),
|
||||
@ -5756,7 +5761,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,
|
||||
@ -5772,7 +5777,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,
|
||||
|
@ -28,11 +28,12 @@
|
||||
#define UNCHECKED_BITSTREAM_READER 1
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#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],
|
||||
|
@ -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
|
||||
$(SLIB_CREATE_DEF_CMD)
|
||||
$$(LD) $(SHFLAGS) $(LDFLAGS) -o $$@ $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS)
|
||||
$$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS)
|
||||
$(SLIB_EXTRA_CMD)
|
||||
|
||||
ifdef SUBDIR
|
||||
|
Loading…
Reference in New Issue
Block a user