Merge commit 'ce5870a3a8
'
* commit 'ce5870a3a8
':
cbs: Refcount all the things!
Some changes for bitstream API.
Merged-by: Mark Thompson <sw@jkqxz.net>
This commit is contained in:
commit
0cc8e34a94
15 changed files with 416 additions and 291 deletions
173
libavcodec/cbs.c
173
libavcodec/cbs.c
|
@ -21,6 +21,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/common.h"
|
||||
|
||||
#include "cbs.h"
|
||||
|
@ -95,11 +96,12 @@ void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
|
|||
static void cbs_unit_uninit(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit)
|
||||
{
|
||||
if (ctx->codec->free_unit && unit->content && !unit->content_external)
|
||||
ctx->codec->free_unit(unit);
|
||||
av_buffer_unref(&unit->content_ref);
|
||||
unit->content = NULL;
|
||||
|
||||
av_freep(&unit->data);
|
||||
unit->data_size = 0;
|
||||
av_buffer_unref(&unit->data_ref);
|
||||
unit->data = NULL;
|
||||
unit->data_size = 0;
|
||||
unit->data_bit_padding = 0;
|
||||
}
|
||||
|
||||
|
@ -113,7 +115,8 @@ void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
|
|||
av_freep(&frag->units);
|
||||
frag->nb_units = 0;
|
||||
|
||||
av_freep(&frag->data);
|
||||
av_buffer_unref(&frag->data_ref);
|
||||
frag->data = NULL;
|
||||
frag->data_size = 0;
|
||||
frag->data_bit_padding = 0;
|
||||
}
|
||||
|
@ -133,6 +136,9 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
|
|||
continue;
|
||||
}
|
||||
|
||||
av_buffer_unref(&frag->units[i].content_ref);
|
||||
frag->units[i].content = NULL;
|
||||
|
||||
err = ctx->codec->read_unit(ctx, &frag->units[i]);
|
||||
if (err == AVERROR(ENOSYS)) {
|
||||
av_log(ctx->log_ctx, AV_LOG_VERBOSE,
|
||||
|
@ -169,6 +175,27 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
|
|||
return cbs_read_fragment_content(ctx, frag);
|
||||
}
|
||||
|
||||
static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const uint8_t *data, size_t size)
|
||||
{
|
||||
av_assert0(!frag->data && !frag->data_ref);
|
||||
|
||||
frag->data_ref =
|
||||
av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!frag->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frag->data = frag->data_ref->data;
|
||||
frag->data_size = size;
|
||||
|
||||
memcpy(frag->data, data, size);
|
||||
memset(frag->data + size, 0,
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_cbs_read_packet(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
const AVPacket *pkt)
|
||||
|
@ -177,16 +204,24 @@ int ff_cbs_read_packet(CodedBitstreamContext *ctx,
|
|||
|
||||
memset(frag, 0, sizeof(*frag));
|
||||
|
||||
frag->data = pkt->data;
|
||||
frag->data_size = pkt->size;
|
||||
if (pkt->buf) {
|
||||
frag->data_ref = av_buffer_ref(pkt->buf);
|
||||
if (!frag->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frag->data = pkt->data;
|
||||
frag->data_size = pkt->size;
|
||||
|
||||
} else {
|
||||
err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ctx->codec->split_fragment(ctx, frag, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
frag->data = NULL;
|
||||
frag->data_size = 0;
|
||||
|
||||
return cbs_read_fragment_content(ctx, frag);
|
||||
}
|
||||
|
||||
|
@ -198,17 +233,14 @@ int ff_cbs_read(CodedBitstreamContext *ctx,
|
|||
|
||||
memset(frag, 0, sizeof(*frag));
|
||||
|
||||
// (We won't write to this during split.)
|
||||
frag->data = (uint8_t*)data;
|
||||
frag->data_size = size;
|
||||
err = cbs_fill_fragment_data(ctx, frag, data, size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = ctx->codec->split_fragment(ctx, frag, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
frag->data = NULL;
|
||||
frag->data_size = 0;
|
||||
|
||||
return cbs_read_fragment_content(ctx, frag);
|
||||
}
|
||||
|
||||
|
@ -219,17 +251,25 @@ int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
|
|||
int err, i;
|
||||
|
||||
for (i = 0; i < frag->nb_units; i++) {
|
||||
if (!frag->units[i].content)
|
||||
CodedBitstreamUnit *unit = &frag->units[i];
|
||||
|
||||
if (!unit->content)
|
||||
continue;
|
||||
|
||||
err = ctx->codec->write_unit(ctx, &frag->units[i]);
|
||||
av_buffer_unref(&unit->data_ref);
|
||||
unit->data = NULL;
|
||||
|
||||
err = ctx->codec->write_unit(ctx, unit);
|
||||
if (err < 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
|
||||
"(type %"PRIu32").\n", i, frag->units[i].type);
|
||||
"(type %"PRIu32").\n", i, unit->type);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
av_buffer_unref(&frag->data_ref);
|
||||
frag->data = NULL;
|
||||
|
||||
err = ctx->codec->assemble_fragment(ctx, frag);
|
||||
if (err < 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
|
||||
|
@ -394,6 +434,45 @@ int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
|
|||
}
|
||||
|
||||
|
||||
int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit,
|
||||
size_t size,
|
||||
void (*free)(void *opaque, uint8_t *data))
|
||||
{
|
||||
av_assert0(!unit->content && !unit->content_ref);
|
||||
|
||||
unit->content = av_mallocz(size);
|
||||
if (!unit->content)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
unit->content_ref = av_buffer_create(unit->content, size,
|
||||
free, ctx, 0);
|
||||
if (!unit->content_ref) {
|
||||
av_freep(&unit->content);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamUnit *unit,
|
||||
size_t size)
|
||||
{
|
||||
av_assert0(!unit->data && !unit->data_ref);
|
||||
|
||||
unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!unit->data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
unit->data = unit->data_ref->data;
|
||||
unit->data_size = size;
|
||||
|
||||
memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbs_insert_unit(CodedBitstreamContext *ctx,
|
||||
CodedBitstreamFragment *frag,
|
||||
int position)
|
||||
|
@ -423,21 +502,35 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
|
|||
CodedBitstreamFragment *frag,
|
||||
int position,
|
||||
CodedBitstreamUnitType type,
|
||||
void *content)
|
||||
void *content,
|
||||
AVBufferRef *content_buf)
|
||||
{
|
||||
CodedBitstreamUnit *unit;
|
||||
AVBufferRef *content_ref;
|
||||
int err;
|
||||
|
||||
if (position == -1)
|
||||
position = frag->nb_units;
|
||||
av_assert0(position >= 0 && position <= frag->nb_units);
|
||||
|
||||
err = cbs_insert_unit(ctx, frag, position);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (content_buf) {
|
||||
content_ref = av_buffer_ref(content_buf);
|
||||
if (!content_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
} else {
|
||||
content_ref = NULL;
|
||||
}
|
||||
|
||||
frag->units[position].type = type;
|
||||
frag->units[position].content = content;
|
||||
frag->units[position].content_external = 1;
|
||||
err = cbs_insert_unit(ctx, frag, position);
|
||||
if (err < 0) {
|
||||
av_buffer_unref(&content_ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
unit = &frag->units[position];
|
||||
unit->type = type;
|
||||
unit->content = content;
|
||||
unit->content_ref = content_ref;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -446,21 +539,35 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
|
|||
CodedBitstreamFragment *frag,
|
||||
int position,
|
||||
CodedBitstreamUnitType type,
|
||||
uint8_t *data, size_t data_size)
|
||||
uint8_t *data, size_t data_size,
|
||||
AVBufferRef *data_buf)
|
||||
{
|
||||
CodedBitstreamUnit *unit;
|
||||
AVBufferRef *data_ref;
|
||||
int err;
|
||||
|
||||
if (position == -1)
|
||||
position = frag->nb_units;
|
||||
av_assert0(position >= 0 && position <= frag->nb_units);
|
||||
|
||||
err = cbs_insert_unit(ctx, frag, position);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (data_buf)
|
||||
data_ref = av_buffer_ref(data_buf);
|
||||
else
|
||||
data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
|
||||
if (!data_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frag->units[position].type = type;
|
||||
frag->units[position].data = data;
|
||||
frag->units[position].data_size = data_size;
|
||||
err = cbs_insert_unit(ctx, frag, position);
|
||||
if (err < 0) {
|
||||
av_buffer_unref(&data_ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
unit = &frag->units[position];
|
||||
unit->type = type;
|
||||
unit->data = data;
|
||||
unit->data_size = data_size;
|
||||
unit->data_ref = data_ref;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue