diff --git a/libavcodec/texturedsp.c b/libavcodec/texturedsp.c index b7dd8baa12..b8938213ef 100644 --- a/libavcodec/texturedsp.c +++ b/libavcodec/texturedsp.c @@ -652,3 +652,7 @@ av_cold void ff_texturedsp_init(TextureDSPContext *c) c->rgtc2u_block = rgtc2u_block; c->dxn3dc_block = dxn3dc_block; } + +#define TEXTUREDSP_FUNC_NAME ff_texturedsp_decompress_thread +#define TEXTUREDSP_TEX_FUNC(a, b, c) tex_funct(a, b, c) +#include "texturedsp_template.c" diff --git a/libavcodec/texturedsp.h b/libavcodec/texturedsp.h index 90ceb2b6aa..e15d3c2b02 100644 --- a/libavcodec/texturedsp.h +++ b/libavcodec/texturedsp.h @@ -39,6 +39,8 @@ #include #include +#include "avcodec.h" + #define TEXTURE_BLOCK_W 4 #define TEXTURE_BLOCK_H 4 @@ -60,7 +62,28 @@ typedef struct TextureDSPContext { int (*dxn3dc_block) (uint8_t *dst, ptrdiff_t stride, const uint8_t *block); } TextureDSPContext; +typedef struct TextureDSPThreadContext { + union { + const uint8_t *in; // Input frame data + uint8_t *out; // Output frame data + } frame_data; + ptrdiff_t stride; // Frame linesize + union { + const uint8_t *in; // Compressed texture for decompression + uint8_t *out; // Compressed texture of compression + } tex_data; + int tex_ratio; // Number of compressed bytes in a texture block + int raw_ratio; // Number bytes in a line of a raw block + int slice_count; // Number of slices for threaded operations + + /* Pointer to the selected compress or decompress function. */ + int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block); +} TextureDSPThreadContext; + void ff_texturedsp_init(TextureDSPContext *c); void ff_texturedspenc_init(TextureDSPContext *c); +int ff_texturedsp_decompress_thread(AVCodecContext *avctx, void *arg, int slice, int thread_nb); +int ff_texturedsp_compress_thread(AVCodecContext *avctx, void *arg, int slice, int thread_nb); + #endif /* AVCODEC_TEXTUREDSP_H */ diff --git a/libavcodec/texturedsp_template.c b/libavcodec/texturedsp_template.c new file mode 100644 index 0000000000..bd193aa97c --- /dev/null +++ b/libavcodec/texturedsp_template.c @@ -0,0 +1,57 @@ +/* + * Texture block compression and decompression + * Copyright (C) 2015 Vittorio Giovara + * + * 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 + * + */ + +int TEXTUREDSP_FUNC_NAME(AVCodecContext *avctx, void *arg, + int slice, int thread_nb) +{ + TextureDSPThreadContext *ctx = arg; + uint8_t *d = ctx->tex_data.out; + int w_block = avctx->coded_width / TEXTURE_BLOCK_W; + int h_block = avctx->coded_height / TEXTURE_BLOCK_H; + int x, y; + int start_slice, end_slice; + int base_blocks_per_slice = h_block / ctx->slice_count; + int remainder_blocks = h_block % ctx->slice_count; + + /* When the frame height (in blocks) doesn't divide evenly between the + * number of slices, spread the remaining blocks evenly between the first + * operations */ + start_slice = slice * base_blocks_per_slice; + /* Add any extra blocks (one per slice) that have been added before this slice */ + start_slice += FFMIN(slice, remainder_blocks); + + end_slice = start_slice + base_blocks_per_slice; + /* Add an extra block if there are still remainder blocks to be accounted for */ + if (slice < remainder_blocks) + end_slice++; + + for (y = start_slice; y < end_slice; y++) { + uint8_t *p = ctx->frame_data.out + y * ctx->stride * TEXTURE_BLOCK_H; + int off = y * w_block; + for (x = 0; x < w_block; x++) { + ctx->TEXTUREDSP_TEX_FUNC(p + x * ctx->raw_ratio, ctx->stride, + d + (off + x) * ctx->tex_ratio); + } + } + + return 0; +} diff --git a/libavcodec/texturedspenc.c b/libavcodec/texturedspenc.c index 3d68e0cf39..381be16f75 100644 --- a/libavcodec/texturedspenc.c +++ b/libavcodec/texturedspenc.c @@ -670,3 +670,7 @@ av_cold void ff_texturedspenc_init(TextureDSPContext *c) c->dxt5ys_block = dxt5ys_block; c->rgtc1u_alpha_block = rgtc1u_alpha_block; } + +#define TEXTUREDSP_FUNC_NAME ff_texturedsp_compress_thread +#define TEXTUREDSP_TEX_FUNC(a, b, c) tex_funct(c, b, a) +#include "texturedsp_template.c"