[FFmpeg-devel] [PATCH 2/3] cbs_av1: Support redundant frame headers
James Almer
jamrial at gmail.com
Mon Nov 5 02:55:46 EET 2018
On 11/4/2018 9:10 PM, Mark Thompson wrote:
> ---
> Includes support for using them when the normal frame header as been lost (try "-bsf:v filter_units=remove_types=3").
>
>
> libavcodec/cbs_av1.c | 8 +++-
> libavcodec/cbs_av1.h | 2 +
> libavcodec/cbs_av1_syntax_template.c | 64 +++++++++++++++++++++++++---
> 3 files changed, 66 insertions(+), 8 deletions(-)
>
> diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
> index 1c49d90f51..b61b757f41 100644
> --- a/libavcodec/cbs_av1.c
> +++ b/libavcodec/cbs_av1.c
> @@ -996,7 +996,9 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
> case AV1_OBU_REDUNDANT_FRAME_HEADER:
> {
> err = cbs_av1_read_frame_header_obu(ctx, &gbc,
> - &obu->obu.frame_header);
> + &obu->obu.frame_header,
> + obu->header.obu_type ==
> + AV1_OBU_REDUNDANT_FRAME_HEADER);
> if (err < 0)
> return err;
> }
> @@ -1124,7 +1126,9 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
> case AV1_OBU_REDUNDANT_FRAME_HEADER:
> {
> err = cbs_av1_write_frame_header_obu(ctx, pbc,
> - &obu->obu.frame_header);
> + &obu->obu.frame_header,
> + obu->header.obu_type ==
> + AV1_OBU_REDUNDANT_FRAME_HEADER);
> if (err < 0)
> return err;
> }
> diff --git a/libavcodec/cbs_av1.h b/libavcodec/cbs_av1.h
> index b66a09c389..af9e88df71 100644
> --- a/libavcodec/cbs_av1.h
> +++ b/libavcodec/cbs_av1.h
> @@ -400,6 +400,8 @@ typedef struct CodedBitstreamAV1Context {
> AVBufferRef *sequence_header_ref;
>
> int seen_frame_header;
> + uint8_t *frame_header;
> + size_t frame_header_size;
>
> int temporal_id;
> int spatial_id;
> diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c
> index e146bbf8bb..5649af841a 100644
> --- a/libavcodec/cbs_av1_syntax_template.c
> +++ b/libavcodec/cbs_av1_syntax_template.c
> @@ -1463,24 +1463,76 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw,
> }
>
> static int FUNC(frame_header_obu)(CodedBitstreamContext *ctx, RWContext *rw,
> - AV1RawFrameHeader *current)
> + AV1RawFrameHeader *current, int redundant)
> {
> CodedBitstreamAV1Context *priv = ctx->priv_data;
> - int err;
> -
> - HEADER("Frame Header");
> + int start_pos, fh_bits, fh_bytes, err;
> + const uint8_t *fh_start;
>
> if (priv->seen_frame_header) {
> - // Nothing to do.
> + if (!redundant) {
> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid repeated "
> + "frame header OBU.\n");
> + return AVERROR_INVALIDDATA;
> + } else {
> + GetBitContext fh;
> + size_t k;
> + int b;
> +
> + HEADER("Redundant Frame Header");
> +
> + init_get_bits(&fh, priv->frame_header,
> + priv->frame_header_size);
> + for (k = 0; k < priv->frame_header_size; k++) {
> + b = get_bits1(&fh);
> + xf(1, frame_header_copy[k], b, b, b, 1, k);
This is making a lot of noise in the trace output for no real gain,
since it prints every single bit as its own line. Can you silence it?
> + }
> + }
> } else {
> + if (redundant)
> + HEADER("Redundant Frame Header (used as Frame Header)");
> + else
> + HEADER("Frame Header");
> +
> priv->seen_frame_header = 1;
>
> +#ifdef READ
> + start_pos = get_bits_count(rw);
> +#else
> + start_pos = put_bits_count(rw);
> +#endif
> +
> CHECK(FUNC(uncompressed_header)(ctx, rw, current));
>
> if (current->show_existing_frame) {
> priv->seen_frame_header = 0;
> } else {
> priv->seen_frame_header = 1;
> +
> + av_freep(&priv->frame_header);
> +
> +#ifdef READ
> + fh_bits = get_bits_count(rw) - start_pos;
> + fh_start = rw->buffer + start_pos / 8;
> +#else
> + // Need to flush the bitwriter so that we can copy its output,
> + // but use a copy so we don't affect the caller's structure.
> + {
> + PutBitContext tmp = *rw;
> + flush_put_bits(&tmp);
> + }
> +
> + fh_bits = put_bits_count(rw) - start_pos;
> + fh_start = rw->buf + start_pos / 8;
> +#endif
> + fh_bytes = (fh_bits + 7) / 8;
> +
> + priv->frame_header_size = fh_bits;
> + priv->frame_header =
> + av_mallocz(fh_bytes + AV_INPUT_BUFFER_PADDING_SIZE);
> + if (!priv->frame_header)
> + return AVERROR(ENOMEM);
> + memcpy(priv->frame_header, fh_start, fh_bytes);
No way to use AVBufferRef for this?
I think i may have asked this before...
> }
> }
>
> @@ -1528,7 +1580,7 @@ static int FUNC(frame_obu)(CodedBitstreamContext *ctx, RWContext *rw,
> {
> int err;
>
> - CHECK(FUNC(frame_header_obu)(ctx, rw, ¤t->header));
> + CHECK(FUNC(frame_header_obu)(ctx, rw, ¤t->header, 0));
>
> CHECK(FUNC(byte_alignment)(ctx, rw));
Seems to work, so LGTM if the above can't be changed. Thanks!
More information about the ffmpeg-devel
mailing list