From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Subject: [FFmpeg-devel] [PATCH 16/25] avformat/avc: Add functions to split access unit into list of NALUs
Date: Mon, 17 Jan 2022 00:03:56 +0100
Message-ID: <AM7PR03MB6660453D3F1E62CC58F1A6348F569@AM7PR03MB6660.eurprd03.prod.outlook.com> (raw)
In-Reply-To: <AM7PR03MB66609FAEE5128E3BA3F57C0F8F569@AM7PR03MB6660.eurprd03.prod.outlook.com>
This will allow to avoid the temporary buffer and memcpys
when repacketing annex B to mp4-style H.264/H.265 without
searching twice for start codes.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/avc.c | 40 +++++++++++++++++++++++++++++++++++++---
libavformat/avc.h | 29 +++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/libavformat/avc.c b/libavformat/avc.c
index b5e2921388..b0ceb1d2d8 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -70,7 +70,8 @@ const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
return out;
}
-int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
+static int avc_parse_nal_units(AVIOContext *pb, NALUList *list,
+ const uint8_t *buf_in, int size)
{
const uint8_t *p = buf_in;
const uint8_t *end = p + size;
@@ -79,19 +80,52 @@ int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
size = 0;
nal_start = ff_avc_find_startcode(p, end);
for (;;) {
+ const size_t nalu_limit = SIZE_MAX / sizeof(*list->nalus);
while (nal_start < end && !*(nal_start++));
if (nal_start == end)
break;
nal_end = ff_avc_find_startcode(nal_start, end);
- avio_wb32(pb, nal_end - nal_start);
- avio_write(pb, nal_start, nal_end - nal_start);
+ if (pb) {
+ avio_wb32(pb, nal_end - nal_start);
+ avio_write(pb, nal_start, nal_end - nal_start);
+ } else if (list->nb_nalus >= nalu_limit) {
+ return AVERROR(ERANGE);
+ } else {
+ NALU *tmp = av_fast_realloc(list->nalus, &list->nalus_array_size,
+ (list->nb_nalus + 1) * sizeof(*list->nalus));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ list->nalus = tmp;
+ tmp[list->nb_nalus++] = (NALU){ .offset = nal_start - p,
+ .size = nal_end - nal_start };
+ }
size += 4 + nal_end - nal_start;
nal_start = nal_end;
}
return size;
}
+int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
+{
+ return avc_parse_nal_units(pb, NULL, buf_in, size);
+}
+
+int ff_nal_units_create_list(NALUList *list, const uint8_t *buf, int size)
+{
+ list->nb_nalus = 0;
+ return avc_parse_nal_units(NULL, list, buf, size);
+}
+
+void ff_nal_units_write_list(const NALUList *list, AVIOContext *pb,
+ const uint8_t *buf)
+{
+ for (unsigned i = 0; i < list->nb_nalus; i++) {
+ avio_wb32(pb, list->nalus[i].size);
+ avio_write(pb, buf + list->nalus[i].offset, list->nalus[i].size);
+ }
+}
+
int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
{
AVIOContext *pb;
diff --git a/libavformat/avc.h b/libavformat/avc.h
index 9792b77913..aced285c7a 100644
--- a/libavformat/avc.h
+++ b/libavformat/avc.h
@@ -25,6 +25,35 @@
#include <stdint.h>
#include "avio.h"
+typedef struct NALU {
+ int offset;
+ uint32_t size;
+} NALU;
+
+typedef struct NALUList {
+ NALU *nalus;
+ unsigned nalus_array_size;
+ unsigned nb_nalus; ///< valid entries in nalus
+} NALUList;
+
+/* This function will parse the given annex B buffer and create
+ * a NALUList from it. This list can be passed to ff_nal_units_write_list()
+ * to write the access unit reformatted to mp4.
+ *
+ * @param list A NALUList. The list->nalus and list->nalus_array_size
+ * must be valid when calling this function and may be updated.
+ * nb_nalus is set by this function on success.
+ * @param buf buffer containing annex B H.264 or H.265. Must be padded.
+ * @param size size of buf, excluding padding.
+ * @return < 0 on error, the size of the mp4-style packet on success.
+ */
+int ff_nal_units_create_list(NALUList *list, const uint8_t *buf, int size);
+
+/* Writes a NALUList to the specified AVIOContext. The list must originate
+ * from ff_nal_units_create_list() with the same buf. */
+void ff_nal_units_write_list(const NALUList *list, AVIOContext *pb,
+ const uint8_t *buf);
+
int ff_avc_parse_nal_units(AVIOContext *s, const uint8_t *buf, int size);
int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size);
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len);
--
2.32.0
_______________________________________________
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:[~2022-01-16 23:06 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-16 22:49 [FFmpeg-devel] [PATCH 01/25] avformat/matroskaenc: Fix potential overflow Andreas Rheinhardt
2022-01-16 22:51 ` James Almer
2022-01-16 23:05 ` Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 02/25] avformat/matroskaenc: Don't open BlockGroup twice Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 03/25] avformat/matroskaenc: Add API to write Masters with minimal length field Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 04/25] avformat/matroskaenc: Don't waste bytes on SimpleTags length fields Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 05/25] avformat/matroskaenc: Don't waste bytes when writing attachments Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 06/25] avformat/matroskaenc: Avoid seeks when writing EBML header Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 07/25] avformat/matroskaenc: Factor writing TrackVideo out Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 08/25] avformat/matroskaenc: Don't waste bytes on Video element length fields Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 09/25] avformat/matroskaenc: Don't waste bytes on ChapterAtoms " Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 10/25] avformat/matroskaenc: Factor writing Info out Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 11/25] avformat/matroskaenc: Allow to use custom reformatting functions Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 12/25] avformat/matroskaenc: Speed up reformatting WavPack Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 13/25] avformat/av1: Document actual behaviour of ff_av1_filter_obus() Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 14/25] avformat/matroskaenc: Redo reformatting AV1 Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 15/25] avformat/matroskaenc: Use common function for H.2645 annex B->mp4 Andreas Rheinhardt
2022-01-16 23:03 ` Andreas Rheinhardt [this message]
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 17/25] avformat/matroskaenc: Avoid temporary buffers when reformatting H.2645 Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 18/25] avformat/matroskaenc: Remove special code for writing subtitles Andreas Rheinhardt
2022-01-16 23:03 ` [FFmpeg-devel] [PATCH 19/25] avformat/matroskaenc: Pass more parameters explicitly to mkv_write_block Andreas Rheinhardt
2022-01-16 23:04 ` [FFmpeg-devel] [PATCH 20/25] avformat/matroskaenc: Redo applying ProRes offset Andreas Rheinhardt
2022-01-16 23:04 ` [FFmpeg-devel] [PATCH 21/25] avformat/matroskaenc: Don't waste bytes on BlockGroup length fields Andreas Rheinhardt
2022-01-16 23:04 ` [FFmpeg-devel] [PATCH 22/25] avformat/matroskaenc: Remove duplicated code for writing WebVTT subs Andreas Rheinhardt
2022-01-16 23:04 ` [FFmpeg-devel] [PATCH 23/25] avformat/matroskaenc: Reindentation Andreas Rheinhardt
2022-01-16 23:04 ` [FFmpeg-devel] [PATCH 24/25] avformat/matroskaenc: Avoid repeated avio_tell() Andreas Rheinhardt
2022-01-16 23:04 ` [FFmpeg-devel] [PATCH 25/25] avformat/matroskaenc: Write data directly into dynamic buffers Andreas Rheinhardt
2022-01-18 11:17 ` [FFmpeg-devel] [PATCH 01/25] avformat/matroskaenc: Fix potential overflow Andreas Rheinhardt
2022-01-18 23:32 ` [FFmpeg-devel] [PATCH 26/31] avformat/mux: Remove assert based on faulty assumptions Andreas Rheinhardt
2022-01-18 23:32 ` [FFmpeg-devel] [PATCH 27/31] fate/matroska: Add test for avoiding negative timestamps Andreas Rheinhardt
2022-01-19 0:33 ` Andreas Rheinhardt
2022-01-18 23:32 ` [FFmpeg-devel] [PATCH 28/31] avformat/avformat: Add AVFMT_AVOID_NEG_TS_DISABLED Andreas Rheinhardt
2022-01-18 23:32 ` [FFmpeg-devel] [PATCH 29/31] avformat/mux: Preserve sync even if later packet has negative ts Andreas Rheinhardt
2022-01-18 23:32 ` [FFmpeg-devel] [PATCH 30/31] avformat/mux: Peek into the muxing queue for avoid_negative_ts Andreas Rheinhardt
2022-01-18 23:32 ` [FFmpeg-devel] [PATCH 31/31] avformat/hls: Remove redundant cast Andreas Rheinhardt
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=AM7PR03MB6660453D3F1E62CC58F1A6348F569@AM7PR03MB6660.eurprd03.prod.outlook.com \
--to=andreas.rheinhardt@outlook.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