[FFmpeg-devel] [PATCH] TXD demuxer and decoder
Ivo
ivop
Sat May 5 13:57:56 CEST 2007
Hi,
On Friday 04 May 2007 21:08, Michael Niedermayer wrote:
> On Fri, May 04, 2007 at 05:32:10PM +0200, Ivo wrote:
> > [Renderware TXD demuxer/decoder]
>
> > +#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
Total number of instructions for the (c0>c1) case dropped by 21% and no more
division by 3. For the (c0<=c1) case it dropped by 14%.
> > + 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
Ok :) Fixed.
> > + a = (alpha & 0x0f) << 28;
> > + a += a >> 4;
> > + ((uint32_t *)d)[x] = a + colors[pixels&3];
>
> why isnt d uint32_t?
Fixed, up to the entry points of the decoding functions to avoid the need
for callers to cast their pointers (which are uint8_t* most of the time if
not always).
> > +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
Fixed.
> > +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
Fixed. Also in two other places.
> > +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
Fixed.
> > + 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()
Ah, yes. I forgot to remove those two lines. They were left-overs from
previous code. Fixed.
> > + pkt->stream_index = 0;
> > + if (ret <= 0) {
> > + av_free_packet(pkt);
>
> this is uneeded av_get_packet() will free it in case of failure
Fixed.
> > + pkt->size = ret;
>
> this also isnt needed
Fixed.
I also removed some code duplication from the demuxer (pushing chunks on the
stack for sub-chunks).
--Ivo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: txd.patch
Type: text/x-diff
Size: 17830 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070505/8311cc4e/attachment.patch>
More information about the ffmpeg-devel
mailing list