2 * Electronic Arts TGQ Video Decoder
3 * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 * Electronic Arts TGQ Video Decoder
25 * @author Peter Ross <pross@xvid.org>
27 * Technical details here:
28 * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGQ
32 #define BITSTREAM_READER_LE
34 #include "bytestream.h"
36 #include "aandcttab.h"
40 typedef struct TgqContext
{
41 AVCodecContext
*avctx
;
45 DECLARE_ALIGNED(16, int16_t, block
)[6][64];
49 static av_cold
int tgq_decode_init(AVCodecContext
*avctx
)
51 TgqContext
*s
= avctx
->priv_data
;
52 uint8_t idct_permutation
[64];
54 ff_init_scantable_permutation(idct_permutation
, FF_IDCT_PERM_NONE
);
55 ff_init_scantable(idct_permutation
, &s
->scantable
, ff_zigzag_direct
);
56 avctx
->framerate
= (AVRational
){ 15, 1 };
57 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
61 static void tgq_decode_block(TgqContext
*s
, int16_t block
[64], GetBitContext
*gb
)
63 uint8_t *perm
= s
->scantable
.permutated
;
65 block
[0] = get_sbits(gb
, 8) * s
->qtable
[0];
66 for (i
= 1; i
< 64;) {
67 switch (show_bits(gb
, 3)) {
77 value
= get_bits(gb
, 6);
78 for (j
= 0; j
< value
; j
++)
83 block
[perm
[i
]] = -s
->qtable
[perm
[i
]];
88 block
[perm
[i
]] = s
->qtable
[perm
[i
]];
94 if (show_bits(gb
, 6) == 0x3F) {
96 block
[perm
[i
]] = get_sbits(gb
, 8) * s
->qtable
[perm
[i
]];
98 block
[perm
[i
]] = get_sbits(gb
, 6) * s
->qtable
[perm
[i
]];
104 block
[0] += 128 << 4;
107 static void tgq_idct_put_mb(TgqContext
*s
, int16_t (*block
)[64], AVFrame
*frame
,
110 int linesize
= frame
->linesize
[0];
111 uint8_t *dest_y
= frame
->data
[0] + (mb_y
* 16 * linesize
) + mb_x
* 16;
112 uint8_t *dest_cb
= frame
->data
[1] + (mb_y
* 8 * frame
->linesize
[1]) + mb_x
* 8;
113 uint8_t *dest_cr
= frame
->data
[2] + (mb_y
* 8 * frame
->linesize
[2]) + mb_x
* 8;
115 ff_ea_idct_put_c(dest_y
, linesize
, block
[0]);
116 ff_ea_idct_put_c(dest_y
+ 8, linesize
, block
[1]);
117 ff_ea_idct_put_c(dest_y
+ 8 * linesize
, linesize
, block
[2]);
118 ff_ea_idct_put_c(dest_y
+ 8 * linesize
+ 8, linesize
, block
[3]);
119 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
)) {
120 ff_ea_idct_put_c(dest_cb
, frame
->linesize
[1], block
[4]);
121 ff_ea_idct_put_c(dest_cr
, frame
->linesize
[2], block
[5]);
125 static inline void tgq_dconly(TgqContext
*s
, unsigned char *dst
,
126 int dst_stride
, int dc
)
128 int level
= av_clip_uint8((dc
*s
->qtable
[0] + 2056) >> 4);
130 for (j
= 0; j
< 8; j
++)
131 memset(dst
+ j
* dst_stride
, level
, 8);
134 static void tgq_idct_put_mb_dconly(TgqContext
*s
, AVFrame
*frame
,
135 int mb_x
, int mb_y
, const int8_t *dc
)
137 int linesize
= frame
->linesize
[0];
138 uint8_t *dest_y
= frame
->data
[0] + (mb_y
* 16 * linesize
) + mb_x
* 16;
139 uint8_t *dest_cb
= frame
->data
[1] + (mb_y
* 8 * frame
->linesize
[1]) + mb_x
* 8;
140 uint8_t *dest_cr
= frame
->data
[2] + (mb_y
* 8 * frame
->linesize
[2]) + mb_x
* 8;
141 tgq_dconly(s
, dest_y
, linesize
, dc
[0]);
142 tgq_dconly(s
, dest_y
+ 8, linesize
, dc
[1]);
143 tgq_dconly(s
, dest_y
+ 8 * linesize
, linesize
, dc
[2]);
144 tgq_dconly(s
, dest_y
+ 8 * linesize
+ 8, linesize
, dc
[3]);
145 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
)) {
146 tgq_dconly(s
, dest_cb
, frame
->linesize
[1], dc
[4]);
147 tgq_dconly(s
, dest_cr
, frame
->linesize
[2], dc
[5]);
151 static int tgq_decode_mb(TgqContext
*s
, AVFrame
*frame
, int mb_y
, int mb_x
)
157 mode
= bytestream2_get_byte(&s
->gb
);
160 init_get_bits8(&gb
, s
->gb
.buffer
, FFMIN(bytestream2_get_bytes_left(&s
->gb
), mode
));
161 for (i
= 0; i
< 6; i
++)
162 tgq_decode_block(s
, s
->block
[i
], &gb
);
163 tgq_idct_put_mb(s
, s
->block
, frame
, mb_x
, mb_y
);
164 bytestream2_skip(&s
->gb
, mode
);
167 memset(dc
, bytestream2_get_byte(&s
->gb
), 4);
168 dc
[4] = bytestream2_get_byte(&s
->gb
);
169 dc
[5] = bytestream2_get_byte(&s
->gb
);
170 } else if (mode
== 6) {
171 bytestream2_get_buffer(&s
->gb
, dc
, 6);
172 } else if (mode
== 12) {
173 for (i
= 0; i
< 6; i
++) {
174 dc
[i
] = bytestream2_get_byte(&s
->gb
);
175 bytestream2_skip(&s
->gb
, 1);
178 av_log(s
->avctx
, AV_LOG_ERROR
, "unsupported mb mode %i\n", mode
);
181 tgq_idct_put_mb_dconly(s
, frame
, mb_x
, mb_y
, dc
);
186 static void tgq_calculate_qtable(TgqContext
*s
, int quant
)
189 const int a
= (14 * (100 - quant
)) / 100 + 1;
190 const int b
= (11 * (100 - quant
)) / 100 + 4;
191 for (j
= 0; j
< 8; j
++)
192 for (i
= 0; i
< 8; i
++)
193 s
->qtable
[j
* 8 + i
] = ((a
* (j
+ i
) / (7 + 7) + b
) *
194 ff_inv_aanscales
[j
* 8 + i
]) >> (14 - 4);
197 static int tgq_decode_frame(AVCodecContext
*avctx
,
198 void *data
, int *got_frame
,
201 const uint8_t *buf
= avpkt
->data
;
202 int buf_size
= avpkt
->size
;
203 TgqContext
*s
= avctx
->priv_data
;
204 AVFrame
*frame
= data
;
209 av_log(avctx
, AV_LOG_WARNING
, "truncated header\n");
210 return AVERROR_INVALIDDATA
;
212 big_endian
= AV_RL32(&buf
[4]) > 0x000FFFFF;
213 bytestream2_init(&s
->gb
, buf
+ 8, buf_size
- 8);
215 s
->width
= bytestream2_get_be16u(&s
->gb
);
216 s
->height
= bytestream2_get_be16u(&s
->gb
);
218 s
->width
= bytestream2_get_le16u(&s
->gb
);
219 s
->height
= bytestream2_get_le16u(&s
->gb
);
222 ret
= ff_set_dimensions(s
->avctx
, s
->width
, s
->height
);
226 tgq_calculate_qtable(s
, bytestream2_get_byteu(&s
->gb
));
227 bytestream2_skip(&s
->gb
, 3);
229 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
231 frame
->key_frame
= 1;
232 frame
->pict_type
= AV_PICTURE_TYPE_I
;
234 for (y
= 0; y
< FFALIGN(avctx
->height
, 16) >> 4; y
++)
235 for (x
= 0; x
< FFALIGN(avctx
->width
, 16) >> 4; x
++)
236 if (tgq_decode_mb(s
, frame
, y
, x
) < 0)
237 return AVERROR_INVALIDDATA
;
244 AVCodec ff_eatgq_decoder
= {
246 .long_name
= NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
247 .type
= AVMEDIA_TYPE_VIDEO
,
248 .id
= AV_CODEC_ID_TGQ
,
249 .priv_data_size
= sizeof(TgqContext
),
250 .init
= tgq_decode_init
,
251 .decode
= tgq_decode_frame
,
252 .capabilities
= CODEC_CAP_DR1
,