[FFmpeg-devel] [PATCH] avcodec: add Amuse Graphics decoder
Michael Niedermayer
michael at niedermayer.cc
Sat Oct 13 17:34:52 EEST 2018
On Wed, Oct 10, 2018 at 01:22:24PM +0200, Paul B Mahol wrote:
> This work is partially sponsored by VideoLAN.
>
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>
> The AGM3 variant decodes with some artifacts.
I looked a bit as you asked on IRC but wasnt able to really fix it in
the time i had available
The following patch avoids the green blocks but it does not feel correct
diff --git a/libavcodec/agm.c b/libavcodec/agm.c
index 424b906eac..a6d9a9a7a6 100644
--- a/libavcodec/agm.c
+++ b/libavcodec/agm.c
@@ -358,10 +358,12 @@ static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size,
if (ret < 0)
return ret;
- if (mv_x < min) {
+ if (mv_x < min && s->block[0] > 512) {
s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
frame->linesize[plane], s->block);
} else {
+ if (mv_x < min)
+ mv_x = 0;
if (y * 8 + mv_y < 0 || y * 8 + mv_y >= h ||
x * 8 + mv_x < 0 || x * 8 + mv_x >= w)
return AVERROR_INVALIDDATA;
[...]
> +
> +static int read_code2(GetBitContext *gb, int *oskip, int *level)
> +{
> + int max, len = 0, skip = 0;
> +
> + if (show_bits(gb, 2)) {
> + switch (show_bits(gb, 4)) {
> + case 1:
> + case 9:
> + len = 1;
> + skip = 3;
> + break;
> + case 2:
> + len = 3;
> + skip = 4;
> + break;
> + case 3:
> + len = 7;
> + skip = 4;
> + break;
> + case 5:
> + case 0xD:
> + len = 2;
> + skip = 3;
> + break;
> + case 6:
> + len = 4;
> + skip = 4;
> + break;
> + case 7:
> + len = 8;
> + skip = 4;
> + break;
> + case 0xA:
> + len = 5;
> + skip = 4;
> + break;
> + case 0xB:
> + len = 9;
> + skip = 4;
> + break;
> + case 0xE:
> + len = 6;
> + skip = 4;
> + break;
> + case 0xF:
> + len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4;
> + skip = 5;
> + break;
> + default:
> + return AVERROR_INVALIDDATA;
> + }
> + skip_bits(gb, skip);
> + *level = get_bits(gb, len);
> + *oskip = 0;
> + max = 1 << (len - 1);
> + if (*level < max)
> + *level = -(max + *level);
> + } else if (show_bits(gb, 3) & 4) {
> + skip_bits(gb, 3);
> + if (show_bits(gb, 4)) {
> + if (show_bits(gb, 4) == 1) {
> + skip_bits(gb, 4);
> + *oskip = get_bits(gb, 16);
> + *level = 0;
> + } else {
> + *oskip = get_bits(gb, 4);
> + *level = 0;
> + }
> + } else {
> + skip_bits(gb, 4);
> + *oskip = get_bits(gb, 10);
> + *level = 0;
> + }
The oskip values which can be represented as shorter codes here (if they
occur) likely are errors, this could be checked for. Not sure its useful
[...]
> +
> +static int decode_frame(AVCodecContext *avctx, void *data,
> + int *got_frame, AVPacket *avpkt)
> +{
> + AGMContext *s = avctx->priv_data;
> + GetBitContext *gb = &s->gb;
> + GetByteContext *gbyte = &s->gbyte;
> + AVFrame *frame = data;
> + int w, h, header;
> + int ret;
> +
> + if (!avpkt->size)
> + return 0;
> +
> + bytestream2_init(gbyte, avpkt->data, avpkt->size);
> +
> + header = bytestream2_get_le32(gbyte);
> + if (header)
> + avpriv_request_sample(avctx, "header %X", header);
> + s->bitstream_size = bytestream2_get_le24(gbyte);
> + if (avpkt->size < s->bitstream_size + 8)
> + return AVERROR_INVALIDDATA;
> +
> + s->key_frame = bytestream2_get_byte(gbyte) == 32;
> + frame->key_frame = s->key_frame;
> + frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
> +
> + s->flags = 0;
> + w = bytestream2_get_le32(gbyte);
> + if (w < 0) {
> + w = -w;
> + s->flags |= 2;
> + }
> + h = bytestream2_get_le32(gbyte);
> + if (h < 0) {
> + avpriv_request_sample(avctx, "negative height");
> + h = -h;
> + s->flags |= 1;
> + }
> +
> + ret = ff_set_dimensions(avctx, w, h);
> + if (ret < 0)
> + return ret;
i suspect this has issues with odd width / height
the motion vectors, and luma and chroma plane sizes probably wont align and then
likely not work as intended as each rounds differently
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Old school: Use the lowest level language in which you can solve the problem
conveniently.
New school: Use the highest level language in which the latest supercomputer
can solve the problem without the user falling asleep waiting.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20181013/3d0b1f15/attachment.sig>
More information about the ffmpeg-devel
mailing list