mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-03-06 20:47:41 +00:00
avcodec/cbs: Avoid code duplication for making unit refcounted/writable
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
9d0c71a81c
commit
33f33beead
@ -921,9 +921,9 @@ int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cbs_clone_unit_content(AVBufferRef **clone_ref,
|
static int cbs_clone_internal_refs_unit_content(AVBufferRef **clone_ref,
|
||||||
CodedBitstreamUnit *unit,
|
const CodedBitstreamUnit *unit,
|
||||||
const CodedBitstreamUnitTypeDescriptor *desc)
|
const CodedBitstreamUnitTypeDescriptor *desc)
|
||||||
{
|
{
|
||||||
uint8_t *src, *copy;
|
uint8_t *src, *copy;
|
||||||
uint8_t **src_ptr, **copy_ptr;
|
uint8_t **src_ptr, **copy_ptr;
|
||||||
@ -987,19 +987,18 @@ fail:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
|
/*
|
||||||
CodedBitstreamUnit *unit)
|
* On success, unit->content and unit->content_ref are updated with
|
||||||
|
* the new content; unit is untouched on failure.
|
||||||
|
* Any old content_ref is simply overwritten and not freed.
|
||||||
|
*/
|
||||||
|
static int cbs_clone_unit_content(CodedBitstreamContext *ctx,
|
||||||
|
CodedBitstreamUnit *unit)
|
||||||
{
|
{
|
||||||
const CodedBitstreamUnitTypeDescriptor *desc;
|
const CodedBitstreamUnitTypeDescriptor *desc;
|
||||||
AVBufferRef *ref;
|
AVBufferRef *ref;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
av_assert0(unit->content);
|
|
||||||
if (unit->content_ref) {
|
|
||||||
// Already refcounted, nothing to do.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
desc = cbs_find_unit_type_desc(ctx, unit);
|
desc = cbs_find_unit_type_desc(ctx, unit);
|
||||||
if (!desc)
|
if (!desc)
|
||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
@ -1014,7 +1013,7 @@ int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CBS_CONTENT_TYPE_INTERNAL_REFS:
|
case CBS_CONTENT_TYPE_INTERNAL_REFS:
|
||||||
err = cbs_clone_unit_content(&ref, unit, desc);
|
err = cbs_clone_internal_refs_unit_content(&ref, unit, desc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CBS_CONTENT_TYPE_COMPLEX:
|
case CBS_CONTENT_TYPE_COMPLEX:
|
||||||
@ -1035,51 +1034,28 @@ int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
|
||||||
|
CodedBitstreamUnit *unit)
|
||||||
|
{
|
||||||
|
av_assert0(unit->content);
|
||||||
|
if (unit->content_ref)
|
||||||
|
return 0;
|
||||||
|
return cbs_clone_unit_content(ctx, unit);
|
||||||
|
}
|
||||||
|
|
||||||
int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
|
int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
|
||||||
CodedBitstreamUnit *unit)
|
CodedBitstreamUnit *unit)
|
||||||
{
|
{
|
||||||
const CodedBitstreamUnitTypeDescriptor *desc;
|
AVBufferRef *ref = unit->content_ref;
|
||||||
AVBufferRef *ref;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
// This can only be applied to refcounted units.
|
av_assert0(unit->content);
|
||||||
err = ff_cbs_make_unit_refcounted(ctx, unit);
|
if (ref && av_buffer_is_writable(ref))
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
av_assert0(unit->content && unit->content_ref);
|
|
||||||
|
|
||||||
if (av_buffer_is_writable(unit->content_ref))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
desc = cbs_find_unit_type_desc(ctx, unit);
|
err = cbs_clone_unit_content(ctx, unit);
|
||||||
if (!desc)
|
|
||||||
return AVERROR(ENOSYS);
|
|
||||||
|
|
||||||
switch (desc->content_type) {
|
|
||||||
case CBS_CONTENT_TYPE_POD:
|
|
||||||
err = av_buffer_make_writable(&unit->content_ref);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CBS_CONTENT_TYPE_INTERNAL_REFS:
|
|
||||||
err = cbs_clone_unit_content(&ref, unit, desc);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CBS_CONTENT_TYPE_COMPLEX:
|
|
||||||
if (!desc->content_clone)
|
|
||||||
return AVERROR_PATCHWELCOME;
|
|
||||||
err = desc->content_clone(&ref, unit);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
av_assert0(0 && "Invalid content type.");
|
|
||||||
}
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
av_buffer_unref(&ref);
|
||||||
if (desc->content_type != CBS_CONTENT_TYPE_POD) {
|
|
||||||
av_buffer_unref(&unit->content_ref);
|
|
||||||
unit->content_ref = ref;
|
|
||||||
}
|
|
||||||
unit->content = unit->content_ref->data;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user