Commit 1b28d9b3 authored by Marcus Gustafsson's avatar Marcus Gustafsson Committed by Derek Buitenhuis

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: 's avatarDerek Buitenhuis <derek.buitenhuis@gmail.com>
parent 32998ee9
...@@ -38,8 +38,6 @@ typedef struct libx265Context { ...@@ -38,8 +38,6 @@ typedef struct libx265Context {
x265_encoder *encoder; x265_encoder *encoder;
x265_param *params; x265_param *params;
uint8_t *header;
int header_size;
char *preset; char *preset;
char *tune; char *tune;
...@@ -66,7 +64,6 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx) ...@@ -66,7 +64,6 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx)
libx265Context *ctx = avctx->priv_data; libx265Context *ctx = avctx->priv_data;
av_frame_free(&avctx->coded_frame); av_frame_free(&avctx->coded_frame);
av_freep(&ctx->header);
x265_param_free(ctx->params); x265_param_free(ctx->params);
...@@ -82,8 +79,6 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -82,8 +79,6 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
x265_nal *nal; x265_nal *nal;
int sar_num, sar_den; int sar_num, sar_den;
int nnal; int nnal;
int ret;
int i;
if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL && if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL &&
!av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w && !av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w &&
...@@ -147,6 +142,9 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -147,6 +142,9 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
ctx->params->rc.rateControlMode = X265_RC_ABR; ctx->params->rc.rateControlMode = X265_RC_ABR;
} }
if (!(avctx->flags & CODEC_FLAG_GLOBAL_HEADER))
ctx->params->bRepeatHeaders = 1;
if (ctx->x265_opts) { if (ctx->x265_opts) {
AVDictionary *dict = NULL; AVDictionary *dict = NULL;
AVDictionaryEntry *en = NULL; AVDictionaryEntry *en = NULL;
...@@ -179,32 +177,23 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -179,32 +177,23 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA; 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) { if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
avctx->extradata_size = ctx->header_size; avctx->extradata_size = x265_encoder_headers(ctx->encoder, &nal, &nnal);
avctx->extradata = ctx->header; 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; avctx->extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
ctx->header = NULL; 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; return 0;
...@@ -246,8 +235,6 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ...@@ -246,8 +235,6 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
for (i = 0; i < nnal; i++) for (i = 0; i < nnal; i++)
payload += nal[i].sizeBytes; payload += nal[i].sizeBytes;
payload += ctx->header_size;
ret = ff_alloc_packet(pkt, payload); ret = ff_alloc_packet(pkt, payload);
if (ret < 0) { if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
...@@ -255,14 +242,6 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ...@@ -255,14 +242,6 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
} }
dst = pkt->data; 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++) { for (i = 0; i < nnal; i++) {
memcpy(dst, nal[i].payload, nal[i].sizeBytes); memcpy(dst, nal[i].payload, nal[i].sizeBytes);
dst += nal[i].sizeBytes; dst += nal[i].sizeBytes;
......
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