9e3a3e652915e798f73758aadd43e4e0a5038bcc
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, DCTELEM
, block
)[6][64];
50 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_NO_IDCT_PERM
);
55 ff_init_scantable(idct_permutation
, &s
->scantable
, ff_zigzag_direct
);
56 avctx
->time_base
= (AVRational
){1, 15};
57 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
61 static void tgq_decode_block(TgqContext
*s
, DCTELEM block
[64], GetBitContext
*gb
){
62 uint8_t *perm
= s
->scantable
.permutated
;
64 block
[0] = get_sbits(gb
,8) * s
->qtable
[0];
66 switch(show_bits(gb
,3)) {
76 value
= get_bits(gb
,6);
77 for(j
=0; j
<value
; j
++)
82 block
[perm
[i
]] = -s
->qtable
[perm
[i
]];
87 block
[perm
[i
]] = s
->qtable
[perm
[i
]];
93 if (show_bits(gb
,6)==0x3F) {
95 block
[perm
[i
]] = get_sbits(gb
,8)*s
->qtable
[perm
[i
]];
97 block
[perm
[i
]] = get_sbits(gb
,6)*s
->qtable
[perm
[i
]];
106 static void tgq_idct_put_mb(TgqContext
*s
, DCTELEM (*block
)[64], int mb_x
, int mb_y
){
107 int linesize
= s
->frame
.linesize
[0];
108 uint8_t *dest_y
= s
->frame
.data
[0] + (mb_y
* 16* linesize
) + mb_x
* 16;
109 uint8_t *dest_cb
= s
->frame
.data
[1] + (mb_y
* 8 * s
->frame
.linesize
[1]) + mb_x
* 8;
110 uint8_t *dest_cr
= s
->frame
.data
[2] + (mb_y
* 8 * s
->frame
.linesize
[2]) + mb_x
* 8;
112 ff_ea_idct_put_c(dest_y
, linesize
, block
[0]);
113 ff_ea_idct_put_c(dest_y
+ 8, linesize
, block
[1]);
114 ff_ea_idct_put_c(dest_y
+ 8*linesize
, linesize
, block
[2]);
115 ff_ea_idct_put_c(dest_y
+ 8*linesize
+ 8, linesize
, block
[3]);
116 if(!(s
->avctx
->flags
&CODEC_FLAG_GRAY
)){
117 ff_ea_idct_put_c(dest_cb
, s
->frame
.linesize
[1], block
[4]);
118 ff_ea_idct_put_c(dest_cr
, s
->frame
.linesize
[2], block
[5]);
122 static inline void tgq_dconly(TgqContext
*s
, unsigned char *dst
, int dst_stride
, int dc
){
123 int level
= av_clip_uint8((dc
*s
->qtable
[0] + 2056)>>4);
126 memset(dst
+j
*dst_stride
, level
, 8);
129 static void tgq_idct_put_mb_dconly(TgqContext
*s
, int mb_x
, int mb_y
, const int8_t *dc
)
131 int linesize
= s
->frame
.linesize
[0];
132 uint8_t *dest_y
= s
->frame
.data
[0] + (mb_y
* 16* linesize
) + mb_x
* 16;
133 uint8_t *dest_cb
= s
->frame
.data
[1] + (mb_y
* 8 * s
->frame
.linesize
[1]) + mb_x
* 8;
134 uint8_t *dest_cr
= s
->frame
.data
[2] + (mb_y
* 8 * s
->frame
.linesize
[2]) + mb_x
* 8;
135 tgq_dconly(s
,dest_y
, linesize
, dc
[0]);
136 tgq_dconly(s
,dest_y
+ 8, linesize
, dc
[1]);
137 tgq_dconly(s
,dest_y
+ 8*linesize
, linesize
, dc
[2]);
138 tgq_dconly(s
,dest_y
+ 8*linesize
+ 8, linesize
, dc
[3]);
139 if(!(s
->avctx
->flags
&CODEC_FLAG_GRAY
)) {
140 tgq_dconly(s
,dest_cb
, s
->frame
.linesize
[1], dc
[4]);
141 tgq_dconly(s
,dest_cr
, s
->frame
.linesize
[2], dc
[5]);
145 static void tgq_decode_mb(TgqContext
*s
, int mb_y
, int mb_x
){
150 mode
= bytestream2_get_byte(&s
->gb
);
153 init_get_bits(&gb
, s
->gb
.buffer
, FFMIN(s
->gb
.buffer_end
- s
->gb
.buffer
, mode
) * 8);
155 tgq_decode_block(s
, s
->block
[i
], &gb
);
156 tgq_idct_put_mb(s
, s
->block
, mb_x
, mb_y
);
157 bytestream2_skip(&s
->gb
, mode
);
160 memset(dc
, bytestream2_get_byte(&s
->gb
), 4);
161 dc
[4] = bytestream2_get_byte(&s
->gb
);
162 dc
[5] = bytestream2_get_byte(&s
->gb
);
164 bytestream2_get_buffer(&s
->gb
, dc
, 6);
165 }else if (mode
==12) {
166 for (i
= 0; i
< 6; i
++) {
167 dc
[i
] = bytestream2_get_byte(&s
->gb
);
168 bytestream2_skip(&s
->gb
, 1);
171 av_log(s
->avctx
, AV_LOG_ERROR
, "unsupported mb mode %i\n", mode
);
173 tgq_idct_put_mb_dconly(s
, mb_x
, mb_y
, dc
);
177 static void tgq_calculate_qtable(TgqContext
*s
, int quant
){
179 const int a
= (14*(100-quant
))/100 + 1;
180 const int b
= (11*(100-quant
))/100 + 4;
183 s
->qtable
[j
*8+i
] = ((a
*(j
+i
)/(7+7) + b
)*ff_inv_aanscales
[j
*8+i
])>>(14-4);
186 static int tgq_decode_frame(AVCodecContext
*avctx
,
187 void *data
, int *data_size
,
189 const uint8_t *buf
= avpkt
->data
;
190 int buf_size
= avpkt
->size
;
191 TgqContext
*s
= avctx
->priv_data
;
193 int big_endian
= AV_RL32(&buf
[4]) > 0x000FFFFF;
196 av_log(avctx
, AV_LOG_WARNING
, "truncated header\n");
199 bytestream2_init(&s
->gb
, buf
+ 8, buf_size
- 8);
201 s
->width
= bytestream2_get_be16u(&s
->gb
);
202 s
->height
= bytestream2_get_be16u(&s
->gb
);
204 s
->width
= bytestream2_get_le16u(&s
->gb
);
205 s
->height
= bytestream2_get_le16u(&s
->gb
);
208 if (s
->avctx
->width
!=s
->width
|| s
->avctx
->height
!=s
->height
) {
209 avcodec_set_dimensions(s
->avctx
, s
->width
, s
->height
);
210 if (s
->frame
.data
[0])
211 avctx
->release_buffer(avctx
, &s
->frame
);
213 tgq_calculate_qtable(s
, bytestream2_get_byteu(&s
->gb
));
214 bytestream2_skip(&s
->gb
, 3);
216 if (!s
->frame
.data
[0]) {
217 s
->frame
.key_frame
= 1;
218 s
->frame
.pict_type
= AV_PICTURE_TYPE_I
;
219 s
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
;
220 if (ff_get_buffer(avctx
, &s
->frame
)) {
221 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
226 for (y
= 0; y
< FFALIGN(avctx
->height
, 16) >> 4; y
++)
227 for (x
= 0; x
< FFALIGN(avctx
->width
, 16) >> 4; x
++)
228 tgq_decode_mb(s
, y
, x
);
230 *data_size
= sizeof(AVFrame
);
231 *(AVFrame
*)data
= s
->frame
;
236 static av_cold
int tgq_decode_end(AVCodecContext
*avctx
){
237 TgqContext
*s
= avctx
->priv_data
;
238 if (s
->frame
.data
[0])
239 s
->avctx
->release_buffer(avctx
, &s
->frame
);
243 AVCodec ff_eatgq_decoder
= {
245 .type
= AVMEDIA_TYPE_VIDEO
,
246 .id
= AV_CODEC_ID_TGQ
,
247 .priv_data_size
= sizeof(TgqContext
),
248 .init
= tgq_decode_init
,
249 .close
= tgq_decode_end
,
250 .decode
= tgq_decode_frame
,
251 .capabilities
= CODEC_CAP_DR1
,
252 .long_name
= NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),