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:
parent
cd60631752
commit
c042cbc3a6
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user