Commit ce5870a3 authored by Mark Thompson's avatar Mark Thompson

cbs: Refcount all the things!

This makes it easier for users of the CBS API to get alloc/free right -
all subelements use the buffer API so that it's clear how to free them.
It also allows eliding some redundant copies: the packet -> fragment copy
disappears after this change if the input packet is refcounted, and more
codec-specific cases are now possible (but not included in this patch).
parent 13ca5d34
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/buffer.h"
#include "libavutil/common.h" #include "libavutil/common.h"
#include "cbs.h" #include "cbs.h"
...@@ -95,10 +96,11 @@ void ff_cbs_close(CodedBitstreamContext **ctx_ptr) ...@@ -95,10 +96,11 @@ void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
static void cbs_unit_uninit(CodedBitstreamContext *ctx, static void cbs_unit_uninit(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit) CodedBitstreamUnit *unit)
{ {
if (ctx->codec->free_unit && unit->content && !unit->content_external) av_buffer_unref(&unit->content_ref);
ctx->codec->free_unit(unit); unit->content = NULL;
av_freep(&unit->data); av_buffer_unref(&unit->data_ref);
unit->data = NULL;
unit->data_size = 0; unit->data_size = 0;
unit->data_bit_padding = 0; unit->data_bit_padding = 0;
} }
...@@ -113,7 +115,8 @@ void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx, ...@@ -113,7 +115,8 @@ void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
av_freep(&frag->units); av_freep(&frag->units);
frag->nb_units = 0; frag->nb_units = 0;
av_freep(&frag->data); av_buffer_unref(&frag->data_ref);
frag->data = NULL;
frag->data_size = 0; frag->data_size = 0;
frag->data_bit_padding = 0; frag->data_bit_padding = 0;
} }
...@@ -133,6 +136,9 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx, ...@@ -133,6 +136,9 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
continue; continue;
} }
av_buffer_unref(&frag->units[i].content_ref);
frag->units[i].content = NULL;
err = ctx->codec->read_unit(ctx, &frag->units[i]); err = ctx->codec->read_unit(ctx, &frag->units[i]);
if (err == AVERROR(ENOSYS)) { if (err == AVERROR(ENOSYS)) {
av_log(ctx->log_ctx, AV_LOG_VERBOSE, av_log(ctx->log_ctx, AV_LOG_VERBOSE,
...@@ -169,6 +175,27 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx, ...@@ -169,6 +175,27 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
return cbs_read_fragment_content(ctx, frag); 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, int ff_cbs_read_packet(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
const AVPacket *pkt) const AVPacket *pkt)
...@@ -177,15 +204,23 @@ int ff_cbs_read_packet(CodedBitstreamContext *ctx, ...@@ -177,15 +204,23 @@ int ff_cbs_read_packet(CodedBitstreamContext *ctx,
memset(frag, 0, sizeof(*frag)); memset(frag, 0, sizeof(*frag));
if (pkt->buf) {
frag->data_ref = av_buffer_ref(pkt->buf);
if (!frag->data_ref)
return AVERROR(ENOMEM);
frag->data = pkt->data; frag->data = pkt->data;
frag->data_size = pkt->size; frag->data_size = pkt->size;
err = ctx->codec->split_fragment(ctx, frag, 0); } else {
err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
if (err < 0) if (err < 0)
return err; return err;
}
frag->data = NULL; err = ctx->codec->split_fragment(ctx, frag, 0);
frag->data_size = 0; if (err < 0)
return err;
return cbs_read_fragment_content(ctx, frag); return cbs_read_fragment_content(ctx, frag);
} }
...@@ -198,17 +233,14 @@ int ff_cbs_read(CodedBitstreamContext *ctx, ...@@ -198,17 +233,14 @@ int ff_cbs_read(CodedBitstreamContext *ctx,
memset(frag, 0, sizeof(*frag)); memset(frag, 0, sizeof(*frag));
// (We won't write to this during split.) err = cbs_fill_fragment_data(ctx, frag, data, size);
frag->data = (uint8_t*)data; if (err < 0)
frag->data_size = size; return err;
err = ctx->codec->split_fragment(ctx, frag, 0); err = ctx->codec->split_fragment(ctx, frag, 0);
if (err < 0) if (err < 0)
return err; return err;
frag->data = NULL;
frag->data_size = 0;
return cbs_read_fragment_content(ctx, frag); return cbs_read_fragment_content(ctx, frag);
} }
...@@ -219,17 +251,25 @@ int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx, ...@@ -219,17 +251,25 @@ int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
int err, i; int err, i;
for (i = 0; i < frag->nb_units; i++) { for (i = 0; i < frag->nb_units; i++) {
if (!frag->units[i].content) CodedBitstreamUnit *unit = &frag->units[i];
if (!unit->content)
continue; 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) { if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d " 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; return err;
} }
} }
av_buffer_unref(&frag->data_ref);
frag->data = NULL;
err = ctx->codec->assemble_fragment(ctx, frag); err = ctx->codec->assemble_fragment(ctx, frag);
if (err < 0) { if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n"); 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, ...@@ -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, static int cbs_insert_unit(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
int position) int position)
...@@ -423,21 +502,35 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, ...@@ -423,21 +502,35 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
int position, int position,
CodedBitstreamUnitType type, CodedBitstreamUnitType type,
void *content) void *content,
AVBufferRef *content_buf)
{ {
CodedBitstreamUnit *unit;
AVBufferRef *content_ref;
int err; int err;
if (position == -1) if (position == -1)
position = frag->nb_units; position = frag->nb_units;
av_assert0(position >= 0 && position <= frag->nb_units); av_assert0(position >= 0 && position <= frag->nb_units);
if (content_buf) {
content_ref = av_buffer_ref(content_buf);
if (!content_ref)
return AVERROR(ENOMEM);
} else {
content_ref = NULL;
}
err = cbs_insert_unit(ctx, frag, position); err = cbs_insert_unit(ctx, frag, position);
if (err < 0) if (err < 0) {
av_buffer_unref(&content_ref);
return err; return err;
}
frag->units[position].type = type; unit = &frag->units[position];
frag->units[position].content = content; unit->type = type;
frag->units[position].content_external = 1; unit->content = content;
unit->content_ref = content_ref;
return 0; return 0;
} }
...@@ -446,21 +539,35 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, ...@@ -446,21 +539,35 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
int position, int position,
CodedBitstreamUnitType type, 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; int err;
if (position == -1) if (position == -1)
position = frag->nb_units; position = frag->nb_units;
av_assert0(position >= 0 && position <= frag->nb_units); av_assert0(position >= 0 && position <= frag->nb_units);
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);
err = cbs_insert_unit(ctx, frag, position); err = cbs_insert_unit(ctx, frag, position);
if (err < 0) if (err < 0) {
av_buffer_unref(&data_ref);
return err; return err;
}
frag->units[position].type = type; unit = &frag->units[position];
frag->units[position].data = data; unit->type = type;
frag->units[position].data_size = data_size; unit->data = data;
unit->data_size = data_size;
unit->data_ref = data_ref;
return 0; return 0;
} }
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "libavutil/buffer.h"
#include "avcodec.h" #include "avcodec.h"
...@@ -81,6 +83,11 @@ typedef struct CodedBitstreamUnit { ...@@ -81,6 +83,11 @@ typedef struct CodedBitstreamUnit {
* This supports non-byte-aligned bitstreams. * This supports non-byte-aligned bitstreams.
*/ */
size_t data_bit_padding; size_t data_bit_padding;
/**
* If data is reference counted, a reference to the buffer containing
* data. Null if data is not reference counted.
*/
AVBufferRef *data_ref;
/** /**
* Pointer to the decomposed form of this unit. * Pointer to the decomposed form of this unit.
...@@ -91,11 +98,10 @@ typedef struct CodedBitstreamUnit { ...@@ -91,11 +98,10 @@ typedef struct CodedBitstreamUnit {
*/ */
void *content; void *content;
/** /**
* Whether the content was supplied externally. * If content is reference counted, a reference to the buffer containing
* * content. Null if content is not reference counted.
* If so, it should not be freed when freeing the unit.
*/ */
int content_external; AVBufferRef *content_ref;
} CodedBitstreamUnit; } CodedBitstreamUnit;
/** /**
...@@ -123,6 +129,11 @@ typedef struct CodedBitstreamFragment { ...@@ -123,6 +129,11 @@ typedef struct CodedBitstreamFragment {
* The number of bits which should be ignored in the final byte. * The number of bits which should be ignored in the final byte.
*/ */
size_t data_bit_padding; size_t data_bit_padding;
/**
* If data is reference counted, a reference to the buffer containing
* data. Null if data is not reference counted.
*/
AVBufferRef *data_ref;
/** /**
* Number of units in this fragment. * Number of units in this fragment.
...@@ -278,28 +289,50 @@ void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx, ...@@ -278,28 +289,50 @@ void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag); CodedBitstreamFragment *frag);
/**
* Allocate a new internal content buffer of the given size in the unit.
*
* The content will be zeroed.
*/
int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit,
size_t size,
void (*free)(void *unit, uint8_t *content));
/**
* Allocate a new internal data buffer of the given size in the unit.
*
* The data buffer will have input padding.
*/
int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit,
size_t size);
/** /**
* Insert a new unit into a fragment with the given content. * Insert a new unit into a fragment with the given content.
* *
* The content structure continues to be owned by the caller, and * The content structure continues to be owned by the caller if
* will not be freed when the unit is. * content_buf is not supplied.
*/ */
int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
int position, int position,
CodedBitstreamUnitType type, CodedBitstreamUnitType type,
void *content); void *content,
AVBufferRef *content_buf);
/** /**
* Insert a new unit into a fragment with the given data bitstream. * Insert a new unit into a fragment with the given data bitstream.
* *
* The data buffer will be owned by the unit after this operation. * If data_buf is not supplied then data must have been allocated with
* av_malloc() and will become owned by the unit after this call.
*/ */
int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
int position, int position,
CodedBitstreamUnitType type, CodedBitstreamUnitType type,
uint8_t *data, size_t data_size); uint8_t *data, size_t data_size,
AVBufferRef *data_buf);
/** /**
* Delete a unit from a fragment and free all memory it uses. * Delete a unit from a fragment and free all memory it uses.
......
...@@ -266,12 +266,14 @@ typedef struct H264RawSEIUserDataRegistered { ...@@ -266,12 +266,14 @@ typedef struct H264RawSEIUserDataRegistered {
uint8_t itu_t_t35_country_code_extension_byte; uint8_t itu_t_t35_country_code_extension_byte;
uint8_t *data; uint8_t *data;
size_t data_length; size_t data_length;
AVBufferRef *data_ref;
} H264RawSEIUserDataRegistered; } H264RawSEIUserDataRegistered;
typedef struct H264RawSEIUserDataUnregistered { typedef struct H264RawSEIUserDataUnregistered {
uint8_t uuid_iso_iec_11578[16]; uint8_t uuid_iso_iec_11578[16];
uint8_t *data; uint8_t *data;
size_t data_length; size_t data_length;
AVBufferRef *data_ref;
} H264RawSEIUserDataUnregistered; } H264RawSEIUserDataUnregistered;
typedef struct H264RawSEIRecoveryPoint { typedef struct H264RawSEIRecoveryPoint {
...@@ -304,6 +306,7 @@ typedef struct H264RawSEIPayload { ...@@ -304,6 +306,7 @@ typedef struct H264RawSEIPayload {
struct { struct {
uint8_t *data; uint8_t *data;
size_t data_length; size_t data_length;
AVBufferRef *data_ref;
} other; } other;
} payload; } payload;
} H264RawSEIPayload; } H264RawSEIPayload;
...@@ -399,6 +402,7 @@ typedef struct H264RawSlice { ...@@ -399,6 +402,7 @@ typedef struct H264RawSlice {
uint8_t *data; uint8_t *data;
size_t data_size; size_t data_size;
int data_bit_start; int data_bit_start;
AVBufferRef *data_ref;
} H264RawSlice; } H264RawSlice;
......
...@@ -291,9 +291,10 @@ static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc) ...@@ -291,9 +291,10 @@ static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc)
#define byte_alignment(rw) (bitstream_tell(rw) % 8) #define byte_alignment(rw) (bitstream_tell(rw) % 8)
#define allocate(name, size) do { \ #define allocate(name, size) do { \
name = av_mallocz(size); \ name ## _ref = av_buffer_allocz(size); \
if (!name) \ if (!name ## _ref) \
return AVERROR(ENOMEM); \ return AVERROR(ENOMEM); \
name = name ## _ref->data; \
} while (0) } while (0)
#define FUNC(name) FUNC_H264(READWRITE, name) #define FUNC(name) FUNC_H264(READWRITE, name)
...@@ -393,12 +394,8 @@ static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc) ...@@ -393,12 +394,8 @@ static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc)
#undef allocate #undef allocate
static void cbs_h264_free_sei(H264RawSEI *sei) static void cbs_h264_free_sei_payload(H264RawSEIPayload *payload)
{ {
int i;
for (i = 0; i < sei->payload_count; i++) {
H264RawSEIPayload *payload = &sei->payload[i];
switch (payload->payload_type) { switch (payload->payload_type) {
case H264_SEI_TYPE_BUFFERING_PERIOD: case H264_SEI_TYPE_BUFFERING_PERIOD:
case H264_SEI_TYPE_PIC_TIMING: case H264_SEI_TYPE_PIC_TIMING:
...@@ -406,69 +403,59 @@ static void cbs_h264_free_sei(H264RawSEI *sei) ...@@ -406,69 +403,59 @@ static void cbs_h264_free_sei(H264RawSEI *sei)
case H264_SEI_TYPE_DISPLAY_ORIENTATION: case H264_SEI_TYPE_DISPLAY_ORIENTATION:
break; break;
case H264_SEI_TYPE_USER_DATA_REGISTERED: case H264_SEI_TYPE_USER_DATA_REGISTERED:
av_freep(&payload->payload.user_data_registered.data); av_buffer_unref(&payload->payload.user_data_registered.data_ref);
break; break;
case H264_SEI_TYPE_USER_DATA_UNREGISTERED: case H264_SEI_TYPE_USER_DATA_UNREGISTERED:
av_freep(&payload->payload.user_data_unregistered.data); av_buffer_unref(&payload->payload.user_data_unregistered.data_ref);
break; break;
default: default:
av_freep(&payload->payload.other.data); av_buffer_unref(&payload->payload.other.data_ref);
break; break;
} }
}
} }
static void cbs_h264_free_slice(H264RawSlice *slice) static void cbs_h264_free_sei(void *unit, uint8_t *content)
{ {
av_freep(&slice->data); H264RawSEI *sei = (H264RawSEI*)content;
int i;
for (i = 0; i < sei->payload_count; i++)
cbs_h264_free_sei_payload(&sei->payload[i]);
av_freep(&content);
} }
static void cbs_h264_free_nal_unit(CodedBitstreamUnit *unit) static void cbs_h264_free_slice(void *unit, uint8_t *content)
{ {
switch (unit->type) { H264RawSlice *slice = (H264RawSlice*)content;
case H264_NAL_SEI: av_buffer_unref(&slice->data_ref);
cbs_h264_free_sei(unit->content); av_freep(&content);
break;
case H264_NAL_IDR_SLICE:
case H264_NAL_SLICE:
cbs_h264_free_slice(unit->content);
break;
}
av_freep(&unit->content);
} }
static void cbs_h265_free_nal_unit(CodedBitstreamUnit *unit) static void cbs_h265_free_vps(void *unit, uint8_t *content)
{ {
switch (unit->type) { H265RawVPS *vps = (H265RawVPS*)content;
case HEVC_NAL_VPS: av_buffer_unref(&vps->extension_data.data_ref);
av_freep(&((H265RawVPS*)unit->content)->extension_data.data); av_freep(&content);
break; }
case HEVC_NAL_SPS:
av_freep(&((H265RawSPS*)unit->content)->extension_data.data); static void cbs_h265_free_sps(void *unit, uint8_t *content)
break; {
case HEVC_NAL_PPS: H265RawSPS *sps = (H265RawSPS*)content;
av_freep(&((H265RawPPS*)unit->content)->extension_data.data); av_buffer_unref(&sps->extension_data.data_ref);
break; av_freep(&content);
case HEVC_NAL_TRAIL_N: }
case HEVC_NAL_TRAIL_R:
case HEVC_NAL_TSA_N: static void cbs_h265_free_pps(void *unit, uint8_t *content)
case HEVC_NAL_TSA_R: {
case HEVC_NAL_STSA_N: H265RawPPS *pps = (H265RawPPS*)content;
case HEVC_NAL_STSA_R: av_buffer_unref(&pps->extension_data.data_ref);
case HEVC_NAL_RADL_N: av_freep(&content);
case HEVC_NAL_RADL_R: }
case HEVC_NAL_RASL_N:
case HEVC_NAL_RASL_R: static void cbs_h265_free_slice(void *unit, uint8_t *content)
case HEVC_NAL_BLA_W_LP: {
case HEVC_NAL_BLA_W_RADL: H265RawSlice *slice = (H265RawSlice*)content;
case HEVC_NAL_BLA_N_LP: av_buffer_unref(&slice->data_ref);
case HEVC_NAL_IDR_W_RADL: av_freep(&content);
case HEVC_NAL_IDR_N_LP:
case HEVC_NAL_CRA_NUT:
av_freep(&((H265RawSlice*)unit->content)->data);
break;
}
av_freep(&unit->content);
} }
static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx,
...@@ -494,7 +481,7 @@ static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, ...@@ -494,7 +481,7 @@ static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx,
memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
err = ff_cbs_insert_unit_data(ctx, frag, -1, nal->type, err = ff_cbs_insert_unit_data(ctx, frag, -1, nal->type,
data, nal->size); data, nal->size, NULL);
if (err < 0) { if (err < 0) {
av_freep(&data); av_freep(&data);
return err; return err;
...@@ -705,35 +692,32 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -705,35 +692,32 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
{ {
H264RawSPS *sps; H264RawSPS *sps;
sps = av_mallocz(sizeof(*sps)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps), NULL);
if (!sps) if (err < 0)
return AVERROR(ENOMEM); return err;
sps = unit->content;
err = cbs_h264_read_sps(ctx, &bc, sps); err = cbs_h264_read_sps(ctx, &bc, sps);
if (err >= 0) if (err < 0)
err = cbs_h264_replace_sps(ctx, sps);
if (err < 0) {
av_free(sps);
return err; return err;
}
unit->content = sps; err = cbs_h264_replace_sps(ctx, sps);
if (err < 0)
return err;
} }
break; break;
case H264_NAL_SPS_EXT: case H264_NAL_SPS_EXT:
{ {
H264RawSPSExtension *sps_ext; err = ff_cbs_alloc_unit_content(ctx, unit,
sizeof(H264RawSPSExtension),
sps_ext = av_mallocz(sizeof(*sps_ext)); NULL);
if (!sps_ext) if (err < 0)
return AVERROR(ENOMEM);
err = cbs_h264_read_sps_extension(ctx, &bc, sps_ext);
if (err < 0) {
av_free(sps_ext);
return err; return err;
}
unit->content = sps_ext; err = cbs_h264_read_sps_extension(ctx, &bc, unit->content);
if (err < 0)
return err;
} }
break; break;
...@@ -741,18 +725,18 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -741,18 +725,18 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
{ {
H264RawPPS *pps; H264RawPPS *pps;
pps = av_mallocz(sizeof(*pps)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps), NULL);
if (!pps) if (err < 0)
return AVERROR(ENOMEM); return err;
pps = unit->content;
err = cbs_h264_read_pps(ctx, &bc, pps); err = cbs_h264_read_pps(ctx, &bc, pps);
if (err >= 0) if (err < 0)
err = cbs_h264_replace_pps(ctx, pps);
if (err < 0) {
av_free(pps);
return err; return err;
}
unit->content = pps; err = cbs_h264_replace_pps(ctx, pps);
if (err < 0)
return err;
} }
break; break;
...@@ -763,14 +747,15 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -763,14 +747,15 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
H264RawSlice *slice; H264RawSlice *slice;
int pos, len; int pos, len;
slice = av_mallocz(sizeof(*slice)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
if (!slice) &cbs_h264_free_slice);
return AVERROR(ENOMEM); if (err < 0)
return err;
slice = unit->content;
err = cbs_h264_read_slice_header(ctx, &bc, &slice->header); err = cbs_h264_read_slice_header(ctx, &bc, &slice->header);
if (err < 0) { if (err < 0)
av_free(slice);
return err; return err;
}
pos = bitstream_tell(&bc); pos = bitstream_tell(&bc);
len = unit->data_size; len = unit->data_size;
...@@ -783,54 +768,42 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -783,54 +768,42 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx,
} }
slice->data_size = len - pos / 8; slice->data_size = len - pos / 8;
slice->data = av_malloc(slice->data_size + slice->data_ref = av_buffer_alloc(slice->data_size +
AV_INPUT_BUFFER_PADDING_SIZE); AV_INPUT_BUFFER_PADDING_SIZE);
if (!slice->data) { if (!slice->data_ref)
av_free(slice);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} slice->data = slice->data_ref->data;
memcpy(slice->data, memcpy(slice->data,
unit->data + pos / 8, slice->data_size); unit->data + pos / 8, slice->data_size);
memset(slice->data + slice->data_size, 0, memset(slice->data + slice->data_size, 0,
AV_INPUT_BUFFER_PADDING_SIZE); AV_INPUT_BUFFER_PADDING_SIZE);
slice->data_bit_start = pos % 8; slice->data_bit_start = pos % 8;
unit->content = slice;
} }
break; break;
case H264_NAL_AUD: case H264_NAL_AUD:
{ {
H264RawAUD *aud; err = ff_cbs_alloc_unit_content(ctx, unit,
sizeof(H264RawAUD), NULL);
aud = av_mallocz(sizeof(*aud)); if (err < 0)
if (!aud)
return AVERROR(ENOMEM);
err = cbs_h264_read_aud(ctx, &bc, aud);
if (err < 0) {
av_free(aud);
return err; return err;
}
unit->content = aud; err = cbs_h264_read_aud(ctx, &bc, unit->content);
if (err < 0)
return err;
} }
break; break;
case H264_NAL_SEI: case H264_NAL_SEI:
{ {
H264RawSEI *sei; err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H264RawSEI),
&cbs_h264_free_sei);
sei = av_mallocz(sizeof(*sei)); if (err < 0)
if (!sei)
return AVERROR(ENOMEM);
err = cbs_h264_read_sei(ctx, &bc, sei);
if (err < 0) {
cbs_h264_free_sei(sei);
av_free(sei);
return err; return err;
}
unit->content = sei; err = cbs_h264_read_sei(ctx, &bc, unit->content);
if (err < 0)
return err;
} }
break; break;
...@@ -856,36 +829,38 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -856,36 +829,38 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
{ {
H265RawVPS *vps; H265RawVPS *vps;
vps = av_mallocz(sizeof(*vps)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*vps),
if (!vps) &cbs_h265_free_vps);
return AVERROR(ENOMEM); if (err < 0)
return err;
vps = unit->content;
err = cbs_h265_read_vps(ctx, &bc, vps); err = cbs_h265_read_vps(ctx, &bc, vps);
if (err >= 0) if (err < 0)
err = cbs_h265_replace_vps(ctx, vps);
if (err < 0) {
av_free(vps);
return err; return err;
}
unit->content = vps; err = cbs_h265_replace_vps(ctx, vps);
if (err < 0)
return err;
} }
break; break;
case HEVC_NAL_SPS: case HEVC_NAL_SPS:
{ {
H265RawSPS *sps; H265RawSPS *sps;
sps = av_mallocz(sizeof(*sps)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps),
if (!sps) &cbs_h265_free_sps);
return AVERROR(ENOMEM); if (err < 0)
return err;
sps = unit->content;
err = cbs_h265_read_sps(ctx, &bc, sps); err = cbs_h265_read_sps(ctx, &bc, sps);
if (err >= 0) if (err < 0)
err = cbs_h265_replace_sps(ctx, sps);
if (err < 0) {
av_free(sps);
return err; return err;
}
unit->content = sps; err = cbs_h265_replace_sps(ctx, sps);
if (err < 0)
return err;
} }
break; break;
...@@ -893,18 +868,19 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -893,18 +868,19 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
{ {
H265RawPPS *pps; H265RawPPS *pps;
pps = av_mallocz(sizeof(*pps)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps),
if (!pps) &cbs_h265_free_pps);
return AVERROR(ENOMEM); if (err < 0)
return err;
pps = unit->content;
err = cbs_h265_read_pps(ctx, &bc, pps); err = cbs_h265_read_pps(ctx, &bc, pps);
if (err >= 0) if (err < 0)
err = cbs_h265_replace_pps(ctx, pps);
if (err < 0) {
av_free(pps);
return err; return err;
}
unit->content = pps; err = cbs_h265_replace_pps(ctx, pps);
if (err < 0)
return err;
} }
break; break;
...@@ -928,14 +904,15 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -928,14 +904,15 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
H265RawSlice *slice; H265RawSlice *slice;
int pos, len; int pos, len;
slice = av_mallocz(sizeof(*slice)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
if (!slice) &cbs_h265_free_slice);
return AVERROR(ENOMEM); if (err < 0)
return err;
slice = unit->content;
err = cbs_h265_read_slice_segment_header(ctx, &bc, &slice->header); err = cbs_h265_read_slice_segment_header(ctx, &bc, &slice->header);
if (err < 0) { if (err < 0)
av_free(slice);
return err; return err;
}
pos = bitstream_tell(&bc); pos = bitstream_tell(&bc);
len = unit->data_size; len = unit->data_size;
...@@ -948,36 +925,29 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, ...@@ -948,36 +925,29 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
} }
slice->data_size = len - pos / 8; slice->data_size = len - pos / 8;
slice->data = av_malloc(slice->data_size + slice->data_ref = av_buffer_alloc(slice->data_size +
AV_INPUT_BUFFER_PADDING_SIZE); AV_INPUT_BUFFER_PADDING_SIZE);
if (!slice->data) { if (!slice->data_ref)
av_free(slice);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} slice->data = slice->data_ref->data;
memcpy(slice->data, memcpy(slice->data,
unit->data + pos / 8, slice->data_size); unit->data + pos / 8, slice->data_size);
memset(slice->data + slice->data_size, 0, memset(slice->data + slice->data_size, 0,
AV_INPUT_BUFFER_PADDING_SIZE); AV_INPUT_BUFFER_PADDING_SIZE);
slice->data_bit_start = pos % 8; slice->data_bit_start = pos % 8;
unit->content = slice;
} }
break; break;
case HEVC_NAL_AUD: case HEVC_NAL_AUD:
{ {
H265RawAUD *aud; err = ff_cbs_alloc_unit_content(ctx, unit,
sizeof(H265RawAUD), NULL);
aud = av_mallocz(sizeof(*aud)); if (err < 0)
if (!aud)
return AVERROR(ENOMEM);
err = cbs_h265_read_aud(ctx, &bc, aud);
if (err < 0) {
av_free(aud);
return err; return err;
}
unit->content = aud; err = cbs_h265_read_aud(ctx, &bc, unit->content);
if (err < 0)
return err;
} }
break; break;
...@@ -1272,7 +1242,7 @@ static int cbs_h2645_write_nal_unit(CodedBitstreamContext *ctx, ...@@ -1272,7 +1242,7 @@ static int cbs_h2645_write_nal_unit(CodedBitstreamContext *ctx,
unit->data_size = (put_bits_count(&pbc) + 7) / 8; unit->data_size = (put_bits_count(&pbc) + 7) / 8;
flush_put_bits(&pbc); flush_put_bits(&pbc);
err = av_reallocp(&unit->data, unit->data_size); err = ff_cbs_alloc_unit_data(ctx, unit, unit->data_size);
if (err < 0) if (err < 0)
return err; return err;
...@@ -1354,6 +1324,12 @@ static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, ...@@ -1354,6 +1324,12 @@ static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx,
if (err) if (err)
return err; return err;
frag->data_ref = av_buffer_create(data, dp, NULL, NULL, 0);
if (!frag->data_ref) {
av_freep(&data);
return AVERROR(ENOMEM);
}
frag->data = data; frag->data = data;
frag->data_size = dp; frag->data_size = dp;
...@@ -1402,7 +1378,6 @@ const CodedBitstreamType ff_cbs_type_h264 = { ...@@ -1402,7 +1378,6 @@ const CodedBitstreamType ff_cbs_type_h264 = {
.write_unit = &cbs_h2645_write_nal_unit, .write_unit = &cbs_h2645_write_nal_unit,
.assemble_fragment = &cbs_h2645_assemble_fragment, .assemble_fragment = &cbs_h2645_assemble_fragment,
.free_unit = &cbs_h264_free_nal_unit,
.close = &cbs_h264_close, .close = &cbs_h264_close,
}; };
...@@ -1416,6 +1391,5 @@ const CodedBitstreamType ff_cbs_type_h265 = { ...@@ -1416,6 +1391,5 @@ const CodedBitstreamType ff_cbs_type_h265 = {
.write_unit = &cbs_h2645_write_nal_unit, .write_unit = &cbs_h2645_write_nal_unit,
.assemble_fragment = &cbs_h2645_assemble_fragment, .assemble_fragment = &cbs_h2645_assemble_fragment,
.free_unit = &cbs_h265_free_nal_unit,
.close = &cbs_h265_close, .close = &cbs_h265_close,
}; };
...@@ -154,6 +154,7 @@ typedef struct H265RawVUI { ...@@ -154,6 +154,7 @@ typedef struct H265RawVUI {
typedef struct H265RawPSExtensionData { typedef struct H265RawPSExtensionData {
uint8_t *data; uint8_t *data;
size_t bit_length; size_t bit_length;
AVBufferRef *data_ref;
} H265RawPSExtensionData; } H265RawPSExtensionData;
typedef struct H265RawVPS { typedef struct H265RawVPS {
...@@ -512,6 +513,7 @@ typedef struct H265RawSlice { ...@@ -512,6 +513,7 @@ typedef struct H265RawSlice {
uint8_t *data; uint8_t *data;
size_t data_size; size_t data_size;
int data_bit_start; int data_bit_start;
AVBufferRef *data_ref;
} H265RawSlice; } H265RawSlice;
......
...@@ -53,9 +53,6 @@ typedef struct CodedBitstreamType { ...@@ -53,9 +53,6 @@ typedef struct CodedBitstreamType {
int (*assemble_fragment)(CodedBitstreamContext *ctx, int (*assemble_fragment)(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag); CodedBitstreamFragment *frag);
// Free the content and data of a single unit.
void (*free_unit)(CodedBitstreamUnit *unit);
// Free the codec internal state. // Free the codec internal state.
void (*close)(CodedBitstreamContext *ctx); void (*close)(CodedBitstreamContext *ctx);
} CodedBitstreamType; } CodedBitstreamType;
......
...@@ -102,6 +102,21 @@ ...@@ -102,6 +102,21 @@
#undef nextbits #undef nextbits
static void cbs_mpeg2_free_user_data(void *unit, uint8_t *content)
{
MPEG2RawUserData *user = (MPEG2RawUserData*)content;
av_buffer_unref(&user->user_data_ref);
av_freep(&content);
}
static void cbs_mpeg2_free_slice(void *unit, uint8_t *content)
{
MPEG2RawSlice *slice = (MPEG2RawSlice*)content;
av_buffer_unref(&slice->header.extra_information_ref);
av_buffer_unref(&slice->data_ref);
av_freep(&content);
}
static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag, CodedBitstreamFragment *frag,
int header) int header)
...@@ -138,7 +153,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, ...@@ -138,7 +153,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
memset(unit_data + unit_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); memset(unit_data + unit_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type, err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type,
unit_data, unit_size); unit_data, unit_size, NULL);
if (err < 0) { if (err < 0) {
av_freep(&unit_data); av_freep(&unit_data);
return err; return err;
...@@ -168,25 +183,25 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, ...@@ -168,25 +183,25 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
MPEG2RawSlice *slice; MPEG2RawSlice *slice;
int pos, len; int pos, len;
slice = av_mallocz(sizeof(*slice)); err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
if (!slice) &cbs_mpeg2_free_slice);
return AVERROR(ENOMEM); if (err < 0)
return err;
slice = unit->content;
err = cbs_mpeg2_read_slice_header(ctx, &bc, &slice->header); err = cbs_mpeg2_read_slice_header(ctx, &bc, &slice->header);
if (err < 0) { if (err < 0)
av_free(slice);
return err; return err;
}
pos = bitstream_tell(&bc); pos = bitstream_tell(&bc);
len = unit->data_size; len = unit->data_size;
slice->data_size = len - pos / 8; slice->data_size = len - pos / 8;
slice->data = av_malloc(slice->data_size + slice->data_ref = av_buffer_alloc(slice->data_size +
AV_INPUT_BUFFER_PADDING_SIZE); AV_INPUT_BUFFER_PADDING_SIZE);
if (!slice->data) { if (!slice->data_ref)
av_free(slice);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} slice->data = slice->data_ref->data;
memcpy(slice->data, memcpy(slice->data,
unit->data + pos / 8, slice->data_size); unit->data + pos / 8, slice->data_size);
...@@ -194,30 +209,29 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, ...@@ -194,30 +209,29 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
AV_INPUT_BUFFER_PADDING_SIZE); AV_INPUT_BUFFER_PADDING_SIZE);
slice->data_bit_start = pos % 8; slice->data_bit_start = pos % 8;
unit->content = slice;
} else { } else {
switch (unit->type) { switch (unit->type) {
#define START(start_code, type, func) \ #define START(start_code, type, read_func, free_func) \
case start_code: \ case start_code: \
{ \ { \
type *header; \ type *header; \
header = av_mallocz(sizeof(*header)); \ err = ff_cbs_alloc_unit_content(ctx, unit, \
if (!header) \ sizeof(*header), free_func); \
return AVERROR(ENOMEM); \ if (err < 0) \
err = cbs_mpeg2_read_ ## func(ctx, &bc, header); \ return err; \
if (err < 0) { \ header = unit->content; \
av_free(header); \ err = cbs_mpeg2_read_ ## read_func(ctx, &bc, header); \
if (err < 0) \
return err; \ return err; \
} \
unit->content = header; \
} \ } \
break; break;
START(0x00, MPEG2RawPictureHeader, picture_header); START(0x00, MPEG2RawPictureHeader, picture_header, NULL);
START(0xb2, MPEG2RawUserData, user_data); START(0xb2, MPEG2RawUserData, user_data,
START(0xb3, MPEG2RawSequenceHeader, sequence_header); &cbs_mpeg2_free_user_data);
START(0xb5, MPEG2RawExtensionData, extension_data); START(0xb3, MPEG2RawSequenceHeader, sequence_header, NULL);
START(0xb8, MPEG2RawGroupOfPicturesHeader, group_of_pictures_header); START(0xb5, MPEG2RawExtensionData, extension_data, NULL);
START(0xb8, MPEG2RawGroupOfPicturesHeader,
group_of_pictures_header, NULL);
#undef START #undef START
default: default:
av_log(ctx->log_ctx, AV_LOG_ERROR, "Unknown start code %02"PRIx32".\n", av_log(ctx->log_ctx, AV_LOG_ERROR, "Unknown start code %02"PRIx32".\n",
...@@ -335,7 +349,7 @@ static int cbs_mpeg2_write_unit(CodedBitstreamContext *ctx, ...@@ -335,7 +349,7 @@ static int cbs_mpeg2_write_unit(CodedBitstreamContext *ctx,
unit->data_size = (put_bits_count(&pbc) + 7) / 8; unit->data_size = (put_bits_count(&pbc) + 7) / 8;
flush_put_bits(&pbc); flush_put_bits(&pbc);
err = av_reallocp(&unit->data, unit->data_size); err = ff_cbs_alloc_unit_data(ctx, unit, unit->data_size);
if (err < 0) if (err < 0)
return err; return err;
...@@ -355,9 +369,10 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx, ...@@ -355,9 +369,10 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx,
for (i = 0; i < frag->nb_units; i++) for (i = 0; i < frag->nb_units; i++)
size += 3 + frag->units[i].data_size; size += 3 + frag->units[i].data_size;
data = av_malloc(size); frag->data_ref = av_buffer_alloc(size);
if (!data) if (!frag->data_ref)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
data = frag->data_ref->data;
dp = 0; dp = 0;
for (i = 0; i < frag->nb_units; i++) { for (i = 0; i < frag->nb_units; i++) {
...@@ -379,19 +394,6 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx, ...@@ -379,19 +394,6 @@ static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx,
return 0; return 0;
} }
static void cbs_mpeg2_free_unit(CodedBitstreamUnit *unit)
{
if (MPEG2_START_IS_SLICE(unit->type)) {
MPEG2RawSlice *slice = unit->content;
av_freep(&slice->data);
av_freep(&slice->header.extra_information);
} else if (unit->type == MPEG2_START_USER_DATA) {
MPEG2RawUserData *user = unit->content;
av_freep(&user->user_data);
}
av_freep(&unit->content);
}
static void cbs_mpeg2_close(CodedBitstreamContext *ctx) static void cbs_mpeg2_close(CodedBitstreamContext *ctx)
{ {
CodedBitstreamMPEG2Context *priv = ctx->priv_data; CodedBitstreamMPEG2Context *priv = ctx->priv_data;
...@@ -409,6 +411,5 @@ const CodedBitstreamType ff_cbs_type_mpeg2 = { ...@@ -409,6 +411,5 @@ const CodedBitstreamType ff_cbs_type_mpeg2 = {
.write_unit = &cbs_mpeg2_write_unit, .write_unit = &cbs_mpeg2_write_unit,
.assemble_fragment = &cbs_mpeg2_assemble_fragment, .assemble_fragment = &cbs_mpeg2_assemble_fragment,
.free_unit = &cbs_mpeg2_free_unit,
.close = &cbs_mpeg2_close, .close = &cbs_mpeg2_close,
}; };
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "libavutil/buffer.h"
enum { enum {
MPEG2_START_PICTURE = 0x00, MPEG2_START_PICTURE = 0x00,
...@@ -76,6 +78,7 @@ typedef struct MPEG2RawUserData { ...@@ -76,6 +78,7 @@ typedef struct MPEG2RawUserData {
uint8_t *user_data; uint8_t *user_data;
size_t user_data_length; size_t user_data_length;
AVBufferRef *user_data_ref;
} MPEG2RawUserData; } MPEG2RawUserData;
typedef struct MPEG2RawSequenceExtension { typedef struct MPEG2RawSequenceExtension {
...@@ -195,6 +198,7 @@ typedef struct MPEG2RawSliceHeader { ...@@ -195,6 +198,7 @@ typedef struct MPEG2RawSliceHeader {
size_t extra_information_length; size_t extra_information_length;
uint8_t *extra_information; uint8_t *extra_information;
AVBufferRef *extra_information_ref;
} MPEG2RawSliceHeader; } MPEG2RawSliceHeader;
typedef struct MPEG2RawSlice { typedef struct MPEG2RawSlice {
...@@ -203,6 +207,7 @@ typedef struct MPEG2RawSlice { ...@@ -203,6 +207,7 @@ typedef struct MPEG2RawSlice {
uint8_t *data; uint8_t *data;
size_t data_size; size_t data_size;
int data_bit_start; int data_bit_start;
AVBufferRef *data_ref;
} MPEG2RawSlice; } MPEG2RawSlice;
......
...@@ -71,9 +71,10 @@ static int FUNC(user_data)(CodedBitstreamContext *ctx, RWContext *rw, ...@@ -71,9 +71,10 @@ static int FUNC(user_data)(CodedBitstreamContext *ctx, RWContext *rw,
av_assert0(k % 8 == 0); av_assert0(k % 8 == 0);
current->user_data_length = k /= 8; current->user_data_length = k /= 8;
if (k > 0) { if (k > 0) {
current->user_data = av_malloc(k); current->user_data_ref = av_buffer_alloc(k);
if (!current->user_data) if (!current->user_data_ref)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
current->user_data = current->user_data_ref->data;
} }
#endif #endif
......
...@@ -270,7 +270,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out) ...@@ -270,7 +270,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
aud->primary_pic_type = j; aud->primary_pic_type = j;
err = ff_cbs_insert_unit_content(ctx->cbc, au, err = ff_cbs_insert_unit_content(ctx->cbc, au,
0, H264_NAL_AUD, aud); 0, H264_NAL_AUD, aud, NULL);
if (err < 0) { if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
goto fail; goto fail;
...@@ -314,8 +314,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out) ...@@ -314,8 +314,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *out)
sei->nal_unit_header.nal_unit_type = H264_NAL_SEI; sei->nal_unit_header.nal_unit_type = H264_NAL_SEI;
err = ff_cbs_insert_unit_content(ctx->cbc, au, err = ff_cbs_insert_unit_content(ctx->cbc, au, sei_pos,
sei_pos, H264_NAL_SEI, sei); H264_NAL_SEI, sei, NULL);
if (err < 0) { if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert SEI.\n"); av_log(bsf, AV_LOG_ERROR, "Failed to insert SEI.\n");
goto fail; goto fail;
......
...@@ -289,7 +289,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *out) ...@@ -289,7 +289,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *out)
aud->pic_type = pic_type; aud->pic_type = pic_type;
err = ff_cbs_insert_unit_content(ctx->cbc, au, err = ff_cbs_insert_unit_content(ctx->cbc, au,
0, HEVC_NAL_AUD, aud); 0, HEVC_NAL_AUD, aud, NULL);
if (err) { if (err) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
goto fail; goto fail;
......
...@@ -167,7 +167,8 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, ...@@ -167,7 +167,8 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1, err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1,
MPEG2_START_EXTENSION, MPEG2_START_EXTENSION,
&ctx->sequence_display_extension); &ctx->sequence_display_extension,
NULL);
if (err < 0) { if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to insert new sequence " av_log(bsf, AV_LOG_ERROR, "Failed to insert new sequence "
"display extension.\n"); "display extension.\n");
......
...@@ -133,7 +133,7 @@ static int vaapi_encode_h264_add_nal(AVCodecContext *avctx, ...@@ -133,7 +133,7 @@ static int vaapi_encode_h264_add_nal(AVCodecContext *avctx,
int err; int err;
err = ff_cbs_insert_unit_content(priv->cbc, au, -1, err = ff_cbs_insert_unit_content(priv->cbc, au, -1,
header->nal_unit_type, nal_unit); header->nal_unit_type, nal_unit, NULL);
if (err < 0) { if (err < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: "
"type = %d.\n", header->nal_unit_type); "type = %d.\n", header->nal_unit_type);
......
...@@ -105,7 +105,7 @@ static int vaapi_encode_h265_add_nal(AVCodecContext *avctx, ...@@ -105,7 +105,7 @@ static int vaapi_encode_h265_add_nal(AVCodecContext *avctx,
int err; int err;
err = ff_cbs_insert_unit_content(priv->cbc, au, -1, err = ff_cbs_insert_unit_content(priv->cbc, au, -1,
header->nal_unit_type, nal_unit); header->nal_unit_type, nal_unit, NULL);
if (err < 0) { if (err < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: "
"type = %d.\n", header->nal_unit_type); "type = %d.\n", header->nal_unit_type);
......
...@@ -92,7 +92,7 @@ static int vaapi_encode_mpeg2_add_header(AVCodecContext *avctx, ...@@ -92,7 +92,7 @@ static int vaapi_encode_mpeg2_add_header(AVCodecContext *avctx,
VAAPIEncodeMPEG2Context *priv = ctx->priv_data; VAAPIEncodeMPEG2Context *priv = ctx->priv_data;
int err; int err;
err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, type, header); err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, type, header, NULL);
if (err < 0) { if (err < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to add header: " av_log(avctx, AV_LOG_ERROR, "Failed to add header: "
"type = %d.\n", type); "type = %d.\n", type);
......
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