eatgv.c
Go to the documentation of this file.
1 /*
2  * Electronic Arts TGV Video Decoder
3  * Copyright (c) 2007-2008 Peter Ross
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 TGV Video Decoder
25  * by Peter Ross (pross@xvid.org)
26  *
27  * Technical details here:
28  * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGV
29  */
30 
31 #include "avcodec.h"
32 #define BITSTREAM_READER_LE
33 #include "get_bits.h"
34 #include "internal.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/mem.h"
37 
38 #define EA_PREAMBLE_SIZE 8
39 #define kVGT_TAG MKTAG('k', 'V', 'G', 'T')
40 
41 typedef struct TgvContext {
47 
48  int (*mv_codebook)[2];
50  int num_mvs; ///< current length of mv_codebook
51  int num_blocks_packed; ///< current length of block_codebook
52 } TgvContext;
53 
55 {
56  TgvContext *s = avctx->priv_data;
57  s->avctx = avctx;
58  avctx->time_base = (AVRational){1, 15};
59  avctx->pix_fmt = AV_PIX_FMT_PAL8;
61  return 0;
62 }
63 
64 /**
65  * Unpack buffer
66  * @return 0 on success, -1 on critical buffer underflow
67  */
68 static int unpack(const uint8_t *src, const uint8_t *src_end,
69  uint8_t *dst, int width, int height)
70 {
71  uint8_t *dst_end = dst + width*height;
72  int size, size1, size2, offset, run;
73  uint8_t *dst_start = dst;
74 
75  if (src[0] & 0x01)
76  src += 5;
77  else
78  src += 2;
79 
80  if (src_end - src < 3)
81  return AVERROR_INVALIDDATA;
82  size = AV_RB24(src);
83  src += 3;
84 
85  while (size > 0 && src < src_end) {
86 
87  /* determine size1 and size2 */
88  size1 = (src[0] & 3);
89  if (src[0] & 0x80) { // 1
90  if (src[0] & 0x40 ) { // 11
91  if (src[0] & 0x20) { // 111
92  if (src[0] < 0xFC) // !(111111)
93  size1 = (((src[0] & 31) + 1) << 2);
94  src++;
95  size2 = 0;
96  } else { // 110
97  offset = ((src[0] & 0x10) << 12) + AV_RB16(&src[1]) + 1;
98  size2 = ((src[0] & 0xC) << 6) + src[3] + 5;
99  src += 4;
100  }
101  } else { // 10
102  size1 = ((src[1] & 0xC0) >> 6);
103  offset = (AV_RB16(&src[1]) & 0x3FFF) + 1;
104  size2 = (src[0] & 0x3F) + 4;
105  src += 3;
106  }
107  } else { // 0
108  offset = ((src[0] & 0x60) << 3) + src[1] + 1;
109  size2 = ((src[0] & 0x1C) >> 2) + 3;
110  src += 2;
111  }
112 
113 
114  /* fetch strip from src */
115  if (size1 > src_end - src)
116  break;
117 
118  if (size1 > 0) {
119  size -= size1;
120  run = FFMIN(size1, dst_end - dst);
121  memcpy(dst, src, run);
122  dst += run;
123  src += run;
124  }
125 
126  if (size2 > 0) {
127  if (dst - dst_start < offset)
128  return 0;
129  size -= size2;
130  run = FFMIN(size2, dst_end - dst);
131  av_memcpy_backptr(dst, offset, run);
132  dst += run;
133  }
134  }
135 
136  return 0;
137 }
138 
139 /**
140  * Decode inter-frame
141  * @return 0 on success, -1 on critical buffer underflow
142  */
144  const uint8_t *buf, const uint8_t *buf_end)
145 {
146  int num_mvs;
147  int num_blocks_raw;
148  int num_blocks_packed;
149  int vector_bits;
150  int i,j,x,y;
151  GetBitContext gb;
152  int mvbits;
153  const uint8_t *blocks_raw;
154 
155  if(buf_end - buf < 12)
156  return AVERROR_INVALIDDATA;
157 
158  num_mvs = AV_RL16(&buf[0]);
159  num_blocks_raw = AV_RL16(&buf[2]);
160  num_blocks_packed = AV_RL16(&buf[4]);
161  vector_bits = AV_RL16(&buf[6]);
162  buf += 12;
163 
164  if (vector_bits > MIN_CACHE_BITS || !vector_bits) {
166  "Invalid value for motion vector bits: %d\n", vector_bits);
167  return AVERROR_INVALIDDATA;
168  }
169 
170  /* allocate codebook buffers as necessary */
171  if (num_mvs > s->num_mvs) {
172  s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int));
173  s->num_mvs = num_mvs;
174  }
175 
176  if (num_blocks_packed > s->num_blocks_packed) {
177  s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16);
179  }
180 
181  /* read motion vectors */
182  mvbits = (num_mvs * 2 * 10 + 31) & ~31;
183 
184  if (buf_end - buf < (mvbits>>3) + 16*num_blocks_raw + 8*num_blocks_packed)
185  return AVERROR_INVALIDDATA;
186 
187  init_get_bits(&gb, buf, mvbits);
188  for (i = 0; i < num_mvs; i++) {
189  s->mv_codebook[i][0] = get_sbits(&gb, 10);
190  s->mv_codebook[i][1] = get_sbits(&gb, 10);
191  }
192  buf += mvbits >> 3;
193 
194  /* note ptr to uncompressed blocks */
195  blocks_raw = buf;
196  buf += num_blocks_raw * 16;
197 
198  /* read compressed blocks */
199  init_get_bits(&gb, buf, (buf_end - buf) << 3);
200  for (i = 0; i < num_blocks_packed; i++) {
201  int tmp[4];
202  for (j = 0; j < 4; j++)
203  tmp[j] = get_bits(&gb, 8);
204  for (j = 0; j < 16; j++)
205  s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];
206  }
207 
208  if (get_bits_left(&gb) < vector_bits *
209  (s->avctx->height / 4) * (s->avctx->width / 4))
210  return AVERROR_INVALIDDATA;
211 
212  /* read vectors and build frame */
213  for (y = 0; y < s->avctx->height / 4; y++)
214  for (x = 0; x < s->avctx->width / 4; x++) {
215  unsigned int vector = get_bits(&gb, vector_bits);
216  const uint8_t *src;
217  int src_stride;
218 
219  if (vector < num_mvs) {
220  int mx = x * 4 + s->mv_codebook[vector][0];
221  int my = y * 4 + s->mv_codebook[vector][1];
222 
223  if (mx < 0 || mx + 4 > s->avctx->width ||
224  my < 0 || my + 4 > s->avctx->height) {
225  av_log(s->avctx, AV_LOG_ERROR, "MV %d %d out of picture\n", mx, my);
226  continue;
227  }
228 
229  src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];
230  src_stride = s->last_frame.linesize[0];
231  } else {
232  int offset = vector - num_mvs;
233  if (offset < num_blocks_raw)
234  src = blocks_raw + 16*offset;
235  else if (offset - num_blocks_raw < num_blocks_packed)
236  src = s->block_codebook[offset - num_blocks_raw];
237  else
238  continue;
239  src_stride = 4;
240  }
241 
242  for (j = 0; j < 4; j++)
243  for (i = 0; i < 4; i++)
244  frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4 + i)] =
245  src[j * src_stride + i];
246  }
247 
248  return 0;
249 }
250 
252  void *data, int *got_frame,
253  AVPacket *avpkt)
254 {
255  const uint8_t *buf = avpkt->data;
256  int buf_size = avpkt->size;
257  TgvContext *s = avctx->priv_data;
258  const uint8_t *buf_end = buf + buf_size;
259  AVFrame *frame = data;
260  int chunk_type, ret;
261 
262  if (buf_end - buf < EA_PREAMBLE_SIZE)
263  return AVERROR_INVALIDDATA;
264 
265  chunk_type = AV_RL32(&buf[0]);
266  buf += EA_PREAMBLE_SIZE;
267 
268  if (chunk_type == kVGT_TAG) {
269  int pal_count, i;
270  if(buf_end - buf < 12) {
271  av_log(avctx, AV_LOG_WARNING, "truncated header\n");
272  return AVERROR_INVALIDDATA;
273  }
274 
275  s->width = AV_RL16(&buf[0]);
276  s->height = AV_RL16(&buf[2]);
277  if (s->avctx->width != s->width || s->avctx->height != s->height) {
279  av_freep(&s->frame_buffer);
281  }
282 
283  pal_count = AV_RL16(&buf[6]);
284  buf += 12;
285  for(i = 0; i < pal_count && i < AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
286  s->palette[i] = 0xFFU << 24 | AV_RB24(buf);
287  buf += 3;
288  }
289  }
290 
291  if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0)
292  return ret;
293 
294  if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
295  return ret;
296 
297  memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
298 
299  if (chunk_type == kVGT_TAG) {
300  int y;
301  frame->key_frame = 1;
302  frame->pict_type = AV_PICTURE_TYPE_I;
303 
304  if (!s->frame_buffer &&
305  !(s->frame_buffer = av_malloc(s->width * s->height)))
306  return AVERROR(ENOMEM);
307 
308  if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) {
309  av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");
310  return AVERROR_INVALIDDATA;
311  }
312  for (y = 0; y < s->height; y++)
313  memcpy(frame->data[0] + y * frame->linesize[0],
314  s->frame_buffer + y * s->width,
315  s->width);
316  } else {
317  if (!s->last_frame.data[0]) {
318  av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");
319  return buf_size;
320  }
321  frame->key_frame = 0;
322  frame->pict_type = AV_PICTURE_TYPE_P;
323  if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {
324  av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
325  return AVERROR_INVALIDDATA;
326  }
327  }
328 
330  if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
331  return ret;
332 
333  *got_frame = 1;
334 
335  return buf_size;
336 }
337 
339 {
340  TgvContext *s = avctx->priv_data;
342  av_freep(&s->frame_buffer);
343  av_free(s->mv_codebook);
345  return 0;
346 }
347 
349  .name = "eatgv",
350  .type = AVMEDIA_TYPE_VIDEO,
351  .id = AV_CODEC_ID_TGV,
352  .priv_data_size = sizeof(TgvContext),
356  .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
357  .capabilities = CODEC_CAP_DR1,
358 };
int height
Definition: eatgv.c:45
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
misc image utilities
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
int width
Definition: eatgv.c:45
memory handling functions
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
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
#define AV_RB24
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define AV_RL16
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:141
uint8_t run
Definition: svq3.c:136
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:225
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
uint8_t
#define av_cold
Definition: attributes.h:78
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
#define kVGT_TAG
Definition: eatgv.c:39
AVCodecContext * avctx
Definition: eatgv.c:42
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
bitstream reader API header.
frame
Definition: stft.m:14
Discrete Time axis x
int(* mv_codebook)[2]
Definition: eatgv.c:48
#define U(x)
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:557
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
#define AV_RB16
static av_cold int tgv_decode_end(AVCodecContext *avctx)
Definition: eatgv.c:338
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
int num_mvs
current length of mv_codebook
Definition: eatgv.c:50
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
external API header
int size
struct AVRational AVRational
rational number numerator/denominator
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:231
uint32_t palette[AVPALETTE_COUNT]
Definition: eatgv.c:46
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
#define FFMIN(a, b)
Definition: common.h:58
uint8_t(* block_codebook)[16]
Definition: eatgv.c:49
ret
Definition: avfilter.c:821
int width
picture width / height.
#define AV_RL32
AVCodec ff_eatgv_decoder
Definition: eatgv.c:348
uint8_t * frame_buffer
Definition: eatgv.c:44
int num_blocks_packed
current length of block_codebook
Definition: eatgv.c:51
#define EA_PREAMBLE_SIZE
Definition: eatgv.c:38
AVS_Value src
Definition: avisynth_c.h:523
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
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
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
void avcodec_get_frame_defaults(AVFrame *frame)
Set the fields of the given AVFrame to default values.
static int tgv_decode_inter(TgvContext *s, AVFrame *frame, const uint8_t *buf, const uint8_t *buf_end)
Decode inter-frame.
Definition: eatgv.c:143
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
static av_cold int tgv_decode_init(AVCodecContext *avctx)
Definition: eatgv.c:54
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:330
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define AVPALETTE_COUNT
Definition: pixfmt.h:34
struct TgvContext TgvContext
#define MIN_CACHE_BITS
Definition: get_bits.h:122
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
static int unpack(const uint8_t *src, const uint8_t *src_end, uint8_t *dst, int width, int height)
Unpack buffer.
Definition: eatgv.c:68
common internal api header.
function y
Definition: D.m:1
AVFrame last_frame
Definition: eatgv.c:43
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
deliberately overlapping memcpy implementation
Definition: mem.c:327
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
static int tgv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: eatgv.c:251
This structure stores compressed data.
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Predicted.
Definition: avutil.h:217