Discussion:
[libav-devel] [PATCH 2/7] avcodec/h264_mp4toannexb_bsf: implement a AVBSFContext.flush() callback
James Almer
2018-07-27 17:59:52 UTC
Permalink
Signed-off-by: James Almer <***@gmail.com>
---
libavcodec/h264_mp4toannexb_bsf.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index c65aaeb98..c45ecd8ce 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -232,6 +232,13 @@ fail:
return ret;
}

+static void h264_mp4toannexb_flush(AVBSFContext *ctx)
+{
+ H264BSFContext *s = ctx->priv_data;
+
+ s->first_idr = s->extradata_parsed;
+}
+
static const enum AVCodecID codec_ids[] = {
AV_CODEC_ID_H264, AV_CODEC_ID_NONE,
};
@@ -241,5 +248,6 @@ const AVBitStreamFilter ff_h264_mp4toannexb_bsf = {
.priv_data_size = sizeof(H264BSFContext),
.init = h264_mp4toannexb_init,
.filter = h264_mp4toannexb_filter,
+ .flush = h264_mp4toannexb_flush,
.codec_ids = codec_ids,
};
--
2.18.0
James Almer
2018-07-27 17:59:53 UTC
Permalink
Signed-off-by: James Almer <***@gmail.com>
---
libavcodec/vp9_superframe_split_bsf.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/libavcodec/vp9_superframe_split_bsf.c b/libavcodec/vp9_superframe_split_bsf.c
index 4e635a307..4e6e7ff08 100644
--- a/libavcodec/vp9_superframe_split_bsf.c
+++ b/libavcodec/vp9_superframe_split_bsf.c
@@ -131,6 +131,14 @@ fail:
return ret;
}

+static void vp9_superframe_split_flush(AVBSFContext *ctx)
+{
+ VP9SFSplitContext *s = ctx->priv_data;
+
+ av_packet_free(&s->buffer_pkt);
+ memset(s, 0, sizeof(*s));
+}
+
static void vp9_superframe_split_uninit(AVBSFContext *ctx)
{
VP9SFSplitContext *s = ctx->priv_data;
@@ -142,5 +150,6 @@ const AVBitStreamFilter ff_vp9_superframe_split_bsf = {
.priv_data_size = sizeof(VP9SFSplitContext),
.close = vp9_superframe_split_uninit,
.filter = vp9_superframe_split_filter,
+ .flush = vp9_superframe_split_flush,
.codec_ids = (const enum AVCodecID []){ AV_CODEC_ID_VP9, AV_CODEC_ID_NONE },
};
--
2.18.0
James Almer
2018-07-27 17:59:54 UTC
Permalink
Signed-off-by: James Almer <***@gmail.com>
---
libavcodec/vp9_superframe_bsf.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/libavcodec/vp9_superframe_bsf.c b/libavcodec/vp9_superframe_bsf.c
index ad66cb599..04b158fa1 100644
--- a/libavcodec/vp9_superframe_bsf.c
+++ b/libavcodec/vp9_superframe_bsf.c
@@ -191,6 +191,17 @@ static int vp9_superframe_init(AVBSFContext *ctx)
return 0;
}

+static void vp9_superframe_flush(AVBSFContext *ctx)
+{
+ VP9BSFContext *s = ctx->priv_data;
+ int n;
+
+ // unref cached data
+ for (n = 0; n < s->n_cache; n++)
+ av_packet_unref(s->cache[n]);
+ s->n_cache = 0;
+}
+
static void vp9_superframe_close(AVBSFContext *ctx)
{
VP9BSFContext *s = ctx->priv_data;
@@ -210,6 +221,7 @@ const AVBitStreamFilter ff_vp9_superframe_bsf = {
.priv_data_size = sizeof(VP9BSFContext),
.filter = vp9_superframe_filter,
.init = vp9_superframe_init,
+ .flush = vp9_superframe_flush,
.close = vp9_superframe_close,
.codec_ids = codec_ids,
};
--
2.18.0
James Almer
2018-07-27 17:59:55 UTC
Permalink
Signed-off-by: James Almer <***@gmail.com>
---
libavcodec/h264_redundant_pps_bsf.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/libavcodec/h264_redundant_pps_bsf.c b/libavcodec/h264_redundant_pps_bsf.c
index 24b7b6730..d806427da 100644
--- a/libavcodec/h264_redundant_pps_bsf.c
+++ b/libavcodec/h264_redundant_pps_bsf.c
@@ -35,6 +35,7 @@ typedef struct H264RedundantPPSContext {

int global_pic_init_qp;
int current_pic_init_qp;
+ int extradata_pic_init_qp;
} H264RedundantPPSContext;


@@ -145,6 +146,7 @@ static int h264_redundant_pps_init(AVBSFContext *bsf)
h264_redundant_pps_fixup_pps(ctx, au->units[i].content);
}

+ ctx->extradata_pic_init_qp = ctx->current_pic_init_qp;
err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
@@ -157,6 +159,12 @@ static int h264_redundant_pps_init(AVBSFContext *bsf)
return 0;
}

+static void h264_redundant_pps_flush(AVBSFContext *bsf)
+{
+ H264RedundantPPSContext *ctx = bsf->priv_data;
+ ctx->current_pic_init_qp = ctx->extradata_pic_init_qp;
+}
+
static void h264_redundant_pps_close(AVBSFContext *bsf)
{
H264RedundantPPSContext *ctx = bsf->priv_data;
@@ -172,6 +180,7 @@ const AVBitStreamFilter ff_h264_redundant_pps_bsf = {
.name = "h264_redundant_pps",
.priv_data_size = sizeof(H264RedundantPPSContext),
.init = &h264_redundant_pps_init,
+ .flush = &h264_redundant_pps_flush,
.close = &h264_redundant_pps_close,
.filter = &h264_redundant_pps_filter,
.codec_ids = h264_redundant_pps_codec_ids,
--
2.18.0
James Almer
2018-07-27 17:59:56 UTC
Permalink
Initialize the bsfs once when opening the codec and uninitialize them once when
closing it, instead of at every codec flush/seek.

Signed-off-by: James Almer <***@gmail.com>
---
I think i didn't miss any bsf with internal state that needs a flush()
callback, but an extra pair of eyes (or more) to make sure would come in handy.

In any case, the only bsfs where this matters are those used during decoding,
which essentially means those autoinserted by decoders given that the cli
doesn't allow -bsf as an input option. But you can't know what an API user may
do, so better get them all right.

libavcodec/decode.c | 20 ++++++++++----------
libavcodec/decode.h | 2 ++
libavcodec/utils.c | 5 +++++
3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 8635aec94..2dab7f2a7 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -156,7 +156,7 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
return 0;
}

-static int bsfs_init(AVCodecContext *avctx)
+int ff_decode_bsfs_init(AVCodecContext *avctx)
{
AVCodecInternal *avci = avctx->internal;
DecodeFilterContext *s = &avci->filter;
@@ -449,10 +449,6 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke
if (avctx->internal->draining)
return AVERROR_EOF;

- ret = bsfs_init(avctx);
- if (ret < 0)
- return ret;
-
av_packet_unref(avci->buffer_pkt);
if (avpkt && (avpkt->data || avpkt->side_data_elems)) {
ret = av_packet_ref(avci->buffer_pkt, avpkt);
@@ -511,10 +507,6 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
return AVERROR(EINVAL);

- ret = bsfs_init(avctx);
- if (ret < 0)
- return ret;
-
if (avci->buffer_frame->buf[0]) {
av_frame_move_ref(frame, avci->buffer_frame);
} else {
@@ -1394,6 +1386,14 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
return 0;
}

+static void bsfs_flush(AVCodecContext *avctx)
+{
+ DecodeFilterContext *s = &avctx->internal->filter;
+
+ for (int i = 0; i < s->nb_bsfs; i++)
+ av_bsf_flush(s->bsfs[i]);
+}
+
void avcodec_flush_buffers(AVCodecContext *avctx)
{
avctx->internal->draining = 0;
@@ -1410,7 +1410,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
else if (avctx->codec->flush)
avctx->codec->flush(avctx);

- ff_decode_bsfs_uninit(avctx);
+ bsfs_flush(avctx);

if (!avctx->refcounted_frames)
av_frame_unref(avctx->internal->to_free);
diff --git a/libavcodec/decode.h b/libavcodec/decode.h
index 37b2e45c6..4a76d7a85 100644
--- a/libavcodec/decode.h
+++ b/libavcodec/decode.h
@@ -69,6 +69,8 @@ typedef struct FrameDecodeData {
*/
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt);

+int ff_decode_bsfs_init(AVCodecContext *avctx);
+
void ff_decode_bsfs_uninit(AVCodecContext *avctx);

/**
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index ba3457664..13d9e4e62 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -664,6 +664,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
ret = AVERROR(EINVAL);
goto free_and_end;
}
+
+ ret = ff_decode_bsfs_init(avctx);
+ if (ret < 0)
+ goto free_and_end;
}
end:
if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) {
@@ -706,6 +710,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_packet_free(&avctx->internal->last_pkt_props);

av_packet_free(&avctx->internal->ds.in_pkt);
+ ff_decode_bsfs_uninit(avctx);

av_freep(&avctx->internal->pool);
}
--
2.18.0
James Almer
2018-07-27 17:59:57 UTC
Permalink
Certain AVCodecParameters, like the contents of the extradata, may be changed
by the init() function of any of the bitstream filters in the chain.

Signed-off-by: James Almer <***@gmail.com>
---
libavcodec/decode.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 2dab7f2a7..d10a2c8b5 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -221,6 +221,10 @@ int ff_decode_bsfs_init(AVCodecContext *avctx)
goto fail;
}

+ ret = avcodec_parameters_to_context(avctx, s->bsfs[s->nb_bsfs - 1]->par_out);
+ if (ret < 0)
+ return ret;
+
return 0;
fail:
ff_decode_bsfs_uninit(avctx);
--
2.18.0
Luca Barbato
2018-07-27 20:51:18 UTC
Permalink
Meant to reset the internal bsf state without the need to reinitialize it.
The set looks good.

Loading...