Add a public function to parse the Sequence Header from raw bitstream data

Signed-off-by: James Almer's avatarJames Almer <jamrial@gmail.com>
parent 041f6535
......@@ -76,6 +76,22 @@ DAV1D_API void dav1d_default_settings(Dav1dSettings *s);
*/
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.
*
......
......@@ -167,6 +167,54 @@ error:
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 @@ int dav1d_get_picture(Dav1dContext *const c, Dav1dPicture *const out)
}
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;
}
......
......@@ -1157,7 +1157,7 @@ check_for_overrun(GetBits *const gb, unsigned init_bit_pos, unsigned obu_len)
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 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
// 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 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
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);
......
......@@ -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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment