From c042cbc3a68d09a20cfd75fb4a4eff0534253081 Mon Sep 17 00:00:00 2001 From: Marcus Gustafsson Date: Tue, 25 Mar 2014 21:51:21 +0100 Subject: libx265: Use the repeat headers flag when not using global headers This allows proper muxing and seeking in things like MPEG-TS, by placing headers by random access points. Signed-off-by: Derek Buitenhuis --- libavcodec/libx265.c | 57 +++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index b12407030e..77d0b03bee 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -38,8 +38,6 @@ typedef struct libx265Context { x265_encoder *encoder; x265_param *params; - uint8_t *header; - int header_size; char *preset; char *tune; @@ -66,7 +64,6 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx) libx265Context *ctx = avctx->priv_data; av_frame_free(&avctx->coded_frame); - av_freep(&ctx->header); x265_param_free(ctx->params); @@ -82,8 +79,6 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) x265_nal *nal; int sar_num, sar_den; int nnal; - int ret; - int i; if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL && !av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w && @@ -147,6 +142,9 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ctx->params->rc.rateControlMode = X265_RC_ABR; } + if (!(avctx->flags & CODEC_FLAG_GLOBAL_HEADER)) + ctx->params->bRepeatHeaders = 1; + if (ctx->x265_opts) { AVDictionary *dict = NULL; AVDictionaryEntry *en = NULL; @@ -179,32 +177,23 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - ret = x265_encoder_headers(ctx->encoder, &nal, &nnal); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n"); - libx265_encode_close(avctx); - return AVERROR_INVALIDDATA; - } - - for (i = 0; i < nnal; i++) - ctx->header_size += nal[i].sizeBytes; - - ctx->header = av_malloc(ctx->header_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!ctx->header) { - av_log(avctx, AV_LOG_ERROR, - "Cannot allocate HEVC header of size %d.\n", ctx->header_size); - libx265_encode_close(avctx); - return AVERROR(ENOMEM); - } - - memcpy(ctx->header, nal[0].payload, ctx->header_size); - if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { - avctx->extradata_size = ctx->header_size; - avctx->extradata = ctx->header; + avctx->extradata_size = x265_encoder_headers(ctx->encoder, &nal, &nnal); + if (avctx->extradata_size <= 0) { + av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n"); + libx265_encode_close(avctx); + return AVERROR_INVALIDDATA; + } - ctx->header_size = 0; - ctx->header = NULL; + avctx->extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, + "Cannot allocate HEVC header of size %d.\n", avctx->extradata_size); + libx265_encode_close(avctx); + return AVERROR(ENOMEM); + } + + memcpy(avctx->extradata, nal[0].payload, avctx->extradata_size); } return 0; @@ -246,8 +235,6 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, for (i = 0; i < nnal; i++) payload += nal[i].sizeBytes; - payload += ctx->header_size; - ret = ff_alloc_packet(pkt, payload); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); @@ -255,14 +242,6 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } dst = pkt->data; - if (ctx->header) { - memcpy(dst, ctx->header, ctx->header_size); - dst += ctx->header_size; - - av_freep(&ctx->header); - ctx->header_size = 0; - } - for (i = 0; i < nnal; i++) { memcpy(dst, nal[i].payload, nal[i].sizeBytes); dst += nal[i].sizeBytes; -- cgit v1.2.3