X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fcbs_vp9.c;h=e0b8c02ac2fce335643ad4c3480d9cf5cd0575a0;hb=3749eede66c3774799766b1f246afae8a6ffc9bb;hp=7498be4b73b4066360d2fef898102a132a262199;hpb=022fa7a24ea8f5000e7b6a50e57cc752f417da47;p=ffmpeg diff --git a/libavcodec/cbs_vp9.c b/libavcodec/cbs_vp9.c index 7498be4b73b..e0b8c02ac2f 100644 --- a/libavcodec/cbs_vp9.c +++ b/libavcodec/cbs_vp9.c @@ -253,28 +253,27 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL) #define f(width, name) \ - xf(width, name, current->name, 0) + xf(width, name, current->name, 0, ) #define s(width, name) \ - xs(width, name, current->name, 0) + xs(width, name, current->name, 0, ) #define fs(width, name, subs, ...) \ xf(width, name, current->name, subs, __VA_ARGS__) #define ss(width, name, subs, ...) \ xs(width, name, current->name, subs, __VA_ARGS__) - #define READ #define READWRITE read #define RWContext GetBitContext #define xf(width, name, var, subs, ...) do { \ - uint32_t value = 0; \ + uint32_t value; \ CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ SUBSCRIPTS(subs, __VA_ARGS__), \ &value, 0, (1 << width) - 1)); \ var = value; \ } while (0) #define xs(width, name, var, subs, ...) do { \ - int32_t value = 0; \ + int32_t value; \ CHECK(cbs_vp9_read_s(ctx, rw, width, #name, \ SUBSCRIPTS(subs, __VA_ARGS__), &value)); \ var = value; \ @@ -282,7 +281,7 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #define increment(name, min, max) do { \ - uint32_t value = 0; \ + uint32_t value; \ CHECK(cbs_vp9_read_increment(ctx, rw, min, max, #name, &value)); \ current->name = value; \ } while (0) @@ -295,9 +294,9 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #define delta_q(name) do { \ uint8_t delta_coded; \ int8_t delta_q; \ - xf(1, name.delta_coded, delta_coded, 0); \ + xf(1, name.delta_coded, delta_coded, 0, ); \ if (delta_coded) \ - xs(4, name.delta_q, delta_q, 0); \ + xs(4, name.delta_q, delta_q, 0, ); \ else \ delta_q = 0; \ current->name = delta_q; \ @@ -305,7 +304,7 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #define prob(name, subs, ...) do { \ uint8_t prob_coded; \ - int8_t prob; \ + uint8_t prob; \ xf(1, name.prob_coded, prob_coded, subs, __VA_ARGS__); \ if (prob_coded) \ xf(8, name.prob, prob, subs, __VA_ARGS__); \ @@ -314,6 +313,12 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, current->name = prob; \ } while (0) +#define fixed(width, name, value) do { \ + av_unused uint32_t fixed_value; \ + CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ + 0, &fixed_value, value, value)); \ + } while (0) + #define infer(name, value) do { \ current->name = value; \ } while (0) @@ -331,6 +336,7 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #undef fle #undef delta_q #undef prob +#undef fixed #undef infer #undef byte_alignment @@ -359,9 +365,9 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, } while (0) #define delta_q(name) do { \ - xf(1, name.delta_coded, !!current->name, 0); \ + xf(1, name.delta_coded, !!current->name, 0, ); \ if (current->name) \ - xs(4, name.delta_q, current->name, 0); \ + xs(4, name.delta_q, current->name, 0, ); \ } while (0) #define prob(name, subs, ...) do { \ @@ -370,6 +376,11 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, xf(8, name.prob, current->name, subs, __VA_ARGS__); \ } while (0) +#define fixed(width, name, value) do { \ + CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ + 0, value, value, value)); \ + } while (0) + #define infer(name, value) do { \ if (current->name != (value)) { \ av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \ @@ -383,7 +394,7 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #include "cbs_vp9_syntax_template.c" -#undef READ +#undef WRITE #undef READWRITE #undef RWContext #undef xf @@ -392,6 +403,7 @@ static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, #undef fle #undef delta_q #undef prob +#undef fixed #undef infer #undef byte_alignment @@ -403,6 +415,9 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, uint8_t superframe_header; int err; + if (frag->data_size == 0) + return AVERROR_INVALIDDATA; + // Last byte in the packet. superframe_header = frag->data[frag->data_size - 1]; @@ -415,6 +430,9 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, index_size = 2 + (((superframe_header & 0x18) >> 3) + 1) * ((superframe_header & 0x07) + 1); + if (index_size > frag->data_size) + return AVERROR_INVALIDDATA; + err = init_get_bits(&gbc, frag->data + frag->data_size - index_size, 8 * index_size); if (err < 0) @@ -433,7 +451,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return AVERROR_INVALIDDATA; } - err = ff_cbs_insert_unit_data(ctx, frag, -1, 0, + err = ff_cbs_insert_unit_data(frag, -1, 0, frag->data + pos, sfi.frame_sizes[i], frag->data_ref); @@ -444,14 +462,14 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, } if (pos + index_size != frag->data_size) { av_log(ctx->log_ctx, AV_LOG_WARNING, "Extra padding at " - "end of superframe: %zu bytes.\n", + "end of superframe: %"SIZE_SPECIFIER" bytes.\n", frag->data_size - (pos + index_size)); } return 0; } else { - err = ff_cbs_insert_unit_data(ctx, frag, -1, 0, + err = ff_cbs_insert_unit_data(frag, -1, 0, frag->data, frag->data_size, frag->data_ref); if (err < 0) @@ -461,13 +479,6 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return 0; } -static void cbs_vp9_free_frame(void *unit, uint8_t *content) -{ - VP9RawFrame *frame = (VP9RawFrame*)content; - av_buffer_unref(&frame->data_ref); - av_freep(&frame); -} - static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) { @@ -479,8 +490,7 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*frame), - &cbs_vp9_free_frame); + err = ff_cbs_alloc_unit_content2(ctx, unit); if (err < 0) return err; frame = unit->content; @@ -509,62 +519,28 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, } static int cbs_vp9_write_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) + CodedBitstreamUnit *unit, + PutBitContext *pbc) { - CodedBitstreamVP9Context *priv = ctx->priv_data; VP9RawFrame *frame = unit->content; - PutBitContext pbc; int err; - if (!priv->write_buffer) { - // Initial write buffer size is 1MB. - priv->write_buffer_size = 1024 * 1024; - - reallocate_and_try_again: - err = av_reallocp(&priv->write_buffer, priv->write_buffer_size); - if (err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a " - "sufficiently large write buffer (last attempt " - "%zu bytes).\n", priv->write_buffer_size); - return err; - } - } - - init_put_bits(&pbc, priv->write_buffer, priv->write_buffer_size); - - err = cbs_vp9_write_frame(ctx, &pbc, frame); - if (err == AVERROR(ENOSPC)) { - priv->write_buffer_size *= 2; - goto reallocate_and_try_again; - } + err = cbs_vp9_write_frame(ctx, pbc, frame); if (err < 0) return err; // Frame must be byte-aligned. - av_assert0(put_bits_count(&pbc) % 8 == 0); - - unit->data_size = put_bits_count(&pbc) / 8; - unit->data_bit_padding = 0; - flush_put_bits(&pbc); + av_assert0(put_bits_count(pbc) % 8 == 0); if (frame->data) { - if (unit->data_size + frame->data_size > - priv->write_buffer_size) { - priv->write_buffer_size *= 2; - goto reallocate_and_try_again; - } + if (frame->data_size > put_bits_left(pbc) / 8) + return AVERROR(ENOSPC); - memcpy(priv->write_buffer + unit->data_size, - frame->data, frame->data_size); - unit->data_size += frame->data_size; + flush_put_bits(pbc); + memcpy(put_bits_ptr(pbc), frame->data, frame->data_size); + skip_put_bytes(pbc, frame->data_size); } - err = ff_cbs_alloc_unit_data(ctx, unit, unit->data_size); - if (err < 0) - return err; - - memcpy(unit->data, priv->write_buffer, unit->data_size); - return 0; } @@ -658,22 +634,30 @@ static int cbs_vp9_assemble_fragment(CodedBitstreamContext *ctx, return 0; } -static void cbs_vp9_close(CodedBitstreamContext *ctx) +static void cbs_vp9_flush(CodedBitstreamContext *ctx) { - CodedBitstreamVP9Context *priv = ctx->priv_data; + CodedBitstreamVP9Context *vp9 = ctx->priv_data; - av_freep(&priv->write_buffer); + memset(vp9->ref, 0, sizeof(vp9->ref)); } +static const CodedBitstreamUnitTypeDescriptor cbs_vp9_unit_types[] = { + CBS_UNIT_TYPE_INTERNAL_REF(0, VP9RawFrame, data), + CBS_UNIT_TYPE_END_OF_LIST +}; + const CodedBitstreamType ff_cbs_type_vp9 = { .codec_id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(CodedBitstreamVP9Context), + .unit_types = cbs_vp9_unit_types, + .split_fragment = &cbs_vp9_split_fragment, .read_unit = &cbs_vp9_read_unit, .write_unit = &cbs_vp9_write_unit, - .assemble_fragment = &cbs_vp9_assemble_fragment, - .close = &cbs_vp9_close, + .flush = &cbs_vp9_flush, + + .assemble_fragment = &cbs_vp9_assemble_fragment, };