History

avcodec/eatgq: decode motion vector macroblocks

Peter Ross committed 2 years ago

Commit 2f34b151 parent 10c02de2 files · +51 −5Browse files

Showing the changes to libavcodec (2 of 2 files). Show all

Unified · Split

2 files
  1. libavcodec/codec_desc.c +1 −1
  2. libavcodec/eatgq.c +50 −4
libavcodec/codec_desc.c+1−1
@@ -905,7 +905,7 @@ static const AVCodecDescriptor codec_descriptors[] = { · 904 unmodified lines
905 .type = AVMEDIA_TYPE_VIDEO,905 .type = AVMEDIA_TYPE_VIDEO,
906 .name = "tgq",906 .name = "tgq",
907 .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),907 .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
908 .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,908 .props = AV_CODEC_PROP_LOSSY,
909 },909 },
910 {910 {
911 .id = AV_CODEC_ID_TQI,911 .id = AV_CODEC_ID_TQI,
libavcodec/eatgq.c+50−4
@@ -36,12 +36,14 @@ · 35 unmodified lines
36#include "avcodec.h"36#include "avcodec.h"
37#include "bytestream.h"37#include "bytestream.h"
38#include "codec_internal.h"38#include "codec_internal.h"
39#include "copy_block.h"
39#include "decode.h"40#include "decode.h"
40#include "eaidct.h"41#include "eaidct.h"
41#include "get_bits.h"42#include "get_bits.h"
42 43
43typedef struct TgqContext {44typedef struct TgqContext {
44 AVCodecContext *avctx;45 AVCodecContext *avctx;
46 AVFrame *last_frame;
45 int width, height;47 int width, height;
46 int qtable[64];48 int qtable[64];
47 DECLARE_ALIGNED(16, int16_t, block)[6][64];49 DECLARE_ALIGNED(16, int16_t, block)[6][64];
@@ -53,6 +55,9 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) · 5 unmodified lines
53 s->avctx = avctx;55 s->avctx = avctx;
54 avctx->framerate = (AVRational){ 15, 1 };56 avctx->framerate = (AVRational){ 15, 1 };
55 avctx->pix_fmt = AV_PIX_FMT_YUV420P;57 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
58 s->last_frame = av_frame_alloc();
59 if (!s->last_frame)
60 return AVERROR(ENOMEM);
56 return 0;61 return 0;
57}62}
58 63
@@ -173,7 +178,33 @@ static int tgq_decode_mb(TgqContext *s, GetByteContext *gbyte, · 114 unmodified lines
173 tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y);178 tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y);
174 bytestream2_skip(gbyte, mode);179 bytestream2_skip(gbyte, mode);
175 } else {180 } else {
176 if (mode == 3) {181 if (mode == 1) {
182 int x, y;
183 int mv = bytestream2_get_byte(gbyte);
184 int mv_x = mv >> 4;
185 int mv_y = mv & 0x0F;
186 if (!s->last_frame->data[0]) {
187 av_log(s->avctx, AV_LOG_ERROR, "missing reference frame\n");
188 return -1;
189 }
190 if (mv_x >= 8) mv_x -= 16;
191 if (mv_y >= 8) mv_y -= 16;
192 x = mb_x * 16 - mv_x;
193 y = mb_y * 16 - mv_y;
194 if (x < 0 || x + 16 > s->width || y < 0 || y + 16 > s->height) {
195 av_log(s->avctx, AV_LOG_ERROR, "invalid motion vector\n");
196 return -1;
197 }
198 copy_block16(frame->data[0] + (mb_y * 16 * frame->linesize[0]) + mb_x * 16,
199 s->last_frame->data[0] + y * s->last_frame->linesize[0] + x,
200 frame->linesize[0], s->last_frame->linesize[0], 16);
201 for (int p = 1; p < 3; p++)
202 copy_block8(frame->data[p] + (mb_y * 8 * frame->linesize[p]) + mb_x * 8,
203 s->last_frame->data[p] + (y >> 1) * s->last_frame->linesize[p] + (x >> 1),
204 frame->linesize[p], s->last_frame->linesize[p], 8);
205 frame->flags &= ~AV_FRAME_FLAG_KEY;
206 return 0;
207 } else if (mode == 3) {
177 memset(dc, bytestream2_get_byte(gbyte), 4);208 memset(dc, bytestream2_get_byte(gbyte), 4);
178 dc[4] = bytestream2_get_byte(gbyte);209 dc[4] = bytestream2_get_byte(gbyte);
179 dc[5] = bytestream2_get_byte(gbyte);210 dc[5] = bytestream2_get_byte(gbyte);
@@ -228,9 +259,12 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVFrame *frame, · 48 unmodified lines
228 s->height = bytestream2_get_le16u(&gbyte);259 s->height = bytestream2_get_le16u(&gbyte);
229 }260 }
230 261
231 ret = ff_set_dimensions(s->avctx, s->width, s->height);262 if (s->avctx->width != s->width || s->avctx->height != s->height) {
232 if (ret < 0)263 av_frame_unref(s->last_frame);
233 return ret;264 ret = ff_set_dimensions(s->avctx, s->width, s->height);
265 if (ret < 0)
266 return ret;
267 }
234 268
235 tgq_calculate_qtable(s, bytestream2_get_byteu(&gbyte));269 tgq_calculate_qtable(s, bytestream2_get_byteu(&gbyte));
236 bytestream2_skipu(&gbyte, 3);270 bytestream2_skipu(&gbyte, 3);
@@ -238,16 +272,27 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVFrame *frame, · 1 unmodified line
238 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)272 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
239 return ret;273 return ret;
240 274
275 frame->flags |= AV_FRAME_FLAG_KEY;
241 for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)276 for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
242 for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)277 for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
243 if (tgq_decode_mb(s, &gbyte, frame, y, x) < 0)278 if (tgq_decode_mb(s, &gbyte, frame, y, x) < 0)
244 return AVERROR_INVALIDDATA;279 return AVERROR_INVALIDDATA;
245 280
281 if ((ret = av_frame_replace(s->last_frame, frame)) < 0)
282 return ret;
283
246 *got_frame = 1;284 *got_frame = 1;
247 285
248 return avpkt->size;286 return avpkt->size;
249}287}
250 288
289static av_cold int tgq_decode_close(AVCodecContext *avctx)
290{
291 TgqContext *s = avctx->priv_data;
292 av_frame_free(&s->last_frame);
293 return 0;
294}
295
251const FFCodec ff_eatgq_decoder = {296const FFCodec ff_eatgq_decoder = {
252 .p.name = "eatgq",297 .p.name = "eatgq",
253 CODEC_LONG_NAME("Electronic Arts TGQ video"),298 CODEC_LONG_NAME("Electronic Arts TGQ video"),
@@ -255,6 +300,7 @@ const FFCodec ff_eatgq_decoder = { · 1 unmodified line
255 .p.id = AV_CODEC_ID_TGQ,300 .p.id = AV_CODEC_ID_TGQ,
256 .priv_data_size = sizeof(TgqContext),301 .priv_data_size = sizeof(TgqContext),
257 .init = tgq_decode_init,302 .init = tgq_decode_init,
303 .close = tgq_decode_close,
258 FF_CODEC_DECODE_CB(tgq_decode_frame),304 FF_CODEC_DECODE_CB(tgq_decode_frame),
259 .p.capabilities = AV_CODEC_CAP_DR1,305 .p.capabilities = AV_CODEC_CAP_DR1,
260};306};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t