summaryrefslogtreecommitdiff
path: root/libavformat/mux_utils.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-05-06 15:43:55 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-05-10 07:29:15 +0200
commitba49acf143743bc9480566a52e94030cf38bfc75 (patch)
tree3c6bbef86d5dc35c471ba69ca0227d8024326d40 /libavformat/mux_utils.c
parentb9f6d416ecbed36fbe1b819d1099f71ba2936ddd (diff)
avformat/mux_utils: Move ff_format_shift_data to new file for mux utils
It is only used by muxers. Given that it is not part of the core muxing code and given that mux.c is already big enough, it is moved to a new file for utility functions for muxing. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavformat/mux_utils.c')
-rw-r--r--libavformat/mux_utils.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/libavformat/mux_utils.c b/libavformat/mux_utils.c
new file mode 100644
index 0000000000..7b79ffd1fb
--- /dev/null
+++ b/libavformat/mux_utils.c
@@ -0,0 +1,81 @@
+/*
+ * Various muxing utility functions
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * 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 "avformat.h"
+#include "avio.h"
+#include "internal.h"
+#include "mux.h"
+
+int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size)
+{
+ int ret;
+ int64_t pos, pos_end;
+ uint8_t *buf, *read_buf[2];
+ int read_buf_id = 0;
+ int read_size[2];
+ AVIOContext *read_pb;
+
+ buf = av_malloc_array(shift_size, 2);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ read_buf[0] = buf;
+ read_buf[1] = buf + shift_size;
+
+ /* Shift the data: the AVIO context of the output can only be used for
+ * writing, so we re-open the same output, but for reading. It also avoids
+ * a read/seek/write/seek back and forth. */
+ avio_flush(s->pb);
+ ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for shifting data\n", s->url);
+ goto end;
+ }
+
+ /* mark the end of the shift to up to the last data we wrote, and get ready
+ * for writing */
+ pos_end = avio_tell(s->pb);
+ avio_seek(s->pb, read_start + shift_size, SEEK_SET);
+
+ avio_seek(read_pb, read_start, SEEK_SET);
+ pos = avio_tell(read_pb);
+
+#define READ_BLOCK do { \
+ read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
+ read_buf_id ^= 1; \
+} while (0)
+
+ /* shift data by chunk of at most shift_size */
+ READ_BLOCK;
+ do {
+ int n;
+ READ_BLOCK;
+ n = read_size[read_buf_id];
+ if (n <= 0)
+ break;
+ avio_write(s->pb, read_buf[read_buf_id], n);
+ pos += n;
+ } while (pos < pos_end);
+ ret = ff_format_io_close(s, &read_pb);
+
+end:
+ av_free(buf);
+ return ret;
+}