txd: Use the TextureDSP module for decoding

Using the internal DXTC routines brings support for non multiple of 4
textures. A new test is added to cover this feature. Hashes differ
since the decoding algorithm is different, though no visual changes
have been spotted.

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
This commit is contained in:
Vittorio Giovara 2015-05-19 23:54:16 +01:00
parent 8337e0c573
commit c0b105756f
8 changed files with 46 additions and 170 deletions

1
configure vendored
View File

@ -1949,6 +1949,7 @@ truehd_decoder_select="mlp_decoder"
truemotion2_decoder_select="bswapdsp" truemotion2_decoder_select="bswapdsp"
truespeech_decoder_select="bswapdsp" truespeech_decoder_select="bswapdsp"
tscc_decoder_deps="zlib" tscc_decoder_deps="zlib"
txd_decoder_select="texturedsp"
twinvq_decoder_select="mdct lsp sinewin" twinvq_decoder_select="mdct lsp sinewin"
utvideo_decoder_select="bswapdsp" utvideo_decoder_select="bswapdsp"
utvideo_encoder_select="bswapdsp huffman huffyuvencdsp" utvideo_encoder_select="bswapdsp huffman huffyuvencdsp"

View File

@ -404,7 +404,7 @@ OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o
OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o
OBJS-$(CONFIG_TTA_DECODER) += tta.o OBJS-$(CONFIG_TTA_DECODER) += tta.o
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o
OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o OBJS-$(CONFIG_TXD_DECODER) += txd.o
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o
OBJS-$(CONFIG_UTVIDEO_ENCODER) += utvideoenc.o utvideo.o OBJS-$(CONFIG_UTVIDEO_ENCODER) += utvideoenc.o utvideo.o

View File

@ -1,97 +0,0 @@
/*
* S3 Texture Compression (S3TC) decoding functions
* Copyright (c) 2007 by Ivo van Poorten
*
* see also: http://wiki.multimedia.cx/index.php?title=S3TC
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "bytestream.h"
#include "s3tc.h"
static inline void dxt1_decode_pixels(GetByteContext *gb, uint32_t *d,
unsigned int qstride, unsigned int flag,
uint64_t alpha) {
unsigned int x, y, c0, c1, a = (!flag * 255u) << 24;
unsigned int rb0, rb1, rb2, rb3, g0, g1, g2, g3;
uint32_t colors[4], pixels;
c0 = bytestream2_get_le16(gb);
c1 = bytestream2_get_le16(gb);
rb0 = (c0<<3 | c0<<8) & 0xf800f8;
rb1 = (c1<<3 | c1<<8) & 0xf800f8;
rb0 += (rb0>>5) & 0x070007;
rb1 += (rb1>>5) & 0x070007;
g0 = (c0 <<5) & 0x00fc00;
g1 = (c1 <<5) & 0x00fc00;
g0 += (g0 >>6) & 0x000300;
g1 += (g1 >>6) & 0x000300;
colors[0] = rb0 + g0 + a;
colors[1] = rb1 + g1 + a;
if (c0 > c1 || flag) {
rb2 = (((2*rb0+rb1) * 21) >> 6) & 0xff00ff;
rb3 = (((2*rb1+rb0) * 21) >> 6) & 0xff00ff;
g2 = (((2*g0 +g1 ) * 21) >> 6) & 0x00ff00;
g3 = (((2*g1 +g0 ) * 21) >> 6) & 0x00ff00;
colors[3] = rb3 + g3 + a;
} else {
rb2 = ((rb0+rb1) >> 1) & 0xff00ff;
g2 = ((g0 +g1 ) >> 1) & 0x00ff00;
colors[3] = 0;
}
colors[2] = rb2 + g2 + a;
pixels = bytestream2_get_le32(gb);
for (y=0; y<4; y++) {
for (x=0; x<4; x++) {
a = (alpha & 0x0f) << 28;
a += a >> 4;
d[x] = a + colors[pixels&3];
pixels >>= 2;
alpha >>= 4;
}
d += qstride;
}
}
void ff_decode_dxt1(GetByteContext *gb, uint8_t *dst,
const unsigned int w, const unsigned int h,
const unsigned int stride) {
unsigned int bx, by, qstride = stride/4;
uint32_t *d = (uint32_t *) dst;
for (by=0; by < h/4; by++, d += stride-w)
for (bx = 0; bx < w / 4; bx++, d += 4)
dxt1_decode_pixels(gb, d, qstride, 0, 0LL);
}
void ff_decode_dxt3(GetByteContext *gb, uint8_t *dst,
const unsigned int w, const unsigned int h,
const unsigned int stride) {
unsigned int bx, by, qstride = stride/4;
uint32_t *d = (uint32_t *) dst;
for (by=0; by < h/4; by++, d += stride-w)
for (bx = 0; bx < w / 4; bx++, d += 4)
dxt1_decode_pixels(gb, d, qstride, 1, bytestream2_get_le64(gb));
}

View File

@ -1,55 +0,0 @@
/*
* S3 Texture Compression (S3TC) decoding functions
* Copyright (c) 2007 by Ivo van Poorten
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_S3TC_H
#define AVCODEC_S3TC_H
#include <stdint.h>
#include "bytestream.h"
#define FF_S3TC_DXT1 0x31545844
#define FF_S3TC_DXT3 0x33545844
/**
* Decode DXT1 encoded data to RGB32
* @param gb GetByteContext
* @param dst destination buffer
* @param w width of output image
* @param h height of output image
* @param stride line size of output image
*/
void ff_decode_dxt1(GetByteContext *gb, uint8_t *dst,
const unsigned int w, const unsigned int h,
const unsigned int stride);
/**
* Decode DXT3 encoded data to RGB32
* @param gb GetByteContext
* @param dst destination buffer
* @param w width of output image
* @param h height of output image
* @param stride line size of output image
*/
void ff_decode_dxt3(GetByteContext *gb, uint8_t *dst,
const unsigned int w, const unsigned int h,
const unsigned int stride);
#endif /* AVCODEC_S3TC_H */

View File

@ -26,18 +26,25 @@
#include "avcodec.h" #include "avcodec.h"
#include "bytestream.h" #include "bytestream.h"
#include "internal.h" #include "internal.h"
#include "s3tc.h" #include "texturedsp.h"
#define TXD_DXT1 0x31545844
#define TXD_DXT3 0x33545844
static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt) { AVPacket *avpkt) {
GetByteContext gb; GetByteContext gb;
TextureDSPContext dxtc;
AVFrame * const p = data; AVFrame * const p = data;
unsigned int version, w, h, d3d_format, depth, stride, flags; unsigned int version, w, h, d3d_format, depth, stride, flags;
unsigned int y, v; unsigned int y, v;
uint8_t *ptr; uint8_t *ptr;
uint32_t *pal; uint32_t *pal;
int i, j;
int ret; int ret;
ff_texturedsp_init(&dxtc);
bytestream2_init(&gb, avpkt->data, avpkt->size); bytestream2_init(&gb, avpkt->data, avpkt->size);
version = bytestream2_get_le32(&gb); version = bytestream2_get_le32(&gb);
bytestream2_skip(&gb, 72); bytestream2_skip(&gb, 72);
@ -57,7 +64,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
if (depth == 8) { if (depth == 8) {
avctx->pix_fmt = AV_PIX_FMT_PAL8; avctx->pix_fmt = AV_PIX_FMT_PAL8;
} else if (depth == 16 || depth == 32) { } else if (depth == 16 || depth == 32) {
avctx->pix_fmt = AV_PIX_FMT_RGB32; avctx->pix_fmt = AV_PIX_FMT_RGBA;
} else { } else {
av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth); av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth);
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
@ -66,6 +73,9 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
if ((ret = ff_set_dimensions(avctx, w, h)) < 0) if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret; return ret;
avctx->coded_width = FFALIGN(w, 4);
avctx->coded_height = FFALIGN(h, 4);
if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret; return ret;
@ -93,11 +103,23 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
case 0: case 0:
if (!(flags & 1)) if (!(flags & 1))
goto unsupported; goto unsupported;
case FF_S3TC_DXT1: case TXD_DXT1:
ff_decode_dxt1(&gb, ptr, w, h, stride); for (j = 0; j < avctx->height; j += 4) {
for (i = 0; i < avctx->width; i += 4) {
uint8_t *p = ptr + i * 4 + j * stride;
int step = dxtc.dxt1_block(p, stride, gb.buffer);
bytestream2_skip(&gb, step);
}
}
break; break;
case FF_S3TC_DXT3: case TXD_DXT3:
ff_decode_dxt3(&gb, ptr, w, h, stride); for (j = 0; j < avctx->height; j += 4) {
for (i = 0; i < avctx->width; i += 4) {
uint8_t *p = ptr + i * 4 + j * stride;
int step = dxtc.dxt3_block(p, stride, gb.buffer);
bytestream2_skip(&gb, step);
}
}
break; break;
default: default:
goto unsupported; goto unsupported;

View File

@ -272,6 +272,9 @@ fate-tmv: CMD = framecrc -i $(TARGET_SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
FATE_TXD += fate-txd-16bpp FATE_TXD += fate-txd-16bpp
fate-txd-16bpp: CMD = framecrc -i $(TARGET_SAMPLES)/txd/misc.txd -pix_fmt bgra -an fate-txd-16bpp: CMD = framecrc -i $(TARGET_SAMPLES)/txd/misc.txd -pix_fmt bgra -an
FATE_TXD += fate-txd-odd
fate-txd-odd: CMD = framecrc -i $(TARGET_SAMPLES)/txd/odd.txd -pix_fmt bgra -an
FATE_TXD += fate-txd-pal8 FATE_TXD += fate-txd-pal8
fate-txd-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an fate-txd-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an

View File

@ -1,12 +1,12 @@
#tb 0: 1/5 #tb 0: 1/5
0, 0, 0, 1, 16384, 0x213f9ea8 0, 0, 0, 1, 16384, 0x4c7bb4cb
0, 1, 1, 1, 16384, 0x8185fdb1 0, 1, 1, 1, 16384, 0x914e14b4
0, 2, 2, 1, 16384, 0xf03581d1 0, 2, 2, 1, 16384, 0x81e293cb
0, 3, 3, 1, 16384, 0x629cd573 0, 3, 3, 1, 16384, 0xf733ed43
0, 4, 4, 1, 16384, 0xfe7a5b63 0, 4, 4, 1, 16384, 0x739a6c21
0, 5, 5, 1, 16384, 0x4afc05b2 0, 5, 5, 1, 16384, 0x47f9184a
0, 6, 6, 1, 16384, 0x074b8515 0, 6, 6, 1, 16384, 0x329f9d3e
0, 7, 7, 1, 16384, 0x17fde900 0, 7, 7, 1, 16384, 0x231ffd9c
0, 8, 8, 1, 16384, 0x831bac76 0, 8, 8, 1, 16384, 0xe7c2c4c6
0, 9, 9, 1, 16384, 0x2fb579f3 0, 9, 9, 1, 16384, 0x880d8ffb
0, 10, 10, 1, 16384, 0x68762bed 0, 10, 10, 1, 16384, 0xf83238d2

2
tests/ref/fate/txd-odd Normal file
View File

@ -0,0 +1,2 @@
#tb 0: 1/5
0, 0, 0, 1, 385452, 0xb22514d6