Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/videolan/dav1d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2018-09-05 00:32:00 +0300
committerRonald S. Bultje <rsbultje@gmail.com>2018-09-22 14:59:19 +0300
commite2892ffa2dd1e893d0229c5fcbe0bbbee8e11c20 (patch)
tree9ba42513c2916db89d47f8b34fa0141d6aeb4dde /tools/input
parentd32eb2d935a31288c34ccaa42b09bc60eacdfd68 (diff)
Initial decoder implementation.
With minor contributions from: - Jean-Baptiste Kempf <jb@videolan.org> - Marvin Scholz <epirat07@gmail.com> - Hugo Beauzée-Luyssen <hugo@videolan.org>
Diffstat (limited to 'tools/input')
-rw-r--r--tools/input/demuxer.h44
-rw-r--r--tools/input/input.c124
-rw-r--r--tools/input/input.h41
-rw-r--r--tools/input/ivf.c113
4 files changed, 322 insertions, 0 deletions
diff --git a/tools/input/demuxer.h b/tools/input/demuxer.h
new file mode 100644
index 0000000..8fdf6ed
--- /dev/null
+++ b/tools/input/demuxer.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DAV1D_INPUT_DEMUXER_H__
+#define __DAV1D_INPUT_DEMUXER_H__
+
+#include "data.h"
+
+typedef struct DemuxerPriv DemuxerPriv;
+typedef struct Demuxer {
+ int priv_data_size;
+ const char *name;
+ const char *extension;
+ int (*open)(DemuxerPriv *ctx, const char *filename,
+ unsigned fps[2], unsigned *num_frames);
+ int (*read)(DemuxerPriv *ctx, Dav1dData *data);
+ void (*close)(DemuxerPriv *ctx);
+} Demuxer;
+
+#endif /* __DAV1D_INPUT_DEMUXER_H__ */
diff --git a/tools/input/input.c b/tools/input/input.c
new file mode 100644
index 0000000..e00c21c
--- /dev/null
+++ b/tools/input/input.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "input/input.h"
+#include "input/demuxer.h"
+
+struct DemuxerContext {
+ DemuxerPriv *data;
+ const Demuxer *impl;
+};
+
+#define MAX_NUM_DEMUXERS 1
+static const Demuxer *demuxers[MAX_NUM_DEMUXERS];
+static int num_demuxers = 0;
+
+#define register_demuxer(impl) { \
+ extern const Demuxer impl; \
+ assert(num_demuxers < MAX_NUM_DEMUXERS); \
+ demuxers[num_demuxers++] = &impl; \
+}
+
+void init_demuxers(void) {
+ register_demuxer(ivf_demuxer);
+}
+
+static const char *find_extension(const char *const f) {
+ const int l = strlen(f);
+
+ if (l == 0) return NULL;
+
+ const char *const end = &f[l - 1], *step = end;
+ while ((*step >= 'a' && *step <= 'z') ||
+ (*step >= 'A' && *step <= 'Z') ||
+ (*step >= '0' && *step <= '9'))
+ {
+ step--;
+ }
+
+ return (step < end && step > f && *step == '.' && step[-1] != '/') ?
+ &step[1] : NULL;
+}
+
+int input_open(DemuxerContext **const c_out, const char *const filename,
+ unsigned fps[2], unsigned *const num_frames)
+{
+ const Demuxer *impl;
+ DemuxerContext *c;
+ int res, i;
+
+ const char *const ext = find_extension(filename);
+ if (!ext) {
+ fprintf(stderr, "No extension found for file %s\n", filename);
+ return -1;
+ }
+
+ for (i = 0; i < num_demuxers; i++) {
+ if (!strcmp(demuxers[i]->extension, ext)) {
+ impl = demuxers[i];
+ break;
+ }
+ }
+ if (i == num_demuxers) {
+ fprintf(stderr,
+ "Failed to find demuxer for file %s (\"%s\")\n",
+ filename, ext);
+ return -ENOPROTOOPT;
+ }
+
+ if (!(c = malloc(sizeof(DemuxerContext) + impl->priv_data_size))) {
+ fprintf(stderr, "Failed to allocate memory\n");
+ return -ENOMEM;
+ }
+ memset(c, 0, sizeof(DemuxerContext) + impl->priv_data_size);
+ c->impl = impl;
+ c->data = (DemuxerPriv *) &c[1];
+ if ((res = impl->open(c->data, filename, fps, num_frames)) < 0) {
+ free(c);
+ return res;
+ }
+ *c_out = c;
+
+ return 0;
+}
+
+int input_read(DemuxerContext *const ctx, Dav1dData *const data) {
+ return ctx->impl->read(ctx->data, data);
+}
+
+void input_close(DemuxerContext *const ctx) {
+ ctx->impl->close(ctx->data);
+ free(ctx);
+}
diff --git a/tools/input/input.h b/tools/input/input.h
new file mode 100644
index 0000000..ad0f0ef
--- /dev/null
+++ b/tools/input/input.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DAV1D_INPUT_INPUT_H__
+#define __DAV1D_INPUT_INPUT_H__
+
+#include "data.h"
+
+typedef struct DemuxerContext DemuxerContext;
+
+void init_demuxers(void);
+int input_open(DemuxerContext **c, const char *filename,
+ unsigned fps[2], unsigned *num_frames);
+int input_read(DemuxerContext *ctx, Dav1dData *data);
+void input_close(DemuxerContext *ctx);
+
+#endif /* __DAV1D_INPUT_INPUT_H__ */
diff --git a/tools/input/ivf.c b/tools/input/ivf.c
new file mode 100644
index 0000000..2e47d32
--- /dev/null
+++ b/tools/input/ivf.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/intops.h"
+
+#include "input/demuxer.h"
+
+typedef struct DemuxerPriv {
+ FILE *f;
+} IvfInputContext;
+
+static int ivf_open(IvfInputContext *const c, const char *const file,
+ unsigned fps[2], unsigned *const num_frames)
+{
+ int res;
+ uint8_t hdr[32];
+
+ memset(c, 0, sizeof(*c));
+ if (!(c->f = fopen(file, "r"))) {
+ fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
+ return -1;
+ } else if ((res = fread(hdr, 32, 1, c->f)) != 1) {
+ fprintf(stderr, "Failed to read stream header: %s\n", strerror(errno));
+ fclose(c->f);
+ return -1;
+ } else if (memcmp(hdr, "DKIF", 4)) {
+ fprintf(stderr, "%s is not an IVF file [tag=%4s|0x%02x%02x%02x%02x]\n",
+ file, hdr, hdr[0], hdr[1], hdr[2], hdr[3]);
+ fclose(c->f);
+ return -1;
+ } else if (memcmp(&hdr[8], "AV01", 4)) {
+ fprintf(stderr, "%s is not an AV1 file [tag=%4s|0x%02x%02x%02x%02x]\n",
+ file, &hdr[8], hdr[8], hdr[9], hdr[10], hdr[11]);
+ fclose(c->f);
+ return -1;
+ }
+
+ fps[0] = rl32(&hdr[16]);
+ fps[1] = rl32(&hdr[20]);
+ const unsigned duration = rl32(&hdr[24]);
+ uint8_t data[4];
+ for (*num_frames = 0;; (*num_frames)++) {
+ if ((res = fread(data, 4, 1, c->f)) != 1)
+ break; // EOF
+ fseek(c->f, rl32(data) + 8, SEEK_CUR);
+ }
+ fps[0] *= *num_frames;
+ fps[1] *= duration;
+ fseek(c->f, 32, SEEK_SET);
+
+ return 0;
+}
+
+static int ivf_read(IvfInputContext *const c, Dav1dData *const buf) {
+ uint8_t data[4];
+ int res;
+
+ if ((res = fread(data, 4, 1, c->f)) != 1)
+ return -1; // EOF
+ fseek(c->f, 8, SEEK_CUR); // skip timestamp
+ const ptrdiff_t sz = rl32(data);
+ dav1d_data_create(buf, sz);
+ if ((res = fread(buf->data, sz, 1, c->f)) != 1)
+ fprintf(stderr, "Failed to read frame data: %s\n", strerror(errno));
+
+ return 0;
+}
+
+static void ivf_close(IvfInputContext *const c) {
+ fclose(c->f);
+}
+
+const Demuxer ivf_demuxer = {
+ .priv_data_size = sizeof(IvfInputContext),
+ .name = "ivf",
+ .extension = "ivf",
+ .open = ivf_open,
+ .read = ivf_read,
+ .close = ivf_close,
+};