mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-28 14:01:27 +00:00
libavcodec/hevc_mp4toannexb_bsf.c: Optional argument "private_spspps_buf" to avoid extradata modification.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
07558ad582
commit
0b8b18b4fb
@ -35,9 +35,21 @@ typedef struct HEVCBSFContext {
|
||||
int extradata_parsed;
|
||||
|
||||
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;
|
||||
|
||||
static int hevc_extradata_to_annexb(AVCodecContext *avctx)
|
||||
static int hevc_extradata_to_annexb(HEVCBSFContext* ctx, AVCodecContext *avctx)
|
||||
{
|
||||
GetByteContext gb;
|
||||
int length_size, num_arrays, i, j;
|
||||
@ -82,9 +94,13 @@ static int hevc_extradata_to_annexb(AVCodecContext *avctx)
|
||||
}
|
||||
}
|
||||
|
||||
av_freep(&avctx->extradata);
|
||||
avctx->extradata = new_extradata;
|
||||
avctx->extradata_size = new_extradata_size;
|
||||
if (!ctx->private_spspps) {
|
||||
av_freep(&avctx->extradata);
|
||||
avctx->extradata = new_extradata;
|
||||
avctx->extradata_size = new_extradata_size;
|
||||
}
|
||||
ctx->spspps_buf = new_extradata;
|
||||
ctx->spspps_size = new_extradata_size;
|
||||
|
||||
if (!new_extradata_size)
|
||||
av_log(avctx, AV_LOG_WARNING, "No parameter sets in the extradata\n");
|
||||
@ -122,8 +138,10 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
*poutbuf_size = buf_size;
|
||||
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)
|
||||
return ret;
|
||||
ctx->length_size = ret;
|
||||
@ -148,7 +166,7 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
/* prepend extradata to IRAP frames */
|
||||
is_irap = nalu_type >= 16 && nalu_type <= 23;
|
||||
add_extradata = is_irap && !got_irap;
|
||||
extra_size = add_extradata * avctx->extradata_size;
|
||||
extra_size = add_extradata * ctx->spspps_size;
|
||||
got_irap |= is_irap;
|
||||
|
||||
if (SIZE_MAX - out_size < 4 ||
|
||||
@ -163,7 +181,7 @@ static int hevc_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
goto fail;
|
||||
|
||||
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);
|
||||
bytestream2_get_buffer(&gb, out + out_size + 4 + extra_size, nalu_size);
|
||||
out_size += 4 + nalu_size + extra_size;
|
||||
@ -179,8 +197,16 @@ fail:
|
||||
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 = {
|
||||
"hevc_mp4toannexb",
|
||||
sizeof(HEVCBSFContext),
|
||||
hevc_mp4toannexb_filter,
|
||||
hevc_mp4toannexb_close,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user