Commit 0b8b18b4 authored by Ivan Uskov's avatar Ivan Uskov Committed by Michael Niedermayer

libavcodec/hevc_mp4toannexb_bsf.c: Optional argument "private_spspps_buf" to...

libavcodec/hevc_mp4toannexb_bsf.c: Optional argument "private_spspps_buf" to avoid extradata modification.
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 07558ad5
...@@ -35,9 +35,21 @@ typedef struct HEVCBSFContext { ...@@ -35,9 +35,21 @@ typedef struct HEVCBSFContext {
int extradata_parsed; int extradata_parsed;
int logged_nonmp4_warning; int logged_nonmp4_warning;
/* When private_spspps is zero then spspps_buf points to global extradata
and bsf does replace a global extradata to own-allocated version (default
behaviour).
When private_spspps is non-zero the bsf uses a private version of spspps buf.
This mode necessary when bsf uses in decoder, else bsf has issues after
decoder re-initialization. Use the "private_spspps_buf" argument to
activate this mode.
*/
int private_spspps;
uint8_t *spspps_buf;
uint32_t spspps_size;
} HEVCBSFContext; } HEVCBSFContext;
static int hevc_extradata_to_annexb(AVCodecContext *avctx) static int hevc_extradata_to_annexb(HEVCBSFContext* ctx, AVCodecContext *avctx)
{ {
GetByteContext gb; GetByteContext gb;
int length_size, num_arrays, i, j; int length_size, num_arrays, i, j;
...@@ -82,9 +94,13 @@ static int hevc_extradata_to_annexb(AVCodecContext *avctx) ...@@ -82,9 +94,13 @@ static int hevc_extradata_to_annexb(AVCodecContext *avctx)
} }
} }
if (!ctx->private_spspps) {
av_freep(&avctx->extradata); av_freep(&avctx->extradata);
avctx->extradata = new_extradata; avctx->extradata = new_extradata;
avctx->extradata_size = new_extradata_size; avctx->extradata_size = new_extradata_size;
}
ctx->spspps_buf = new_extradata;
ctx->spspps_size = new_extradata_size;
if (!new_extradata_size) if (!new_extradata_size)
av_log(avctx, AV_LOG_WARNING, "No parameter sets in the extradata\n"); av_log(avctx, AV_LOG_WARNING, "No parameter sets in the extradata\n");
...@@ -122,8 +138,10 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, ...@@ -122,8 +138,10 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
*poutbuf_size = buf_size; *poutbuf_size = buf_size;
return 0; return 0;
} }
if (args && strstr(args, "private_spspps_buf"))
ctx->private_spspps = 1;
ret = hevc_extradata_to_annexb(avctx); ret = hevc_extradata_to_annexb(ctx, avctx);
if (ret < 0) if (ret < 0)
return ret; return ret;
ctx->length_size = ret; ctx->length_size = ret;
...@@ -148,7 +166,7 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, ...@@ -148,7 +166,7 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
/* prepend extradata to IRAP frames */ /* prepend extradata to IRAP frames */
is_irap = nalu_type >= 16 && nalu_type <= 23; is_irap = nalu_type >= 16 && nalu_type <= 23;
add_extradata = is_irap && !got_irap; add_extradata = is_irap && !got_irap;
extra_size = add_extradata * avctx->extradata_size; extra_size = add_extradata * ctx->spspps_size;
got_irap |= is_irap; got_irap |= is_irap;
if (SIZE_MAX - out_size < 4 || if (SIZE_MAX - out_size < 4 ||
...@@ -163,7 +181,7 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, ...@@ -163,7 +181,7 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
goto fail; goto fail;
if (add_extradata) if (add_extradata)
memcpy(out + out_size, avctx->extradata, extra_size); memcpy(out + out_size, ctx->spspps_buf, extra_size);
AV_WB32(out + out_size + extra_size, 1); AV_WB32(out + out_size + extra_size, 1);
bytestream2_get_buffer(&gb, out + out_size + 4 + extra_size, nalu_size); bytestream2_get_buffer(&gb, out + out_size + 4 + extra_size, nalu_size);
out_size += 4 + nalu_size + extra_size; out_size += 4 + nalu_size + extra_size;
...@@ -179,8 +197,16 @@ fail: ...@@ -179,8 +197,16 @@ fail:
return ret; return ret;
} }
static void hevc_mp4toannexb_close(AVBitStreamFilterContext *bsfc)
{
HEVCBSFContext *ctx = bsfc->priv_data;
if (ctx->private_spspps)
av_freep(&ctx->spspps_buf);
}
AVBitStreamFilter ff_hevc_mp4toannexb_bsf = { AVBitStreamFilter ff_hevc_mp4toannexb_bsf = {
"hevc_mp4toannexb", "hevc_mp4toannexb",
sizeof(HEVCBSFContext), sizeof(HEVCBSFContext),
hevc_mp4toannexb_filter, hevc_mp4toannexb_filter,
hevc_mp4toannexb_close,
}; };
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