#include "libavutil/avassert.h"
#include "libavutil/buffer.h"
#include "libavutil/common.h"
+#include "libavutil/opt.h"
#include "cbs.h"
#include "cbs_internal.h"
-static const CodedBitstreamType *cbs_type_table[] = {
+static const CodedBitstreamType *const cbs_type_table[] = {
#if CONFIG_CBS_AV1
&ff_cbs_type_av1,
#endif
return AVERROR(ENOMEM);
ctx->log_ctx = log_ctx;
- ctx->codec = type;
+ ctx->codec = type; /* Must be before any error */
if (type->priv_data_size) {
ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
av_freep(&ctx);
return AVERROR(ENOMEM);
}
+ if (type->priv_class) {
+ *(const AVClass **)ctx->priv_data = type->priv_class;
+ av_opt_set_defaults(ctx->priv_data);
+ }
}
ctx->decompose_unit_types = NULL;
return 0;
}
+void ff_cbs_flush(CodedBitstreamContext *ctx)
+{
+ if (ctx->codec->flush)
+ ctx->codec->flush(ctx);
+}
+
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
{
CodedBitstreamContext *ctx = *ctx_ptr;
if (!ctx)
return;
- if (ctx->codec && ctx->codec->close)
+ if (ctx->codec->close)
ctx->codec->close(ctx);
av_freep(&ctx->write_buffer);
+
+ if (ctx->codec->priv_class && ctx->priv_data)
+ av_opt_free(ctx->priv_data);
+
av_freep(&ctx->priv_data);
av_freep(ctx_ptr);
}
av_log(ctx->log_ctx, AV_LOG_VERBOSE,
"Decomposition unimplemented for unit %d "
"(type %"PRIu32").\n", i, unit->type);
+ } else if (err == AVERROR(EAGAIN)) {
+ av_log(ctx->log_ctx, AV_LOG_VERBOSE,
+ "Skipping decomposition of unit %d "
+ "(type %"PRIu32").\n", i, unit->type);
+ av_buffer_unref(&unit->content_ref);
+ unit->content = NULL;
} else if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
"(type %"PRIu32").\n", i, unit->type);
return 0;
}
-int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
- CodedBitstreamFragment *frag,
- const AVCodecParameters *par)
-{
- int err;
-
- err = cbs_fill_fragment_data(frag, par->extradata,
- par->extradata_size);
- if (err < 0)
- return err;
-
- err = ctx->codec->split_fragment(ctx, frag, 1);
- if (err < 0)
- return err;
-
- return cbs_read_fragment_content(ctx, frag);
-}
-
-int ff_cbs_read_packet(CodedBitstreamContext *ctx,
- CodedBitstreamFragment *frag,
- const AVPacket *pkt)
+static int cbs_read_data(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ AVBufferRef *buf,
+ const uint8_t *data, size_t size,
+ int header)
{
int err;
- if (pkt->buf) {
- frag->data_ref = av_buffer_ref(pkt->buf);
+ if (buf) {
+ frag->data_ref = av_buffer_ref(buf);
if (!frag->data_ref)
return AVERROR(ENOMEM);
- frag->data = pkt->data;
- frag->data_size = pkt->size;
+ frag->data = (uint8_t *)data;
+ frag->data_size = size;
} else {
- err = cbs_fill_fragment_data(frag, pkt->data, pkt->size);
+ err = cbs_fill_fragment_data(frag, data, size);
if (err < 0)
return err;
}
- err = ctx->codec->split_fragment(ctx, frag, 0);
+ err = ctx->codec->split_fragment(ctx, frag, header);
if (err < 0)
return err;
return cbs_read_fragment_content(ctx, frag);
}
-int ff_cbs_read(CodedBitstreamContext *ctx,
- CodedBitstreamFragment *frag,
- const uint8_t *data, size_t size)
+int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ const AVCodecParameters *par)
{
- int err;
+ return cbs_read_data(ctx, frag, NULL,
+ par->extradata,
+ par->extradata_size, 1);
+}
- err = cbs_fill_fragment_data(frag, data, size);
- if (err < 0)
- return err;
+int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ const AVCodecContext *avctx)
+{
+ return cbs_read_data(ctx, frag, NULL,
+ avctx->extradata,
+ avctx->extradata_size, 1);
+}
- err = ctx->codec->split_fragment(ctx, frag, 0);
- if (err < 0)
- return err;
+int ff_cbs_read_packet(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ const AVPacket *pkt)
+{
+ return cbs_read_data(ctx, frag, pkt->buf,
+ pkt->data, pkt->size, 0);
+}
- return cbs_read_fragment_content(ctx, frag);
+int ff_cbs_read(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *frag,
+ const uint8_t *data, size_t size)
+{
+ return cbs_read_data(ctx, frag, NULL,
+ data, size, 0);
}
static int cbs_write_unit_data(CodedBitstreamContext *ctx,
flush_put_bits(&pbc);
- ret = ff_cbs_alloc_unit_data(unit, put_bits_count(&pbc) / 8);
+ ret = ff_cbs_alloc_unit_data(unit, put_bytes_output(&pbc));
if (ret < 0)
return ret;