eatgq.c
Go to the documentation of this file.
1 /*
2  * Electronic Arts TGQ Video Decoder
3  * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 /**
23  * @file
24  * Electronic Arts TGQ Video Decoder
25  * @author Peter Ross <pross@xvid.org>
26  *
27  * Technical details here:
28  * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGQ
29  */
30 
31 #include "avcodec.h"
32 #define BITSTREAM_READER_LE
33 #include "get_bits.h"
34 #include "bytestream.h"
35 #include "dsputil.h"
36 #include "aandcttab.h"
37 #include "eaidct.h"
38 #include "internal.h"
39 
40 typedef struct TgqContext {
42  int width, height;
44  int qtable[64];
45  DECLARE_ALIGNED(16, int16_t, block)[6][64];
47 } TgqContext;
48 
50 {
51  TgqContext *s = avctx->priv_data;
52  uint8_t idct_permutation[64];
53  s->avctx = avctx;
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;
58  return 0;
59 }
60 
61 static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb)
62 {
64  int i, j, value;
65  block[0] = get_sbits(gb, 8) * s->qtable[0];
66  for (i = 1; i < 64;) {
67  switch (show_bits(gb, 3)) {
68  case 4:
69  block[perm[i++]] = 0;
70  case 0:
71  block[perm[i++]] = 0;
72  skip_bits(gb, 3);
73  break;
74  case 5:
75  case 1:
76  skip_bits(gb, 2);
77  value = get_bits(gb, 6);
78  for (j = 0; j < value; j++)
79  block[perm[i++]] = 0;
80  break;
81  case 6:
82  skip_bits(gb, 3);
83  block[perm[i]] = -s->qtable[perm[i]];
84  i++;
85  break;
86  case 2:
87  skip_bits(gb, 3);
88  block[perm[i]] = s->qtable[perm[i]];
89  i++;
90  break;
91  case 7: // 111b
92  case 3: // 011b
93  skip_bits(gb, 2);
94  if (show_bits(gb, 6) == 0x3F) {
95  skip_bits(gb, 6);
96  block[perm[i]] = get_sbits(gb, 8) * s->qtable[perm[i]];
97  } else {
98  block[perm[i]] = get_sbits(gb, 6) * s->qtable[perm[i]];
99  }
100  i++;
101  break;
102  }
103  }
104  block[0] += 128 << 4;
105 }
106 
107 static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame,
108  int mb_x, int mb_y)
109 {
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;
114 
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]);
122  }
123 }
124 
125 static inline void tgq_dconly(TgqContext *s, unsigned char *dst,
126  int dst_stride, int dc)
127 {
128  int level = av_clip_uint8((dc*s->qtable[0] + 2056) >> 4);
129  int j;
130  for (j = 0; j < 8; j++)
131  memset(dst + j * dst_stride, level, 8);
132 }
133 
135  int mb_x, int mb_y, const int8_t *dc)
136 {
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]);
148  }
149 }
150 
151 static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x)
152 {
153  int mode;
154  int i;
155  int8_t dc[6];
156 
157  mode = bytestream2_get_byte(&s->gb);
158  if (mode > 12) {
160  init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), 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, frame, mb_x, mb_y);
164  bytestream2_skip(&s->gb, mode);
165  } else {
166  if (mode == 3) {
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);
176  }
177  } else {
178  av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
179  return -1;
180  }
181  tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc);
182  }
183  return 0;
184 }
185 
187 {
188  int i, j;
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);
195 }
196 
198  void *data, int *got_frame,
199  AVPacket *avpkt)
200 {
201  const uint8_t *buf = avpkt->data;
202  int buf_size = avpkt->size;
203  TgqContext *s = avctx->priv_data;
204  AVFrame *frame = data;
205  int x, y, ret;
206  int big_endian;
207 
208  if (buf_size < 16) {
209  av_log(avctx, AV_LOG_WARNING, "truncated header\n");
210  return AVERROR_INVALIDDATA;
211  }
212  big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
213  bytestream2_init(&s->gb, buf + 8, buf_size - 8);
214  if (big_endian) {
215  s->width = bytestream2_get_be16u(&s->gb);
216  s->height = bytestream2_get_be16u(&s->gb);
217  } else {
218  s->width = bytestream2_get_le16u(&s->gb);
219  s->height = bytestream2_get_le16u(&s->gb);
220  }
221 
222  if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
224  }
225  tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb));
226  bytestream2_skip(&s->gb, 3);
227 
228  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
229  return ret;
230  frame->key_frame = 1;
231  frame->pict_type = AV_PICTURE_TYPE_I;
232 
233  for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
234  for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
235  if (tgq_decode_mb(s, frame, y, x) < 0)
236  return AVERROR_INVALIDDATA;
237 
238  *got_frame = 1;
239 
240  return avpkt->size;
241 }
242 
244  .name = "eatgq",
245  .type = AVMEDIA_TYPE_VIDEO,
246  .id = AV_CODEC_ID_TGQ,
247  .priv_data_size = sizeof(TgqContext),
250  .capabilities = CODEC_CAP_DR1,
251  .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
252 };
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int height
Definition: eatgq.c:42
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static void tgq_idct_put_mb(TgqContext *s, int16_t(*block)[64], AVFrame *frame, int mb_x, int mb_y)
Definition: eatgq.c:107
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
Scantable.
Definition: dsputil.h:114
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
static void tgq_idct_put_mb_dconly(TgqContext *s, AVFrame *frame, int mb_x, int mb_y, const int8_t *dc)
Definition: eatgq.c:134
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
uint8_t permutated[64]
Definition: dsputil.h:116
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:225
static av_cold int tgq_decode_init(AVCodecContext *avctx)
Definition: eatgq.c:49
#define FFALIGN(x, a)
Definition: common.h:63
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
DECLARE_ALIGNED(16, int16_t, block)[6][64]
uint8_t
#define av_cold
Definition: attributes.h:78
mode
Definition: f_perms.c:27
static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb)
Definition: eatgq.c:61
#define b
Definition: input.c:42
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
GetByteContext gb
Definition: eatgq.c:46
uint8_t * data
const uint8_t * buffer
Definition: bytestream.h:33
bitstream reader API header.
frame
Definition: stft.m:14
Discrete Time axis x
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:159
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:258
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
int flags
CODEC_FLAG_*.
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
external API header
static void tgq_dconly(TgqContext *s, unsigned char *dst, int dst_stride, int dc)
Definition: eatgq.c:125
ScanTable scantable
Definition: eatgq.c:43
struct TgqContext TgqContext
struct AVRational AVRational
rational number numerator/denominator
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
int width
picture width / height.
static unsigned int show_bits(GetBitContext *s, int n)
Show 1-25 bits.
Definition: get_bits.h:255
#define FF_NO_IDCT_PERM
Definition: dsputil.h:251
perm
Definition: f_perms.c:74
#define AV_RL32
static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x)
Definition: eatgq.c:151
AVCodec ff_eatgq_decoder
Definition: eatgq.c:243
FIXME Range Coding of cr are level
Definition: snow.txt:367
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
const uint16_t ff_inv_aanscales[64]
Definition: aandcttab.c:38
main external API structure.
FIXME Range Coding of cr are mx and my are Motion Vector top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff)*mv_scale Intra DC Predicton block[y][x] dc[1]
Definition: snow.txt:392
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
double value
Definition: eval.c:82
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:265
synthesis window for stochastic i
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
int qtable[64]
Definition: eatgq.c:44
void ff_init_scantable_permutation(uint8_t *idct_permutation, int idct_permutation_type)
Definition: dsputil.c:131
const uint8_t * quant
AAN (Arai Agui Nakajima) (I)DCT tables.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
int width
Definition: eatgq.c:42
void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block)
Definition: eaidct.c:80
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
common internal api header.
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:115
#define CODEC_FLAG_GRAY
Only decode/encode grayscale.
function y
Definition: D.m:1
DSP utils.
void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: dsputil.c:110
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
static void tgq_calculate_qtable(TgqContext *s, int quant)
Definition: eatgq.c:186
static int tgq_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: eatgq.c:197
This structure stores compressed data.
AVCodecContext * avctx
Definition: eatgq.c:41