The branch, master has been updated
via 23df9d4172038caa7007a4abbc291cc9c5aea65a (commit)
from 98412edfed56f03d6844aafd48f5891dd9d591ec (commit)
- Log -----------------------------------------------------------------
commit 23df9d4172038caa7007a4abbc291cc9c5aea65a
Author: averne <[email protected]>
AuthorDate: Tue Jul 22 19:06:55 2025 +0200
Commit: Lynne <[email protected]>
CommitDate: Sat Oct 25 19:56:44 2025 +0000
avcodec/prores: add parser
Introduce a basic parser for ProRes frame headers.
This avoid having to decode an entire frame to
extract codec information.
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f5637cee08..972a17f060 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1282,6 +1282,7 @@ OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
OBJS-$(CONFIG_PRORES_RAW_PARSER) += prores_raw_parser.o
OBJS-$(CONFIG_QOI_PARSER) += qoi_parser.o
+OBJS-$(CONFIG_PRORES_PARSER) += prores_parser.o
OBJS-$(CONFIG_RV34_PARSER) += rv34_parser.o
OBJS-$(CONFIG_SBC_PARSER) += sbc_parser.o
OBJS-$(CONFIG_SIPR_PARSER) += sipr_parser.o
diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c
index 42b40643f9..824a1ccd55 100644
--- a/libavcodec/parsers.c
+++ b/libavcodec/parsers.c
@@ -67,6 +67,7 @@ extern const AVCodecParser ff_mpeg4video_parser;
extern const AVCodecParser ff_mpegaudio_parser;
extern const AVCodecParser ff_mpegvideo_parser;
extern const AVCodecParser ff_opus_parser;
+extern const AVCodecParser ff_prores_parser;
extern const AVCodecParser ff_png_parser;
extern const AVCodecParser ff_pnm_parser;
extern const AVCodecParser ff_prores_raw_parser;
diff --git a/libavcodec/prores_parser.c b/libavcodec/prores_parser.c
new file mode 100644
index 0000000000..d778f839bd
--- /dev/null
+++ b/libavcodec/prores_parser.c
@@ -0,0 +1,128 @@
+/*
+ * 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 "libavutil/intreadwrite.h"
+#include "bytestream.h"
+
+#include "avcodec.h"
+
+static int parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ GetByteContext gb;
+ uint8_t flags, depth, chroma_format, alpha_channel_type;
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+
+ /* Frame fields + frame header size */
+ if (buf_size < 28)
+ return buf_size;
+
+ bytestream2_init(&gb, buf, buf_size);
+
+ /* Frame size */
+ if (bytestream2_get_be32(&gb) != buf_size)
+ return buf_size;
+
+ /* Frame identifier */
+ if (bytestream2_get_le32(&gb) != MKTAG('i','c','p','f'))
+ return buf_size;
+
+ /* Frame header size */
+ if (bytestream2_get_be16(&gb) < 20)
+ return buf_size;
+
+ bytestream2_skip(&gb, 6); /* Bitstream version, encoder identifier */
+
+ s->key_frame = 1;
+ s->pict_type = AV_PICTURE_TYPE_I;
+
+ s->width = bytestream2_get_be16(&gb);
+ s->height = bytestream2_get_be16(&gb);
+ s->coded_width = FFALIGN(s->width, 16);
+ s->coded_height = FFALIGN(s->height, 16);
+
+ flags = bytestream2_get_byte(&gb);
+
+ /* Interlace mode */
+ switch (flags >> 2 & 3) {
+ case 0:
+ s->field_order = AV_FIELD_PROGRESSIVE;
+ s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
+ break;
+ case 1:
+ s->field_order = AV_FIELD_TT;
+ s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD;
+ break;
+ case 2:
+ s->field_order = AV_FIELD_BB;
+ s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+ break;
+ default:
+ break;
+ }
+
+ bytestream2_skip(&gb, 4); /* Aspect ratio information, frame rate code,
color primaries, transfer characteristic, matrix coefficients */
+
+ /* Determine pixel format based on color depth, chroma format and alpha
type */
+ switch (avctx->codec_tag) {
+ case MKTAG('a','p','c','o'):
+ case MKTAG('a','p','c','s'):
+ case MKTAG('a','p','c','n'):
+ case MKTAG('a','p','c','h'):
+ depth = 10;
+ break;
+ case MKTAG('a','p','4','h'):
+ case MKTAG('a','p','4','x'):
+ depth = 12;
+ break;
+ default:
+ return buf_size;
+ }
+
+ chroma_format = flags >> 6 & 3;
+ if (chroma_format < 2)
+ return buf_size;
+
+ alpha_channel_type = bytestream2_get_byte(&gb) & 0xf;
+
+ switch (depth | (chroma_format << 4) | (alpha_channel_type << 8)) {
+ case 10 | (2 << 4) | (0 << 8): s->format = AV_PIX_FMT_YUV422P10;
break;
+ case 10 | (2 << 4) | (1 << 8):
+ case 10 | (2 << 4) | (2 << 8): s->format = AV_PIX_FMT_YUVA422P10;
break;
+ case 10 | (3 << 4) | (0 << 8): s->format = AV_PIX_FMT_YUV444P10;
break;
+ case 10 | (3 << 4) | (1 << 8):
+ case 10 | (3 << 4) | (2 << 8): s->format = AV_PIX_FMT_YUVA444P10;
break;
+ case 12 | (2 << 4) | (0 << 8): s->format = AV_PIX_FMT_YUV422P12;
break;
+ case 12 | (2 << 4) | (1 << 8):
+ case 12 | (2 << 4) | (2 << 8): s->format = AV_PIX_FMT_YUVA422P12;
break;
+ case 12 | (3 << 4) | (0 << 8): s->format = AV_PIX_FMT_YUV444P12;
break;
+ case 12 | (3 << 4) | (1 << 8):
+ case 12 | (3 << 4) | (2 << 8): s->format = AV_PIX_FMT_YUVA444P12;
break;
+ }
+
+ return buf_size;
+}
+
+const AVCodecParser ff_prores_parser = {
+ .codec_ids = { AV_CODEC_ID_PRORES },
+ .parser_parse = parse,
+};
diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c
index 0e8ec344a2..814074f9d7 100644
--- a/libavcodec/proresdec.c
+++ b/libavcodec/proresdec.c
@@ -276,10 +276,10 @@ static int decode_frame_header(ProresContext *ctx, const
uint8_t *buf,
#endif
}
- ctx->frame->color_primaries = buf[14];
- ctx->frame->color_trc = buf[15];
- ctx->frame->colorspace = buf[16];
- ctx->frame->color_range = AVCOL_RANGE_MPEG;
+ avctx->color_primaries = buf[14];
+ avctx->color_trc = buf[15];
+ avctx->colorspace = buf[16];
+ avctx->color_range = AVCOL_RANGE_MPEG;
ptr = buf + 20;
flags = buf[19];
@@ -779,6 +779,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame
*frame,
if (frame_hdr_size < 0)
return frame_hdr_size;
+ if (avctx->skip_frame == AVDISCARD_ALL)
+ return 0;
+
buf += frame_hdr_size;
buf_size -= frame_hdr_size;
@@ -870,6 +873,7 @@ const FFCodec ff_prores_decoder = {
FF_CODEC_DECODE_CB(decode_frame),
UPDATE_THREAD_CONTEXT(update_thread_context),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
+ .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
#if HWACCEL_MAX
.hw_configs = (const AVCodecHWConfigInternal *const []) {
diff --git a/libavformat/mov.c b/libavformat/mov.c
index a962594990..45c562cdc6 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2991,6 +2991,7 @@ static int mov_finalize_stsd_codec(MOVContext *c,
AVIOContext *pb,
sti->need_parsing = AVSTREAM_PARSE_FULL;
break;
case AV_CODEC_ID_PRORES_RAW:
+ case AV_CODEC_ID_PRORES:
case AV_CODEC_ID_APV:
case AV_CODEC_ID_EVC:
case AV_CODEC_ID_AV1:
-----------------------------------------------------------------------
Summary of changes:
libavcodec/Makefile | 1 +
libavcodec/parsers.c | 1 +
libavcodec/prores_parser.c | 128 +++++++++++++++++++++++++++++++++++++++++++++
libavcodec/proresdec.c | 12 +++--
libavformat/mov.c | 1 +
5 files changed, 139 insertions(+), 4 deletions(-)
create mode 100644 libavcodec/prores_parser.c
hooks/post-receive
--
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]