ref: 0afc2039e707b2acdc209f0a8943043176376a5e
parent: 041f653545a5c6b677c1f099e9f98634c2cb1601
author: James Almer <jamrial@gmail.com>
date: Sun Nov 25 15:46:11 EST 2018
Add a public function to parse the Sequence Header from raw bitstream data Signed-off-by: James Almer <jamrial@gmail.com>
--- a/include/dav1d/dav1d.h
+++ b/include/dav1d/dav1d.h
@@ -77,6 +77,22 @@
DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);
/**
+ * Parse a Sequence Header OBU from bitstream data.
+ *
+ * @param out Output Sequence Header.
+ * @param buf The data to be parser.
+ * @param sz Size of the data.
+ *
+ * @return 0 on success, or < 0 (a negative errno code) on error.
+ *
+ * @note It is safe to feed this function data containing other OBUs than a
+ * Sequence Header, as they will simply be ignored. If there is more than
+ * one Sequence Header OBU present, only the last will be returned.
+ */
+DAV1D_API int dav1d_parse_sequence_header(Dav1dSequenceHeader *out,
+ const uint8_t *buf, const size_t sz);
+
+/**
* Feed bitstream data to the decoder.
*
* @param c Input decoder instance.
--- a/src/lib.c
+++ b/src/lib.c
@@ -167,6 +167,54 @@
return -ENOMEM;
}
+static void dummy_free(const uint8_t *const data, void *const user_data) {
+ assert(data && !user_data);
+}
+
+int dav1d_parse_sequence_header(Dav1dSequenceHeader *const out,
+ const uint8_t *const ptr, const size_t sz)
+{
+ Dav1dData buf = { 0 };
+ int res;
+
+ validate_input_or_ret(out != NULL, -EINVAL);
+
+ Dav1dSettings s;
+ dav1d_default_settings(&s);
+
+ Dav1dContext *c;
+ res = dav1d_open(&c, &s);
+ if (res < 0) return res;
+
+ if (ptr) {
+ res = dav1d_data_wrap(&buf, ptr, sz, dummy_free, NULL);
+ if (res < 0) goto error;
+ }
+
+ while (buf.sz > 0) {
+ res = dav1d_parse_obus(c, &buf, 1);
+ if (res < 0) goto error;
+
+ assert((size_t)res <= buf.sz);
+ buf.sz -= res;
+ buf.data += res;
+ }
+
+ if (!c->seq_hdr) {
+ res = -EINVAL;
+ goto error;
+ }
+
+ memcpy(out, c->seq_hdr, sizeof(*out));
+
+ res = 0;
+error:
+ dav1d_data_unref(&buf);
+ dav1d_close(&c);
+
+ return res;
+}
+
int dav1d_send_data(Dav1dContext *const c, Dav1dData *const in)
{
validate_input_or_ret(c != NULL, -EINVAL);
@@ -266,7 +314,7 @@
}
while (in->sz > 0) {
- if ((res = dav1d_parse_obus(c, in)) < 0) {
+ if ((res = dav1d_parse_obus(c, in, 0)) < 0) {
dav1d_data_unref(in);
return res;
}
--- a/src/obu.c
+++ b/src/obu.c
@@ -1157,7 +1157,7 @@
return 0;
}
-int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
+int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, int global) {
GetBits gb;
int res;
@@ -1259,6 +1259,7 @@
// fall-through
case OBU_FRAME:
case OBU_FRAME_HDR:
+ if (global) break;
if (!c->seq_hdr) goto error;
if (!c->frame_hdr_ref) {
c->frame_hdr_ref = dav1d_ref_create(sizeof(Dav1dFrameHeader));
@@ -1298,6 +1299,7 @@
dav1d_bytealign_get_bits(&gb);
// fall-through
case OBU_TILE_GRP: {
+ if (global) break;
if (!c->frame_hdr) goto error;
if (c->n_tile_data >= 256) goto error;
parse_tile_hdr(c, &gb);
--- a/src/obu.h
+++ b/src/obu.h
@@ -31,6 +31,6 @@
#include "dav1d/data.h"
#include "src/internal.h"
-int dav1d_parse_obus(Dav1dContext *c, Dav1dData *in);
+int dav1d_parse_obus(Dav1dContext *c, Dav1dData *in, int global);
#endif /* __DAV1D_SRC_OBU_H__ */