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 <derek.buitenhuis@gmail.com>
This commit is contained in:
Marcus Gustafsson 2014-03-25 21:51:21 +01:00 committed by Derek Buitenhuis
parent 32998ee957
commit 1b28d9b357
1 changed files with 18 additions and 39 deletions

View File

@ -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;