History

avcodec: add Amuse Graphics decoder

This work is sponsored by VideoLAN.

Paul B Mahol committed 8 years ago

Commit 4e8cbbf1 parent 52d8f358 files · +668 −2Browse files

Unified · Split

8 files
  1. Changelog +1 −0
  2. libavcodec/Makefile +1 −0
  3. libavcodec/agm.c +653 −0
  4. libavcodec/allcodecs.c +1 −0
  5. libavcodec/avcodec.h +1 −0
  6. libavcodec/codec_desc.c +7 −0
  7. libavcodec/version.h +2 −2
  8. libavformat/riff.c +2 −0
Changelog+1−0
@@ -20,6 +20,7 @@ version <next>: · 19 unmodified lines
2020 - libaribb24 based ARIB STD-B24 caption support (profiles A and C)
2121 - Support decoding of HEVC 4:4:4 content in nvdec and cuviddec
2222 - removed libndi-newtek
23+- agm decoder
2324
2425
2526 version 4.1:
libavcodec/Makefile+1−0
@@ -173,6 +173,7 @@ OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbd · 172 unmodified lines
173173 OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \
174174 ac3.o kbdwin.o
175175 OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
176+OBJS-$(CONFIG_AGM_DECODER) += agm.o
176177 OBJS-$(CONFIG_AIC_DECODER) += aic.o
177178 OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o
178179 OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o
libavcodec/agm.c+653−0
@@ -0,0 +1,653 @@
1+/*
2+ * Amuse Graphics Movie decoder
3+ *
4+ * Copyright (c) 2018 Paul B Mahol
5+ *
6+ * This file is part of FFmpeg.
7+ *
8+ * FFmpeg is free software; you can redistribute it and/or
9+ * modify it under the terms of the GNU Lesser General Public
10+ * License as published by the Free Software Foundation; either
11+ * version 2.1 of the License, or (at your option) any later version.
12+ *
13+ * FFmpeg is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+ * Lesser General Public License for more details.
17+ *
18+ * You should have received a copy of the GNU Lesser General Public
19+ * License along with FFmpeg; if not, write to the Free Software
20+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+ */
22+
23+#include <stdio.h>
24+#include <stdlib.h>
25+#include <string.h>
26+
27+#define BITSTREAM_READER_LE
28+
29+#include "avcodec.h"
30+#include "bytestream.h"
31+#include "copy_block.h"
32+#include "get_bits.h"
33+#include "idctdsp.h"
34+#include "internal.h"
35+
36+static const uint8_t unscaled_luma[64] = {
37+ 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19,
38+ 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56,
39+ 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56,
40+ 68,109,103, 77, 24, 35, 55, 64, 81,104,113, 92,
41+ 49, 64, 78, 87,103,121,120,101, 72, 92, 95, 98,
42+ 112,100,103,99
43+};
44+
45+static const uint8_t unscaled_chroma[64] = {
46+ 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66,
47+ 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
48+ 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
49+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
50+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
51+ 99, 99, 99, 99
52+};
53+
54+typedef struct MotionVector {
55+ int16_t x, y;
56+} MotionVector;
57+
58+typedef struct AGMContext {
59+ const AVClass *class;
60+ AVCodecContext *avctx;
61+ GetBitContext gb;
62+ GetByteContext gbyte;
63+
64+ int key_frame;
65+ int bitstream_size;
66+ int compression;
67+ int blocks_w;
68+ int blocks_h;
69+ int size[3];
70+ int plus;
71+ unsigned flags;
72+ unsigned fflags;
73+
74+ MotionVector *mvectors;
75+ int mvectors_size;
76+
77+ AVFrame *prev_frame;
78+
79+ int luma_quant_matrix[64];
80+ int chroma_quant_matrix[64];
81+
82+ ScanTable scantable;
83+ DECLARE_ALIGNED(32, int16_t, block)[64];
84+ IDCTDSPContext idsp;
85+} AGMContext;
86+
87+static int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mode)
88+{
89+ int len = 0, skip = 0, max;
90+
91+ if (show_bits(gb, 2)) {
92+ switch (show_bits(gb, 4)) {
93+ case 1:
94+ case 9:
95+ len = 1;
96+ skip = 3;
97+ break;
98+ case 2:
99+ len = 3;
100+ skip = 4;
101+ break;
102+ case 3:
103+ len = 7;
104+ skip = 4;
105+ break;
106+ case 5:
107+ case 13:
108+ len = 2;
109+ skip = 3;
110+ break;
111+ case 6:
112+ len = 4;
113+ skip = 4;
114+ break;
115+ case 7:
116+ len = 8;
117+ skip = 4;
118+ break;
119+ case 10:
120+ len = 5;
121+ skip = 4;
122+ break;
123+ case 11:
124+ len = 9;
125+ skip = 4;
126+ break;
127+ case 14:
128+ len = 6;
129+ skip = 4;
130+ break;
131+ case 15:
132+ len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4;
133+ skip = 5;
134+ break;
135+ default:
136+ return AVERROR_INVALIDDATA;
137+ }
138+
139+ skip_bits(gb, skip);
140+ *level = get_bits(gb, len);
141+ *map = 1;
142+ *oskip = 0;
143+ max = 1 << (len - 1);
144+ if (*level < max)
145+ *level = -(max + *level);
146+ } else if (show_bits(gb, 3) & 4) {
147+ skip_bits(gb, 3);
148+ if (mode == 1) {
149+ if (show_bits(gb, 4)) {
150+ if (show_bits(gb, 4) == 1) {
151+ skip_bits(gb, 4);
152+ *oskip = get_bits(gb, 16);
153+ } else {
154+ *oskip = get_bits(gb, 4);
155+ }
156+ } else {
157+ skip_bits(gb, 4);
158+ *oskip = get_bits(gb, 10);
159+ }
160+ } else if (mode == 0) {
161+ *oskip = get_bits(gb, 10);
162+ }
163+ *level = 0;
164+ } else {
165+ skip_bits(gb, 3);
166+ if (mode == 0)
167+ *oskip = get_bits(gb, 4);
168+ else if (mode == 1)
169+ *oskip = 0;
170+ *level = 0;
171+ }
172+
173+ return 0;
174+}
175+
176+static int decode_intra_block(AGMContext *s, GetBitContext *gb, int size,
177+ const int *quant_matrix, int *skip, int *dc_level)
178+{
179+ const uint8_t *scantable = s->scantable.permutated;
180+ const int offset = s->plus ? 0 : 1024;
181+ int16_t *block = s->block;
182+ int level, ret, map = 0;
183+
184+ memset(block, 0, sizeof(s->block));
185+
186+ if (*skip > 0) {
187+ (*skip)--;
188+ } else {
189+ ret = read_code(gb, skip, &level, &map, s->flags & 1);
190+ if (ret < 0)
191+ return ret;
192+ *dc_level += level;
193+ }
194+ block[scantable[0]] = offset + *dc_level * quant_matrix[0];
195+
196+ for (int i = 1; i < 64;) {
197+ if (*skip > 0) {
198+ int rskip;
199+
200+ rskip = FFMIN(*skip, 64 - i);
201+ i += rskip;
202+ *skip -= rskip;
203+ } else {
204+ ret = read_code(gb, skip, &level, &map, s->flags & 1);
205+ if (ret < 0)
206+ return ret;
207+
208+ block[scantable[i]] = level * quant_matrix[i];
209+ i++;
210+ }
211+ }
212+
213+ return 0;
214+}
215+
216+static int decode_intra_plane(AGMContext *s, GetBitContext *gb, int size,
217+ const int *quant_matrix, AVFrame *frame,
218+ int plane)
219+{
220+ int ret, skip = 0, dc_level = 0;
221+
222+ if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0)
223+ return ret;
224+
225+ for (int y = 0; y < s->blocks_h; y++) {
226+ for (int x = 0; x < s->blocks_w; x++) {
227+ ret = decode_intra_block(s, gb, size, quant_matrix, &skip, &dc_level);
228+ if (ret < 0)
229+ return ret;
230+
231+ s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
232+ frame->linesize[plane], s->block);
233+ }
234+ }
235+
236+ align_get_bits(gb);
237+ if (get_bits_left(gb) < 0)
238+ av_log(s->avctx, AV_LOG_WARNING, "overread\n");
239+ if (get_bits_left(gb) > 0)
240+ av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb));
241+
242+ return 0;
243+}
244+
245+static int decode_inter_block(AGMContext *s, GetBitContext *gb, int size,
246+ const int *quant_matrix, int *skip,
247+ int *map)
248+{
249+ const uint8_t *scantable = s->scantable.permutated;
250+ int16_t *block = s->block;
251+ int level, ret;
252+
253+ memset(block, 0, sizeof(s->block));
254+
255+ for (int i = 0; i < 64;) {
256+ if (*skip > 0) {
257+ int rskip;
258+
259+ rskip = FFMIN(*skip, 64 - i);
260+ i += rskip;
261+ *skip -= rskip;
262+ } else {
263+ ret = read_code(gb, skip, &level, map, s->flags & 1);
264+ if (ret < 0)
265+ return ret;
266+
267+ block[scantable[i]] = level * quant_matrix[i];
268+ i++;
269+ }
270+ }
271+
272+ return 0;
273+}
274+
275+static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size,
276+ const int *quant_matrix, AVFrame *frame,
277+ AVFrame *prev, int plane)
278+{
279+ int ret, skip = 0;
280+
281+ if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0)
282+ return ret;
283+
284+ if (s->flags & 2) {
285+ for (int y = 0; y < s->blocks_h; y++) {
286+ for (int x = 0; x < s->blocks_w; x++) {
287+ int shift = plane == 0;
288+ int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift);
289+ int orig_mv_x = s->mvectors[mvpos].x;
290+ int mv_x = s->mvectors[mvpos].x / (1 + !shift);
291+ int mv_y = s->mvectors[mvpos].y / (1 + !shift);
292+ int h = s->avctx->coded_height >> !shift;
293+ int w = s->avctx->coded_width >> !shift;
294+ int map = 0;
295+
296+ ret = decode_inter_block(s, gb, size, quant_matrix, &skip, &map);
297+ if (ret < 0)
298+ return ret;
299+
300+ if (orig_mv_x >= -32) {
301+ if (y * 8 + mv_y < 0 || y * 8 + mv_y >= h ||
302+ x * 8 + mv_x < 0 || x * 8 + mv_x >= w)
303+ return AVERROR_INVALIDDATA;
304+
305+ copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
306+ prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x),
307+ frame->linesize[plane], prev->linesize[plane], 8);
308+ if (map) {
309+ s->idsp.idct(s->block);
310+ for (int i = 0; i < 64; i++)
311+ s->block[i] = (s->block[i] + 1) & 0xFFFC;
312+ s->idsp.add_pixels_clamped(s->block, frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
313+ frame->linesize[plane]);
314+ }
315+ } else if (map) {
316+ s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
317+ frame->linesize[plane], s->block);
318+ }
319+ }
320+ }
321+ } else {
322+ for (int y = 0; y < s->blocks_h; y++) {
323+ for (int x = 0; x < s->blocks_w; x++) {
324+ int map = 0;
325+
326+ ret = decode_inter_block(s, gb, size, quant_matrix, &skip, &map);
327+ if (ret < 0)
328+ return ret;
329+
330+ if (!map)
331+ continue;
332+ s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
333+ frame->linesize[plane], s->block);
334+ }
335+ }
336+ }
337+
338+ align_get_bits(gb);
339+ if (get_bits_left(gb) < 0)
340+ av_log(s->avctx, AV_LOG_WARNING, "overread\n");
341+ if (get_bits_left(gb) > 0)
342+ av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb));
343+
344+ return 0;
345+}
346+
347+static void compute_quant_matrix(AGMContext *s, double qscale)
348+{
349+ int luma[64], chroma[64];
350+ double f = 1.0 - fabs(qscale);
351+
352+ if (!s->key_frame && (s->flags & 2)) {
353+ if (qscale >= 0.0) {
354+ for (int i = 0; i < 64; i++) {
355+ luma[i] = FFMAX(1, 16 * f);
356+ chroma[i] = FFMAX(1, 16 * f);
357+ }
358+ } else {
359+ for (int i = 0; i < 64; i++) {
360+ luma[i] = FFMAX(1, 16 - qscale * 32);
361+ chroma[i] = FFMAX(1, 16 - qscale * 32);
362+ }
363+ }
364+ } else {
365+ if (qscale >= 0.0) {
366+ for (int i = 0; i < 64; i++) {
367+ luma[i] = FFMAX(1, unscaled_luma [(i & 7) * 8 + (i >> 3)] * f);
368+ chroma[i] = FFMAX(1, unscaled_chroma[(i & 7) * 8 + (i >> 3)] * f);
369+ }
370+ } else {
371+ for (int i = 0; i < 64; i++) {
372+ luma[i] = FFMAX(1, 255.0 - (255 - unscaled_luma [(i & 7) * 8 + (i >> 3)]) * f);
373+ chroma[i] = FFMAX(1, 255.0 - (255 - unscaled_chroma[(i & 7) * 8 + (i >> 3)]) * f);
374+ }
375+ }
376+ }
377+
378+ for (int i = 0; i < 64; i++) {
379+ int pos = ff_zigzag_direct[i];
380+
381+ s->luma_quant_matrix[i] = luma[pos] * ((pos / 8) & 1 ? -1 : 1);
382+ s->chroma_quant_matrix[i] = chroma[pos] * ((pos / 8) & 1 ? -1 : 1);
383+ }
384+}
385+
386+static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
387+{
388+ AGMContext *s = avctx->priv_data;
389+ int ret;
390+
391+ compute_quant_matrix(s, (2 * s->compression - 100) / 100.0);
392+
393+ s->blocks_w = avctx->coded_width >> 3;
394+ s->blocks_h = avctx->coded_height >> 3;
395+
396+ ret = decode_intra_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, 0);
397+ if (ret < 0)
398+ return ret;
399+
400+ bytestream2_skip(&s->gbyte, s->size[0]);
401+
402+ s->blocks_w = avctx->coded_width >> 4;
403+ s->blocks_h = avctx->coded_height >> 4;
404+
405+ ret = decode_intra_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, 2);
406+ if (ret < 0)
407+ return ret;
408+
409+ bytestream2_skip(&s->gbyte, s->size[1]);
410+
411+ s->blocks_w = avctx->coded_width >> 4;
412+ s->blocks_h = avctx->coded_height >> 4;
413+
414+ ret = decode_intra_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, 1);
415+ if (ret < 0)
416+ return ret;
417+
418+ return 0;
419+}
420+
421+static int decode_motion_vectors(AVCodecContext *avctx, GetBitContext *gb)
422+{
423+ AGMContext *s = avctx->priv_data;
424+ int nb_mvs = ((avctx->height + 15) >> 4) * ((avctx->width + 15) >> 4);
425+ int ret, skip = 0, value, map;
426+
427+ av_fast_padded_malloc(&s->mvectors, &s->mvectors_size,
428+ nb_mvs * sizeof(*s->mvectors));
429+ if (!s->mvectors)
430+ return AVERROR(ENOMEM);
431+
432+ if ((ret = init_get_bits8(gb, s->gbyte.buffer, bytestream2_get_bytes_left(&s->gbyte) -
433+ (s->size[0] + s->size[1] + s->size[2]))) < 0)
434+ return ret;
435+
436+ memset(s->mvectors, 0, sizeof(*s->mvectors) * nb_mvs);
437+
438+ for (int i = 0; i < nb_mvs; i++) {
439+ ret = read_code(gb, &skip, &value, &map, 1);
440+ if (ret < 0)
441+ return ret;
442+ s->mvectors[i].x = value;
443+ i += skip;
444+ }
445+
446+ for (int i = 0; i < nb_mvs; i++) {
447+ ret = read_code(gb, &skip, &value, &map, 1);
448+ if (ret < 0)
449+ return ret;
450+ s->mvectors[i].y = value;
451+ i += skip;
452+ }
453+
454+ if (get_bits_left(gb) <= 0)
455+ return AVERROR_INVALIDDATA;
456+ skip = (get_bits_count(gb) >> 3) + 1;
457+ bytestream2_skip(&s->gbyte, skip);
458+
459+ return 0;
460+}
461+
462+static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
463+ AVFrame *frame, AVFrame *prev)
464+{
465+ AGMContext *s = avctx->priv_data;
466+ int ret;
467+
468+ compute_quant_matrix(s, (2 * s->compression - 100) / 100.0);
469+
470+ if (s->flags & 2) {
471+ ret = decode_motion_vectors(avctx, gb);
472+ if (ret < 0)
473+ return ret;
474+ }
475+
476+ s->blocks_w = avctx->coded_width >> 3;
477+ s->blocks_h = avctx->coded_height >> 3;
478+
479+ ret = decode_inter_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, prev, 0);
480+ if (ret < 0)
481+ return ret;
482+
483+ bytestream2_skip(&s->gbyte, s->size[0]);
484+
485+ s->blocks_w = avctx->coded_width >> 4;
486+ s->blocks_h = avctx->coded_height >> 4;
487+
488+ ret = decode_inter_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, prev, 2);
489+ if (ret < 0)
490+ return ret;
491+
492+ bytestream2_skip(&s->gbyte, s->size[1]);
493+
494+ s->blocks_w = avctx->coded_width >> 4;
495+ s->blocks_h = avctx->coded_height >> 4;
496+
497+ ret = decode_inter_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, prev, 1);
498+ if (ret < 0)
499+ return ret;
500+
501+ return 0;
502+}
503+
504+static int decode_frame(AVCodecContext *avctx, void *data,
505+ int *got_frame, AVPacket *avpkt)
506+{
507+ AGMContext *s = avctx->priv_data;
508+ GetBitContext *gb = &s->gb;
509+ GetByteContext *gbyte = &s->gbyte;
510+ AVFrame *frame = data;
511+ int w, h, width, height, header;
512+ int ret;
513+
514+ if (!avpkt->size)
515+ return 0;
516+
517+ bytestream2_init(gbyte, avpkt->data, avpkt->size);
518+
519+ header = bytestream2_get_le32(gbyte);
520+ s->fflags = bytestream2_get_le32(gbyte);
521+ s->bitstream_size = s->fflags & 0x1FFFFFFF;
522+ s->fflags >>= 29;
523+ av_log(avctx, AV_LOG_DEBUG, "fflags: %X\n", s->fflags);
524+ if (avpkt->size < s->bitstream_size + 8)
525+ return AVERROR_INVALIDDATA;
526+
527+ s->key_frame = s->fflags & 0x1;
528+ frame->key_frame = s->key_frame;
529+ frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
530+
531+ if (header) {
532+ av_log(avctx, AV_LOG_ERROR, "header: %X\n", header);
533+ return AVERROR_PATCHWELCOME;
534+ }
535+
536+ s->flags = 0;
537+ w = bytestream2_get_le32(gbyte);
538+ if (w < 0) {
539+ w = -w;
540+ s->flags |= 2;
541+ }
542+ h = bytestream2_get_le32(gbyte);
543+ if (h < 0) {
544+ h = -h;
545+ s->flags |= 1;
546+ }
547+
548+ width = avctx->width;
549+ height = avctx->height;
550+ if (w < width || h < height || w & 7 || h & 7)
551+ return AVERROR_INVALIDDATA;
552+
553+ ret = ff_set_dimensions(avctx, w, h);
554+ if (ret < 0)
555+ return ret;
556+ avctx->width = width;
557+ avctx->height = height;
558+
559+ s->compression = bytestream2_get_le32(gbyte);
560+ if (s->compression < 0 || s->compression > 100)
561+ return AVERROR_INVALIDDATA;
562+
563+ for (int i = 0; i < 3; i++)
564+ s->size[i] = bytestream2_get_le32(gbyte);
565+ if (32LL + s->size[0] + s->size[1] + s->size[2] > avpkt->size)
566+ return AVERROR_INVALIDDATA;
567+
568+ if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
569+ return ret;
570+
571+ if (frame->key_frame) {
572+ ret = decode_intra(avctx, gb, frame);
573+ } else {
574+ if (!s->prev_frame->data[0]) {
575+ av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
576+ return AVERROR_INVALIDDATA;
577+ }
578+
579+ if (!(s->flags & 2)) {
580+ ret = av_frame_copy(frame, s->prev_frame);
581+ if (ret < 0)
582+ return ret;
583+ }
584+
585+ ret = decode_inter(avctx, gb, frame, s->prev_frame);
586+ }
587+ if (ret < 0)
588+ return ret;
589+
590+ av_frame_unref(s->prev_frame);
591+ if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
592+ return ret;
593+
594+ frame->crop_top = avctx->coded_height - avctx->height;
595+ frame->crop_left = avctx->coded_width - avctx->width;
596+
597+ *got_frame = 1;
598+
599+ return avpkt->size;
600+}
601+
602+static av_cold int decode_init(AVCodecContext *avctx)
603+{
604+ AGMContext *s = avctx->priv_data;
605+
606+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
607+ s->avctx = avctx;
608+ s->plus = avctx->codec_tag == MKTAG('A', 'G', 'M', '3');
609+
610+ avctx->idct_algo = FF_IDCT_SIMPLE;
611+ ff_idctdsp_init(&s->idsp, avctx);
612+ ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct);
613+
614+ s->prev_frame = av_frame_alloc();
615+ if (!s->prev_frame)
616+ return AVERROR(ENOMEM);
617+
618+ return 0;
619+}
620+
621+static void decode_flush(AVCodecContext *avctx)
622+{
623+ AGMContext *s = avctx->priv_data;
624+
625+ av_frame_unref(s->prev_frame);
626+}
627+
628+static av_cold int decode_close(AVCodecContext *avctx)
629+{
630+ AGMContext *s = avctx->priv_data;
631+
632+ av_frame_free(&s->prev_frame);
633+ av_freep(&s->mvectors);
634+ s->mvectors_size = 0;
635+
636+ return 0;
637+}
638+
639+AVCodec ff_agm_decoder = {
640+ .name = "agm",
641+ .long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),
642+ .type = AVMEDIA_TYPE_VIDEO,
643+ .id = AV_CODEC_ID_AGM,
644+ .priv_data_size = sizeof(AGMContext),
645+ .init = decode_init,
646+ .close = decode_close,
647+ .decode = decode_frame,
648+ .flush = decode_flush,
649+ .capabilities = AV_CODEC_CAP_DR1,
650+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
651+ FF_CODEC_CAP_INIT_CLEANUP |
652+ FF_CODEC_CAP_EXPORTS_CROPPING,
653+};
libavcodec/allcodecs.c+1−0
@@ -35,6 +35,7 @@ extern AVCodec ff_aasc_decoder; · 34 unmodified lines
3535 extern AVCodec ff_aic_decoder;
3636 extern AVCodec ff_alias_pix_encoder;
3737 extern AVCodec ff_alias_pix_decoder;
38+extern AVCodec ff_agm_decoder;
3839 extern AVCodec ff_amv_encoder;
3940 extern AVCodec ff_amv_decoder;
4041 extern AVCodec ff_anm_decoder;
libavcodec/avcodec.h+1−0
@@ -454,6 +454,7 @@ enum AVCodecID { · 453 unmodified lines
454454 AV_CODEC_ID_RASC,
455455 AV_CODEC_ID_HYMT,
456456 AV_CODEC_ID_ARBC,
457+ AV_CODEC_ID_AGM,
457458
458459 /* various PCM "codecs" */
459460 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/codec_desc.c+7−0
@@ -1705,6 +1705,13 @@ static const AVCodecDescriptor codec_descriptors[] = { · 1704 unmodified lines
17051705 .long_name = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"),
17061706 .props = AV_CODEC_PROP_LOSSY,
17071707 },
1708+ {
1709+ .id = AV_CODEC_ID_AGM,
1710+ .type = AVMEDIA_TYPE_VIDEO,
1711+ .name = "agm",
1712+ .long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),
1713+ .props = AV_CODEC_PROP_LOSSY,
1714+ },
17081715
17091716 /* various PCM "codecs" */
17101717 {
libavcodec/version.h+2−2
@@ -28,8 +28,8 @@ · 27 unmodified lines
2828 #include "libavutil/version.h"
2929
3030 #define LIBAVCODEC_VERSION_MAJOR 58
31−#define LIBAVCODEC_VERSION_MINOR 47
32−#define LIBAVCODEC_VERSION_MICRO 106
31+#define LIBAVCODEC_VERSION_MINOR 48
32+#define LIBAVCODEC_VERSION_MICRO 100
3333
3434 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
3535 LIBAVCODEC_VERSION_MINOR, \
libavformat/riff.c+2−0
@@ -477,6 +477,8 @@ const AVCodecTag ff_codec_bmp_tags[] = { · 476 unmodified lines
477477 { AV_CODEC_ID_RASC, MKTAG('R', 'A', 'S', 'C') },
478478 { AV_CODEC_ID_HYMT, MKTAG('H', 'Y', 'M', 'T') },
479479 { AV_CODEC_ID_ARBC, MKTAG('A', 'R', 'B', 'C') },
480+ { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '2') },
481+ { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '3') },
480482 { AV_CODEC_ID_NONE, 0 }
481483 };
482484

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