[FFmpeg-devel] [PATCH] TXD demuxer and decoder
Michael Niedermayer
michaelni
Fri May 4 21:08:37 CEST 2007
Hi
On Fri, May 04, 2007 at 05:32:10PM +0200, Ivo wrote:
> Hi,
>
> The following patch implements a demuxer and decoder for .txd files, used by
> various games that use the Renderware engine, like Grand Theft Auto. See
> http://wiki.multimedia.cx/index.php?title=TXD for details.
>
> I decided to place the S3TC decoding functions in a separate file as they
> are pretty generic and used in other (Microsoft) formats too, like
> DirectShow Surfaces. This way they can easily be re-used in the future.
>
> Currently, the code demuxes and decodes all GTA:SA files I have tested
> correctly, except for one problem with mid-stream dimension changes which I
> described here:
>
> Message-Id: <200705040110.13009.ivop at euronet.nl>
> Subject: [FFmpeg-devel] Multiple frame dimensions in a single stream
>
> I have traced the problem back to ffmpeg.c which sets the output
> AVCodecContext parameters once at the beginning, based on the input
> context, which is based on the first frame in the TXD case. It does not
> handle changes of the input context. Fixing that is non-trivial because of
> potential padding/cropping/scaling of the frames and is also outside the
> scope of this patch. But I will look into it as it affects other codecs
> that support multiple dimensions in one stream as well.
>
> --Ivo
[...]
> +#define UNPACK_R(c, r) r = (c&0x1f)<<3; r += r>>5;
> +#define UNPACK_G(c, g) g = (c>>3)&0xfc; g += g>>6;
> +#define UNPACK_B(c, b) b = (c>>8)&0xf8; b += b>>5;
> +#define UNPACK_RGB(c,r,g,b) UNPACK_R(c,r); UNPACK_G(c,g); UNPACK_B(c,b);
> +#define PACK_COLOR(r,g,b,a) (r+(g<<8)+(b<<16)+(a<<24))
> +
> +static inline void dxt1_decode_pixels(uint8_t *s, uint8_t *d,
> + unsigned int stride, unsigned int flag,
> + uint64_t alpha) {
> + unsigned int x, y, c0, c1, r0, g0, b0, r1, g1, b1, a = !flag * 255;
> + uint32_t colors[4], pixels;
> +
> + c0 = le2me_16(*(uint16_t *)(s));
> + c1 = le2me_16(*(uint16_t *)(s+2));
> + UNPACK_RGB(c0, r0, g0, b0);
> + UNPACK_RGB(c1, r1, g1, b1);
> +
> + colors[0] = PACK_COLOR(r0, g0, b0, a);
> + colors[1] = PACK_COLOR(r1, g1, b1, a);
> + if (c0 > c1 || flag) {
> + colors[2] = PACK_COLOR((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, a);
r0+=r0>>5; r1+=r1>>5; 2*r0+r1
== (except rounding)
T=2*r0+r1; T+= T>>5;
furthermore the T+=T>>5 and the /3 == * 11 >>5
> + colors[3] = PACK_COLOR((2*r1+r0)/3, (2*g1+g0)/3, (2*b1+b0)/3, a);
> + } else {
> + colors[2] = PACK_COLOR((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, a);
> + colors[3] = 0;
> + }
> +
> + for (pixels=le2me_32(*(uint32_t *)(s+4)), y=0; y<4; d+=stride, y++)
> + for (x=0; x<4; x++, pixels>>=2, alpha>>=4) {
may i suggest to put fewer statements on each line of code
> + a = (alpha & 0x0f) << 28;
> + a += a >> 4;
> + ((uint32_t *)d)[x] = a + colors[pixels&3];
why isnt d uint32_t?
> + }
> +}
> +
> +void ff_decode_dxt1(const uint8_t *src, const uint8_t *dst,
> + const unsigned int w, const unsigned int h,
> + const unsigned int stride) {
> + unsigned int bx, by, stride3 = 4*stride - 4*w;
> + uint8_t *s = (uint8_t *) src, *d = (uint8_t *) dst;
this is wrong, dst isnt const, src should stay const
[...]
> +static int txd_init(AVCodecContext *avctx) {
> + TXDContext *s = avctx->priv_data;
> +
> + avcodec_get_frame_defaults((AVFrame*)&s->picture);
> + avctx->coded_frame= (AVFrame*)&s->picture;
useles cast
[...]
> +static int txd_probe(AVProbeData * pd) {
> + uint8_t *buf = pd->buf;
> + unsigned int id, marker;
> +
> + id = AV_RL32(buf);
> + marker = AV_RL32(buf+8);
> +
> + if (id == 0x16 && marker == TXD_MARKER)
> + return AVPROBE_SCORE_MAX;
the id and marker variables are redundant
[...]
> + if (av_new_packet(pkt, chunk_size) < 0)
> + return AVERROR_IO;
> + ret = av_get_packet(&s->pb, pkt, chunk_size);
memleak, av_get_packet() calls av_new_packet()
> + pkt->stream_index = 0;
> + if (ret <= 0) {
> + av_free_packet(pkt);
this is uneeded av_get_packet() will free it in case of failure
> + return AVERROR_IO;
> + }
> + pkt->size = ret;
this also isnt needed
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
No snowflake in an avalanche ever feels responsible. -- Voltaire
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070504/c8a8fba5/attachment.pgp>
More information about the ffmpeg-devel
mailing list