aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2022-03-19 20:53:17 +0100
committerMarton Balint <cus@passwd.hu>2022-04-10 20:12:23 +0200
commit30fdcd2e12532c23e4662abf8523292c3f32e5e4 (patch)
treede254284c80fca6b71db791ac297b4eee217f2cc /libavcodec
parent541d3755e92da34b69df8c3c08d0d66cc4b05afd (diff)
downloadffmpeg-30fdcd2e12532c23e4662abf8523292c3f32e5e4.tar.gz
avcodec/dds: use the common texture dsp decode function
Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/dds.c135
1 files changed, 48 insertions, 87 deletions
diff --git a/libavcodec/dds.c b/libavcodec/dds.c
index d4f6800ec9..30788f1777 100644
--- a/libavcodec/dds.c
+++ b/libavcodec/dds.c
@@ -106,12 +106,7 @@ typedef struct DDSContext {
int bpp;
enum DDSPostProc postproc;
- const uint8_t *tex_data; // Compressed texture
- int tex_ratio; // Compression ratio
- 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 dec;
} DDSContext;
static int parse_pixel_format(AVCodecContext *avctx)
@@ -170,35 +165,36 @@ static int parse_pixel_format(AVCodecContext *avctx)
avctx->pix_fmt = AV_PIX_FMT_RGBA;
if (ctx->compressed) {
+ ctx->dec.raw_ratio = 16;
switch (fourcc) {
case MKTAG('D', 'X', 'T', '1'):
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.dxt1a_block;
+ ctx->dec.tex_ratio = 8;
+ ctx->dec.tex_funct = ctx->texdsp.dxt1a_block;
break;
case MKTAG('D', 'X', 'T', '2'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt2_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxt2_block;
break;
case MKTAG('D', 'X', 'T', '3'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt3_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxt3_block;
break;
case MKTAG('D', 'X', 'T', '4'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt4_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxt4_block;
break;
case MKTAG('D', 'X', 'T', '5'):
- ctx->tex_ratio = 16;
+ ctx->dec.tex_ratio = 16;
if (ycocg_scaled)
- ctx->tex_funct = ctx->texdsp.dxt5ys_block;
+ ctx->dec.tex_funct = ctx->texdsp.dxt5ys_block;
else if (ycocg_classic)
- ctx->tex_funct = ctx->texdsp.dxt5y_block;
+ ctx->dec.tex_funct = ctx->texdsp.dxt5y_block;
else
- ctx->tex_funct = ctx->texdsp.dxt5_block;
+ ctx->dec.tex_funct = ctx->texdsp.dxt5_block;
break;
case MKTAG('R', 'X', 'G', 'B'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt5_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxt5_block;
/* This format may be considered as a normal map,
* but it is handled differently in a separate postproc. */
ctx->postproc = DDS_SWIZZLE_RXGB;
@@ -206,25 +202,25 @@ static int parse_pixel_format(AVCodecContext *avctx)
break;
case MKTAG('A', 'T', 'I', '1'):
case MKTAG('B', 'C', '4', 'U'):
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1u_block;
+ ctx->dec.tex_ratio = 8;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc1u_block;
break;
case MKTAG('B', 'C', '4', 'S'):
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1s_block;
+ ctx->dec.tex_ratio = 8;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc1s_block;
break;
case MKTAG('A', 'T', 'I', '2'):
/* RGT2 variant with swapped R and G (3Dc)*/
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxn3dc_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxn3dc_block;
break;
case MKTAG('B', 'C', '5', 'U'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2u_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc2u_block;
break;
case MKTAG('B', 'C', '5', 'S'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2s_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc2s_block;
break;
case MKTAG('U', 'Y', 'V', 'Y'):
ctx->compressed = 0;
@@ -299,40 +295,40 @@ static int parse_pixel_format(AVCodecContext *avctx)
avctx->colorspace = AVCOL_SPC_RGB;
case DXGI_FORMAT_BC1_TYPELESS:
case DXGI_FORMAT_BC1_UNORM:
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.dxt1a_block;
+ ctx->dec.tex_ratio = 8;
+ ctx->dec.tex_funct = ctx->texdsp.dxt1a_block;
break;
case DXGI_FORMAT_BC2_UNORM_SRGB:
avctx->colorspace = AVCOL_SPC_RGB;
case DXGI_FORMAT_BC2_TYPELESS:
case DXGI_FORMAT_BC2_UNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt3_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxt3_block;
break;
case DXGI_FORMAT_BC3_UNORM_SRGB:
avctx->colorspace = AVCOL_SPC_RGB;
case DXGI_FORMAT_BC3_TYPELESS:
case DXGI_FORMAT_BC3_UNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt5_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.dxt5_block;
break;
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1u_block;
+ ctx->dec.tex_ratio = 8;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc1u_block;
break;
case DXGI_FORMAT_BC4_SNORM:
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1s_block;
+ ctx->dec.tex_ratio = 8;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc1s_block;
break;
case DXGI_FORMAT_BC5_TYPELESS:
case DXGI_FORMAT_BC5_UNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2u_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc2u_block;
break;
case DXGI_FORMAT_BC5_SNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2s_block;
+ ctx->dec.tex_ratio = 16;
+ ctx->dec.tex_funct = ctx->texdsp.rgtc2s_block;
break;
default:
av_log(avctx, AV_LOG_ERROR,
@@ -434,43 +430,6 @@ static int parse_pixel_format(AVCodecContext *avctx)
return 0;
}
-static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
- int slice, int thread_nb)
-{
- DDSContext *ctx = avctx->priv_data;
- AVFrame *frame = arg;
- const uint8_t *d = ctx->tex_data;
- 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 = frame->data[0] + y * frame->linesize[0] * TEXTURE_BLOCK_H;
- int off = y * w_block;
- for (x = 0; x < w_block; x++) {
- ctx->tex_funct(p + x * 16, frame->linesize[0],
- d + (off + x) * ctx->tex_ratio);
- }
- }
-
- return 0;
-}
-
static void do_swizzle(AVFrame *frame, int x, int y)
{
int i;
@@ -513,7 +472,7 @@ static void run_postproc(AVCodecContext *avctx, AVFrame *frame)
* http://www.realtimecollisiondetection.net/blog/?p=28 */
av_log(avctx, AV_LOG_DEBUG, "Post-processing normal map.\n");
- x_off = ctx->tex_ratio == 8 ? 0 : 3;
+ x_off = ctx->dec.tex_ratio == 8 ? 0 : 3;
for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
uint8_t *src = frame->data[0] + i;
int x = src[x_off];
@@ -663,9 +622,9 @@ static int dds_decode(AVCodecContext *avctx, AVFrame *frame,
if (ctx->compressed) {
int size = (avctx->coded_height / TEXTURE_BLOCK_H) *
- (avctx->coded_width / TEXTURE_BLOCK_W) * ctx->tex_ratio;
- ctx->slice_count = av_clip(avctx->thread_count, 1,
- avctx->coded_height / TEXTURE_BLOCK_H);
+ (avctx->coded_width / TEXTURE_BLOCK_W) * ctx->dec.tex_ratio;
+ ctx->dec.slice_count = av_clip(avctx->thread_count, 1,
+ avctx->coded_height / TEXTURE_BLOCK_H);
if (bytestream2_get_bytes_left(gbc) < size) {
av_log(avctx, AV_LOG_ERROR,
@@ -675,8 +634,10 @@ static int dds_decode(AVCodecContext *avctx, AVFrame *frame,
}
/* Use the decompress function on the texture, one block per thread. */
- ctx->tex_data = gbc->buffer;
- avctx->execute2(avctx, decompress_texture_thread, frame, NULL, ctx->slice_count);
+ ctx->dec.tex_data.in = gbc->buffer;
+ ctx->dec.frame_data.out = frame->data[0];
+ ctx->dec.stride = frame->linesize[0];
+ avctx->execute2(avctx, ff_texturedsp_decompress_thread, &ctx->dec, NULL, ctx->dec.slice_count);
} else if (!ctx->paletted && ctx->bpp == 4 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
uint8_t *dst = frame->data[0];
int x, y, i;