This provides a public sustainable API/ABI for DSP functions. Only externally used dsp functions are included. The structure is extensible without ABI issues compared to the existing dsp contexts.
Signed-off-by: Michael Niedermayer <michae...@gmx.at> --- libavcodec/Makefile | 1 + libavcodec/avdsp.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/avdsp.h | 91 +++++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 libavcodec/avdsp.c create mode 100644 libavcodec/avdsp.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index c3e4f5d..c769065 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -15,6 +15,7 @@ HEADERS = avcodec.h \ OBJS = allcodecs.o \ audioconvert.o \ + avdsp.o \ avpacket.o \ avpicture.o \ bitstream.o \ diff --git a/libavcodec/avdsp.c b/libavcodec/avdsp.c new file mode 100644 index 0000000..4362177 --- /dev/null +++ b/libavcodec/avdsp.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014 Michael Niedermayer <michae...@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "me_cmp.h" +#include "idctdsp.h" +#include "fdctdsp.h" +#include "pixblockdsp.h" +#include "avdsp.h" + +#define OFFSET(x) offsetof(AVDSP,x) +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +static const AVOption avdsp_options[] = { +{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"}, +{"auto", "autoselect a good one (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"}, +{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"}, + +{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_SH4 +{"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_ALPHA +{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, +{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{NULL}, +}; + +static const AVClass avdsp_class = { + .class_name = "AVDSP", + .option = avdsp_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVDSP *avcodec_dsp_alloc(void) +{ + AVDSP *dsp = av_mallocz(sizeof(AVDSP)); + + if (!dsp) + return NULL; + + dsp->av_class = &avdsp_class; + av_opt_set_defaults(dsp); + + return dsp; +} + +int avcodec_dsp_init(AVDSP *dsp) +{ + AVCodecContext *avctx = avcodec_alloc_context3(NULL); + + if (!avctx) + return AVERROR(ENOMEM); + + avctx->idct_algo = dsp->idct_algo; + avctx->dct_algo = dsp->dct_algo; + +#define COPY(src, name) memcpy(&dsp->name, &src.name, sizeof(dsp->name)) + +#if CONFIG_IDCTDSP + { + IDCTDSPContext idsp; + ff_idctdsp_init(&idsp, avctx); + COPY(idsp, idct); + COPY(idsp, idct_permutation); + } +#endif + +#if CONFIG_FDCTDSP + { + FDCTDSPContext fdsp; + ff_fdctdsp_init(&fdsp, avctx); + COPY(fdsp, fdct); + } +#endif + +#if CONFIG_PIXBLOCKDSP + { + PixblockDSPContext pdsp; + ff_pixblockdsp_init(&pdsp, avctx); + COPY(pdsp, get_pixels); + COPY(pdsp, diff_pixels); + } +#endif + +#if CONFIG_ME_CMP + { + MECmpContext mecc; + ff_me_cmp_init(&mecc, avctx); + COPY(mecc, sum_abs_dctelem); + COPY(mecc, sad); + } +#endif + + avcodec_close(avctx); + av_free(avctx); + + return 0; +} \ No newline at end of file diff --git a/libavcodec/avdsp.h b/libavcodec/avdsp.h new file mode 100644 index 0000000..bf900c7 --- /dev/null +++ b/libavcodec/avdsp.h @@ -0,0 +1,91 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVDSP_H +#define AVCODEC_AVDSP_H + +#include "libavutil/opt.h" + +typedef int (*av_me_cmp_func)(void *c, + uint8_t *blk1 /* align width (8 or 16) */, + uint8_t *blk2 /* align 1 */, int line_size, int h); + +/** + * AVDSP context. + * @note function pointers can be NULL if the specific features have been + * disabled at build time. + */ +typedef struct AVDSP { + const AVClass *av_class; + + int (*sum_abs_dctelem)(int16_t *block /* align 16 */); + + av_me_cmp_func sad[6]; + + void (*idct)(int16_t *block /* align 16 */); + + /** + * IDCT input permutation. + * Several optimized IDCTs need a permutated input (relative to the + * normal order of the reference IDCT). + * This permutation must be performed before the idct_put/add. + * Note, normally this can be merged with the zigzag/alternate scan<br> + * An example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) + * - (x -> reference DCT -> reference IDCT -> x) + * - (x -> reference DCT -> simple_mmx_perm = idct_permutation + * -> simple_idct_mmx -> x) + * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant + * -> simple_idct_mmx -> ...) + */ + uint8_t idct_permutation[64]; + + void (*fdct)(int16_t *block /* align 16 */); + + void (*get_pixels)(int16_t *block /* align 16 */, + const uint8_t *pixels /* align 8 */, + int line_size); + void (*diff_pixels)(int16_t *block /* align 16 */, + const uint8_t *s1 /* align 8 */, + const uint8_t *s2 /* align 8 */, + int stride); + + /** + * DCT algorithm. + * must use AVOptions to set this field. + */ + int dct_algo; + + /** + * IDCT algorithm. + * must use AVOptions to set this field. + */ + int idct_algo; +} AVDSP; + +/** + * Allocates a AVDSP context. + * This needs to be initialized with avcodec_dsp_init() after optionally + * configuring it with AVOptions. + * + * To free it use av_free() + */ +AVDSP *avcodec_dsp_alloc(void); +int avcodec_dsp_init(AVDSP *); + +#endif /* AVCODEC_AVDSP_H */ \ No newline at end of file -- 1.7.9.5 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel