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