2 * Electronic Arts TGQ Video Decoder
3 * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
5 * This file is part of Libav.
7 * Libav 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 * Libav 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 Libav; 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
;
46 DECLARE_ALIGNED(16, int16_t, block
)[6][64];
50 static av_cold
int tgq_decode_init(AVCodecContext
*avctx
)
52 TgqContext
*s
= avctx
->priv_data
;
53 uint8_t idct_permutation
[64];
55 ff_init_scantable_permutation(idct_permutation
, FF_NO_IDCT_PERM
);
56 ff_init_scantable(idct_permutation
, &s
->scantable
, ff_zigzag_direct
);
57 avctx
->time_base
= (AVRational
){1, 15};
58 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
62 static void tgq_decode_block(TgqContext
*s
, int16_t block
[64], GetBitContext
*gb
)
64 uint8_t *perm
= s
->scantable
.permutated
;
66 block
[0] = get_sbits(gb
, 8) * s
->qtable
[0];
67 for (i
= 1; i
< 64;) {
68 switch (show_bits(gb
, 3)) {
78 value
= get_bits(gb
, 6);
79 for (j
= 0; j
< value
; j
++)
84 block
[perm
[i
]] = -s
->qtable
[perm
[i
]];
89 block
[perm
[i
]] = s
->qtable
[perm
[i
]];
95 if (show_bits(gb
, 6) == 0x3F) {
97 block
[perm
[i
]] = get_sbits(gb
, 8) * s
->qtable
[perm
[i
]];
99 block
[perm
[i
]] = get_sbits(gb
, 6) * s
->qtable
[perm
[i
]];
105 block
[0] += 128 << 4;
108 static void tgq_idct_put_mb(TgqContext
*s
, int16_t (*block
)[64],
111 int linesize
= s
->frame
.linesize
[0];
112 uint8_t *dest_y
= s
->frame
.data
[0] + (mb_y
* 16 * linesize
) + mb_x
* 16;
113 uint8_t *dest_cb
= s
->frame
.data
[1] + (mb_y
* 8 * s
->frame
.linesize
[1]) + mb_x
* 8;
114 uint8_t *dest_cr
= s
->frame
.data
[2] + (mb_y
* 8 * s
->frame
.linesize
[2]) + mb_x
* 8;
116 ff_ea_idct_put_c(dest_y
, linesize
, block
[0]);
117 ff_ea_idct_put_c(dest_y
+ 8, linesize
, block
[1]);
118 ff_ea_idct_put_c(dest_y
+ 8 * linesize
, linesize
, block
[2]);
119 ff_ea_idct_put_c(dest_y
+ 8 * linesize
+ 8, linesize
, block
[3]);
120 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
)) {
121 ff_ea_idct_put_c(dest_cb
, s
->frame
.linesize
[1], block
[4]);
122 ff_ea_idct_put_c(dest_cr
, s
->frame
.linesize
[2], block
[5]);
126 static inline void tgq_dconly(TgqContext
*s
, unsigned char *dst
,
127 int dst_stride
, int dc
)
129 int level
= av_clip_uint8((dc
*s
->qtable
[0] + 2056) >> 4);
131 for (j
= 0; j
< 8; j
++)
132 memset(dst
+ j
* dst_stride
, level
, 8);
135 static void tgq_idct_put_mb_dconly(TgqContext
*s
, int mb_x
, int mb_y
, const int8_t *dc
)
137 int linesize
= s
->frame
.linesize
[0];
138 uint8_t *dest_y
= s
->frame
.data
[0] + (mb_y
* 16 * linesize
) + mb_x
* 16;
139 uint8_t *dest_cb
= s
->frame
.data
[1] + (mb_y
* 8 * s
->frame
.linesize
[1]) + mb_x
* 8;
140 uint8_t *dest_cr
= s
->frame
.data
[2] + (mb_y
* 8 * s
->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
, s
->frame
.linesize
[1], dc
[4]);
147 tgq_dconly(s
, dest_cr
, s
->frame
.linesize
[2], dc
[5]);
151 static void tgq_decode_mb(TgqContext
*s
, int mb_y
, int mb_x
)
157 mode
= bytestream2_get_byte(&s
->gb
);
160 init_get_bits(&gb
, s
->gb
.buffer
, FFMIN(s
->gb
.buffer_end
- s
->gb
.buffer
, mode
) * 8);
161 for (i
= 0; i
< 6; i
++)
162 tgq_decode_block(s
, s
->block
[i
], &gb
);
163 tgq_idct_put_mb(s
, s
->block
, 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
);
180 tgq_idct_put_mb_dconly(s
, mb_x
, mb_y
, dc
);
184 static void tgq_calculate_qtable(TgqContext
*s
, int quant
)
187 const int a
= (14 * (100 - quant
)) / 100 + 1;
188 const int b
= (11 * (100 - quant
)) / 100 + 4;
189 for (j
= 0; j
< 8; j
++)
190 for (i
= 0; i
< 8; i
++)
191 s
->qtable
[j
* 8 + i
] = ((a
* (j
+ i
) / (7 + 7) + b
) *
192 ff_inv_aanscales
[j
* 8 + i
]) >> (14 - 4);
195 static int tgq_decode_frame(AVCodecContext
*avctx
,
196 void *data
, int *got_frame
,
199 const uint8_t *buf
= avpkt
->data
;
200 int buf_size
= avpkt
->size
;
201 TgqContext
*s
= avctx
->priv_data
;
203 int big_endian
= AV_RL32(&buf
[4]) > 0x000FFFFF;
206 av_log(avctx
, AV_LOG_WARNING
, "truncated header\n");
207 return AVERROR_INVALIDDATA
;
209 bytestream2_init(&s
->gb
, buf
+ 8, buf_size
- 8);
211 s
->width
= bytestream2_get_be16u(&s
->gb
);
212 s
->height
= bytestream2_get_be16u(&s
->gb
);
214 s
->width
= bytestream2_get_le16u(&s
->gb
);
215 s
->height
= bytestream2_get_le16u(&s
->gb
);
218 if (s
->avctx
->width
!=s
->width
|| s
->avctx
->height
!=s
->height
) {
219 avcodec_set_dimensions(s
->avctx
, s
->width
, s
->height
);
220 if (s
->frame
.data
[0])
221 avctx
->release_buffer(avctx
, &s
->frame
);
223 tgq_calculate_qtable(s
, bytestream2_get_byteu(&s
->gb
));
224 bytestream2_skip(&s
->gb
, 3);
226 if (!s
->frame
.data
[0]) {
227 s
->frame
.key_frame
= 1;
228 s
->frame
.pict_type
= AV_PICTURE_TYPE_I
;
229 s
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
;
230 if ((ret
= ff_get_buffer(avctx
, &s
->frame
)) < 0) {
231 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
236 for (y
= 0; y
< FFALIGN(avctx
->height
, 16) >> 4; y
++)
237 for (x
= 0; x
< FFALIGN(avctx
->width
, 16) >> 4; x
++)
238 tgq_decode_mb(s
, y
, x
);
241 *(AVFrame
*)data
= s
->frame
;
246 static av_cold
int tgq_decode_end(AVCodecContext
*avctx
)
248 TgqContext
*s
= avctx
->priv_data
;
249 if (s
->frame
.data
[0])
250 s
->avctx
->release_buffer(avctx
, &s
->frame
);
254 AVCodec ff_eatgq_decoder
= {
256 .type
= AVMEDIA_TYPE_VIDEO
,
257 .id
= AV_CODEC_ID_TGQ
,
258 .priv_data_size
= sizeof(TgqContext
),
259 .init
= tgq_decode_init
,
260 .close
= tgq_decode_end
,
261 .decode
= tgq_decode_frame
,
262 .capabilities
= CODEC_CAP_DR1
,
263 .long_name
= NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),