X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fav1.c;h=0cbffb1fd8bea5c1a1a5efebe8dada34ae9b8647;hb=d16974c3dd3a05900aa080ea0729284aea358d10;hp=132f4e987bdcac668f4abb7eccfd01206d807628;hpb=a31f68fb449eaf6f030ce5633435663f154bb34d;p=ffmpeg diff --git a/libavformat/av1.c b/libavformat/av1.c index 132f4e987bd..0cbffb1fd8b 100644 --- a/libavformat/av1.c +++ b/libavformat/av1.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavcodec/av1.h" #include "libavcodec/av1_parse.h" @@ -28,13 +29,20 @@ #include "avio.h" #include "avio_internal.h" -int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size) +static int av1_filter_obus(AVIOContext *pb, const uint8_t *buf, + int size, int *offset) { - const uint8_t *end = buf + size; + const uint8_t *start = buf, *end = buf + size; int64_t obu_size; - int start_pos, type, temporal_id, spatial_id; - - size = 0; + int off, start_pos, type, temporal_id, spatial_id; + enum { + START_NOT_FOUND, + START_FOUND, + END_FOUND, + OFFSET_IMPOSSIBLE, + } state = START_NOT_FOUND; + + off = size = 0; while (buf < end) { int len = parse_obu_header(buf, end - buf, &obu_size, &start_pos, &type, &temporal_id, &spatial_id); @@ -46,37 +54,70 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size) case AV1_OBU_REDUNDANT_FRAME_HEADER: case AV1_OBU_TILE_LIST: case AV1_OBU_PADDING: + if (state == START_FOUND) + state = END_FOUND; break; default: - avio_write(pb, buf, len); + if (state == START_NOT_FOUND) { + off = buf - start; + state = START_FOUND; + } else if (state == END_FOUND) { + state = OFFSET_IMPOSSIBLE; + } + if (pb) + avio_write(pb, buf, len); size += len; break; } buf += len; } + if (offset) + *offset = state != OFFSET_IMPOSSIBLE ? off : -1; + return size; } -int ff_av1_filter_obus_buf(const uint8_t *buf, uint8_t **out, int *size) +int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size) { - AVIOContext *pb; - int ret; + return av1_filter_obus(pb, buf, size, NULL); +} - ret = avio_open_dyn_buf(&pb); - if (ret < 0) - return ret; +int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, + int *size, int *offset) +{ + AVIOContext pb; + uint8_t *buf; + int len, off, ret; - ret = ff_av1_filter_obus(pb, buf, *size); + len = ret = av1_filter_obus(NULL, in, *size, &off); if (ret < 0) { - ffio_free_dyn_buf(&pb); return ret; } + if (off >= 0) { + *out = (uint8_t *)in; + *size = len; + *offset = off; - av_freep(out); - *size = avio_close_dyn_buf(pb, out); + return 0; + } - return ret; + buf = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE); + if (!buf) + return AVERROR(ENOMEM); + + ffio_init_context(&pb, buf, len, 1, NULL, NULL, NULL, NULL); + + ret = av1_filter_obus(&pb, in, *size, NULL); + av_assert1(ret == len); + + memset(buf + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); + + *out = buf; + *size = len; + *offset = 0; + + return 0; } static inline void uvlc(GetBitContext *gb) @@ -257,7 +298,7 @@ static int parse_sequence_header(AV1SequenceParameters *seq_params, const uint8_ if (!reduced_still_picture_header) { int enable_order_hint, seq_force_screen_content_tools; - skip_bits(&gb, 4); // enable_intraintra_compound (1), enable_masked_compound (1) + skip_bits(&gb, 4); // enable_interintra_compound (1), enable_masked_compound (1) // enable_warped_motion (1), enable_dual_filter (1) enable_order_hint = get_bits1(&gb); @@ -322,11 +363,11 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) { - AVIOContext *seq_pb = NULL, *meta_pb = NULL; + AVIOContext *meta_pb; AV1SequenceParameters seq_params; PutBitContext pbc; - uint8_t header[4]; - uint8_t *seq, *meta; + uint8_t header[4], *meta; + const uint8_t *seq; int64_t obu_size; int start_pos, type, temporal_id, spatial_id; int ret, nb_seq = 0, seq_size, meta_size; @@ -334,12 +375,9 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) if (size <= 0) return AVERROR_INVALIDDATA; - ret = avio_open_dyn_buf(&seq_pb); - if (ret < 0) - return ret; ret = avio_open_dyn_buf(&meta_pb); if (ret < 0) - goto fail; + return ret; while (size > 0) { int len = parse_obu_header(buf, size, &obu_size, &start_pos, @@ -360,7 +398,8 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) if (ret < 0) goto fail; - avio_write(seq_pb, buf, len); + seq = buf; + seq_size = len; break; case AV1_OBU_METADATA: if (!obu_size) { @@ -376,8 +415,7 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) buf += len; } - seq_size = avio_get_dyn_buf(seq_pb, &seq); - if (!seq_size) { + if (!nb_seq) { ret = AVERROR_INVALIDDATA; goto fail; } @@ -406,7 +444,6 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) avio_write(pb, meta, meta_size); fail: - ffio_free_dyn_buf(&seq_pb); ffio_free_dyn_buf(&meta_pb); return ret;