summaryrefslogtreecommitdiff
path: root/libavformat/av1.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2018-07-07 16:35:32 -0300
committerJames Almer <jamrial@gmail.com>2018-07-20 12:00:32 -0300
commit9888a19db477cb8cc217321468c12a2ebe521d32 (patch)
treec7fc2529a2e7a8948388d92088a751b2ae257e8b /libavformat/av1.c
parent9ca7ad246d536a78245b0d12dab4590004ec775d (diff)
avformat/movenc: add support for AV1 streams
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavformat/av1.c')
-rw-r--r--libavformat/av1.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/libavformat/av1.c b/libavformat/av1.c
new file mode 100644
index 0000000000..7db29c8d76
--- /dev/null
+++ b/libavformat/av1.c
@@ -0,0 +1,108 @@
+/*
+ * AV1 helper functions for muxers
+ * Copyright (c) 2018 James Almer <jamrial@gmail.com>
+ *
+ * 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/mem.h"
+#include "libavcodec/av1.h"
+#include "libavcodec/av1_parse.h"
+#include "av1.h"
+#include "avio.h"
+
+int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
+{
+ const uint8_t *end = buf + size;
+ int64_t obu_size;
+ int start_pos, type, temporal_id, spatial_id;
+
+ size = 0;
+ while (buf < end) {
+ int ret = parse_obu_header(buf, end - buf, &obu_size, &start_pos,
+ &type, &temporal_id, &spatial_id);
+ if (ret < 0)
+ return ret;
+
+ obu_size += start_pos;
+ if (obu_size > INT_MAX)
+ return AVERROR_INVALIDDATA;
+
+ switch (type) {
+ case AV1_OBU_TEMPORAL_DELIMITER:
+ case AV1_OBU_REDUNDANT_FRAME_HEADER:
+ case AV1_OBU_PADDING:
+ break;
+ default:
+ avio_write(pb, buf, obu_size);
+ size += obu_size;
+ break;
+ }
+ buf += obu_size;
+ }
+
+ return size;
+}
+
+int ff_av1_filter_obus_buf(const uint8_t *buf, uint8_t **out, int *size)
+{
+ AVIOContext *pb;
+ int ret;
+
+ ret = avio_open_dyn_buf(&pb);
+ if (ret < 0)
+ return ret;
+
+ ret = ff_av1_filter_obus(pb, buf, *size);
+ if (ret < 0)
+ return ret;
+
+ av_freep(out);
+ *size = avio_close_dyn_buf(pb, out);
+
+ return ret;
+}
+
+int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
+{
+ int64_t obu_size;
+ int start_pos, type, temporal_id, spatial_id;
+
+ while (size > 0) {
+ int ret = parse_obu_header(buf, size, &obu_size, &start_pos,
+ &type, &temporal_id, &spatial_id);
+ if (ret < 0)
+ return ret;
+
+ obu_size += start_pos;
+ if (obu_size > INT_MAX)
+ return AVERROR_INVALIDDATA;
+
+ switch (type) {
+ case AV1_OBU_SEQUENCE_HEADER:
+ case AV1_OBU_METADATA:
+ avio_write(pb, buf, obu_size);
+ break;
+ default:
+ break;
+ }
+ size -= obu_size;
+ buf += obu_size;
+ }
+
+ return 0;
+}