From: James Almer <jamrial@gmail.com> To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] avcodec: add RTV1 decoder Date: Sun, 4 Jun 2023 12:09:21 -0300 Message-ID: <150c9b09-ed6d-9e76-21be-4ae208f1d5d8@gmail.com> (raw) In-Reply-To: <CAPYw7P7s+_EFE7P2TMJZW7PhyjMDh8mTEZ++okMasH-5Tbf1og@mail.gmail.com> > From cdd867aa1c88fa8b89dfe473ae0e2caf69c74313 Mon Sep 17 00:00:00 2001 > From: Paul B Mahol <onemda@gmail.com> > Date: Sat, 3 Jun 2023 12:29:25 +0200 > Subject: [PATCH] avcodec: add RTV1 decoder > > Signed-off-by: Paul B Mahol <onemda@gmail.com> > --- > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/codec_desc.c | 7 ++ > libavcodec/codec_id.h | 1 + > libavcodec/rtv1.c | 141 ++++++++++++++++++++++++++++++++++++++++ > libavformat/riff.c | 1 + > 6 files changed, 152 insertions(+) > create mode 100644 libavcodec/rtv1.c Don't forget to bump minor version. [...] > diff --git a/libavcodec/rtv1.c b/libavcodec/rtv1.c > new file mode 100644 > index 0000000000..953f915c83 > --- /dev/null > +++ b/libavcodec/rtv1.c > @@ -0,0 +1,141 @@ > +/* > + * RTV1 decoder > + * Copyright (c) 2023 Paul B Mahol > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include <stdio.h> > +#include <string.h> > + > +#include "avcodec.h" > +#include "bytestream.h" > +#include "codec_internal.h" > +#include "decode.h" > +#include "texturedsp.h" > +#include "thread.h" > + > +static int decode_rtv1(GetByteContext *gb, uint8_t *dst, int linesize, ptrdiff_t linesize > + int width, int height, int flag, > + int (*dxt1_block)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)) > +{ > + uint8_t block[8] = { 0 }; > + int run = 0; > + > + for (int y = 0; y < height; y += 4) { > + for (int x = 0; x < width * 4; x += 16) { > + int mode = 0; > + > + if (run && --run > 0) { > + dxt1_block(dst + x, linesize, block); > + } else { > + int a, b; > + > + if (bytestream2_get_bytes_left(gb) < 4) > + break; > + > + a = bytestream2_get_le16u(gb); > + b = bytestream2_get_le16u(gb); > + if (a == b && flag) { 4 bytes for a boolean value? Geez. > + AV_WL32(block + 4, 0); > + } else if (a == 1 && b == 0xffff) { > + mode = 1; > + } else if (b && a == 0) { > + run = b; > + } else { > + AV_WL16(block, a); > + AV_WL16(block + 2, b); > + AV_WL32(block + 4, bytestream2_get_le32(gb)); > + } > + if (run && !mode) { > + dxt1_block(dst + x, linesize, block); > + } else if (!mode) { > + AV_WL16(block, a); > + AV_WL16(block + 2, b); > + dxt1_block(dst + x, linesize, block); > + } else { > + if (bytestream2_get_bytes_left(gb) < 12 * 4) > + break; > + > + for (int by = 0; by < 4; by++) { > + for (int bx = 0; bx < 4; bx++) > + AV_WL32(dst + x + bx * 4 + by * linesize, bytestream2_get_le24u(gb)); > + } > + } > + } > + } > + > + dst += linesize * 4; > + } > + > + return 0; > +} > + > +static int decode_frame(AVCodecContext *avctx, AVFrame *p, > + int *got_frame, AVPacket *avpkt) > +{ > + int ret, width, height, flags; > + TextureDSPContext dsp; > + GetByteContext gb; > + ptrdiff_t linesize; > + uint8_t *dst; > + > + if (avpkt->size < 22) > + return AVERROR_INVALIDDATA; > + > + ff_texturedsp_init(&dsp); This should be in an init() function, not called for every frame. > + > + bytestream2_init(&gb, avpkt->data, avpkt->size); > + > + if (bytestream2_get_le32(&gb) != MKTAG('D','X','T','1')) Is this really a RivaTuner codec and not just raw texture if the first four bytes are the name of the texture type? > + return AVERROR_INVALIDDATA; > + flags = bytestream2_get_le32(&gb); > + > + width = bytestream2_get_le32(&gb); > + height = bytestream2_get_le32(&gb); > + ret = ff_set_dimensions(avctx, width, height); > + if (ret < 0) > + return ret; > + > + avctx->coded_width = FFALIGN(avctx->width, 4); > + avctx->coded_height = FFALIGN(avctx->height, 4); This should also be in avcodec_align_dimensions2(), otherwise it will not be taken into account by ff_thread_get_buffer(). > + avctx->pix_fmt = AV_PIX_FMT_BGR0; Move this to the init function too while at it. > + > + if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0) > + return ret; > + > + dst = p->data[0] + p->linesize[0] * (avctx->coded_height - 1); > + linesize = -p->linesize[0]; > + > + decode_rtv1(&gb, dst, linesize, width, height, flags, dsp.dxt1_block); > + > + p->pict_type = AV_PICTURE_TYPE_I; > + p->flags |= AV_FRAME_FLAG_KEY; > + > + *got_frame = 1; > + > + return avpkt->size; > +} > + > +const FFCodec ff_rtv1_decoder = { > + .p.name = "rtv1", > + CODEC_LONG_NAME("RTV1 (RivaTuner Video)"), > + .p.type = AVMEDIA_TYPE_VIDEO, > + .p.id = AV_CODEC_ID_RTV1, > + FF_CODEC_DECODE_CB(decode_frame), > + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, > +}; > diff --git a/libavformat/riff.c b/libavformat/riff.c > index 7319406b39..4279071159 100644 > --- a/libavformat/riff.c > +++ b/libavformat/riff.c > @@ -501,6 +501,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { > { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'l', 'c', '1') }, > { AV_CODEC_ID_VQC, MKTAG('V', 'Q', 'C', '1') }, > { AV_CODEC_ID_VQC, MKTAG('V', 'Q', 'C', '2') }, > + { AV_CODEC_ID_RTV1, MKTAG('R', 'T', 'V', '1') }, > { AV_CODEC_ID_NONE, 0 } > }; > > -- > 2.39.1 > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-06-04 15:09 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-06-04 14:03 Paul B Mahol 2023-06-04 15:09 ` James Almer [this message] 2023-06-04 15:53 ` Paul B Mahol 2023-06-07 6:51 ` Paul B Mahol
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=150c9b09-ed6d-9e76-21be-4ae208f1d5d8@gmail.com \ --to=jamrial@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git