mirror of https://git.ffmpeg.org/ffmpeg.git
libx264: Pass the reordered_opaque field through the encoder
libx264 does have a field for opaque data to pass along with frames through the encoder, but it is a pointer, while the libavcodec reordered_opaque field is an int64_t. Therefore, allocate an array within the libx264 wrapper, where reordered_opaque values in flight are stored, and pass a pointer to this array to libx264. Update the public libavcodec documentation for the AVCodecContext field to explain this usage, and add a codec capability that allows detecting whether an encoder handles this field. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
a3a501df24
commit
80f85a95da
|
@ -899,6 +899,13 @@ typedef struct RcOverride{
|
||||||
*/
|
*/
|
||||||
#define AV_CODEC_CAP_HYBRID (1 << 18)
|
#define AV_CODEC_CAP_HYBRID (1 << 18)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This codec takes the reordered_opaque field from input AVFrames
|
||||||
|
* and returns it in the corresponding field in AVCodecContext after
|
||||||
|
* encoding.
|
||||||
|
*/
|
||||||
|
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 19)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pan Scan area.
|
* Pan Scan area.
|
||||||
* This specifies the area which should be displayed.
|
* This specifies the area which should be displayed.
|
||||||
|
@ -2297,7 +2304,10 @@ typedef struct AVCodecContext {
|
||||||
/**
|
/**
|
||||||
* opaque 64-bit number (generally a PTS) that will be reordered and
|
* opaque 64-bit number (generally a PTS) that will be reordered and
|
||||||
* output in AVFrame.reordered_opaque
|
* output in AVFrame.reordered_opaque
|
||||||
* - encoding: unused
|
* - encoding: Set by libavcodec to the reordered_opaque of the input
|
||||||
|
* frame corresponding to the last returned packet. Only
|
||||||
|
* supported by encoders with the
|
||||||
|
* AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability.
|
||||||
* - decoding: Set by user.
|
* - decoding: Set by user.
|
||||||
*/
|
*/
|
||||||
int64_t reordered_opaque;
|
int64_t reordered_opaque;
|
||||||
|
|
|
@ -85,6 +85,9 @@ typedef struct X264Context {
|
||||||
int noise_reduction;
|
int noise_reduction;
|
||||||
|
|
||||||
char *x264_params;
|
char *x264_params;
|
||||||
|
|
||||||
|
int nb_reordered_opaque, next_reordered_opaque;
|
||||||
|
int64_t *reordered_opaque;
|
||||||
} X264Context;
|
} X264Context;
|
||||||
|
|
||||||
static void X264_log(void *p, int level, const char *fmt, va_list args)
|
static void X264_log(void *p, int level, const char *fmt, va_list args)
|
||||||
|
@ -240,6 +243,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
|
||||||
x264_nal_t *nal;
|
x264_nal_t *nal;
|
||||||
int nnal, i, ret;
|
int nnal, i, ret;
|
||||||
x264_picture_t pic_out;
|
x264_picture_t pic_out;
|
||||||
|
int64_t *out_opaque;
|
||||||
|
|
||||||
x264_picture_init( &x4->pic );
|
x264_picture_init( &x4->pic );
|
||||||
x4->pic.img.i_csp = x4->params.i_csp;
|
x4->pic.img.i_csp = x4->params.i_csp;
|
||||||
|
@ -259,6 +263,11 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
|
||||||
|
|
||||||
x4->pic.i_pts = frame->pts;
|
x4->pic.i_pts = frame->pts;
|
||||||
|
|
||||||
|
x4->reordered_opaque[x4->next_reordered_opaque] = frame->reordered_opaque;
|
||||||
|
x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
|
||||||
|
x4->next_reordered_opaque++;
|
||||||
|
x4->next_reordered_opaque %= x4->nb_reordered_opaque;
|
||||||
|
|
||||||
switch (frame->pict_type) {
|
switch (frame->pict_type) {
|
||||||
case AV_PICTURE_TYPE_I:
|
case AV_PICTURE_TYPE_I:
|
||||||
x4->pic.i_type = x4->forced_idr ? X264_TYPE_IDR
|
x4->pic.i_type = x4->forced_idr ? X264_TYPE_IDR
|
||||||
|
@ -288,6 +297,15 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
|
||||||
pkt->pts = pic_out.i_pts;
|
pkt->pts = pic_out.i_pts;
|
||||||
pkt->dts = pic_out.i_dts;
|
pkt->dts = pic_out.i_dts;
|
||||||
|
|
||||||
|
out_opaque = pic_out.opaque;
|
||||||
|
if (out_opaque >= x4->reordered_opaque &&
|
||||||
|
out_opaque < &x4->reordered_opaque[x4->nb_reordered_opaque]) {
|
||||||
|
ctx->reordered_opaque = *out_opaque;
|
||||||
|
} else {
|
||||||
|
// Unexpected opaque pointer on picture output
|
||||||
|
ctx->reordered_opaque = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if FF_API_CODED_FRAME
|
#if FF_API_CODED_FRAME
|
||||||
FF_DISABLE_DEPRECATION_WARNINGS
|
FF_DISABLE_DEPRECATION_WARNINGS
|
||||||
switch (pic_out.i_type) {
|
switch (pic_out.i_type) {
|
||||||
|
@ -331,6 +349,7 @@ static av_cold int X264_close(AVCodecContext *avctx)
|
||||||
|
|
||||||
av_freep(&avctx->extradata);
|
av_freep(&avctx->extradata);
|
||||||
av_freep(&x4->sei);
|
av_freep(&x4->sei);
|
||||||
|
av_freep(&x4->reordered_opaque);
|
||||||
|
|
||||||
if (x4->enc) {
|
if (x4->enc) {
|
||||||
x264_encoder_close(x4->enc);
|
x264_encoder_close(x4->enc);
|
||||||
|
@ -663,6 +682,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
cpb_props->max_bitrate = x4->params.rc.i_vbv_max_bitrate * 1000;
|
cpb_props->max_bitrate = x4->params.rc.i_vbv_max_bitrate * 1000;
|
||||||
cpb_props->avg_bitrate = x4->params.rc.i_bitrate * 1000;
|
cpb_props->avg_bitrate = x4->params.rc.i_bitrate * 1000;
|
||||||
|
|
||||||
|
// Overestimate the reordered opaque buffer size, in case a runtime
|
||||||
|
// reconfigure would increase the delay (which it shouldn't).
|
||||||
|
x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 17;
|
||||||
|
x4->reordered_opaque = av_malloc_array(x4->nb_reordered_opaque,
|
||||||
|
sizeof(*x4->reordered_opaque));
|
||||||
|
if (!x4->reordered_opaque)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +877,8 @@ AVCodec ff_libx264_encoder = {
|
||||||
.init = X264_init,
|
.init = X264_init,
|
||||||
.encode2 = X264_frame,
|
.encode2 = X264_frame,
|
||||||
.close = X264_close,
|
.close = X264_close,
|
||||||
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS |
|
||||||
|
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
||||||
.priv_class = &class,
|
.priv_class = &class,
|
||||||
.defaults = x264_defaults,
|
.defaults = x264_defaults,
|
||||||
.init_static_data = X264_init_static,
|
.init_static_data = X264_init_static,
|
||||||
|
@ -877,7 +905,8 @@ AVCodec ff_libx262_encoder = {
|
||||||
.init = X264_init,
|
.init = X264_init,
|
||||||
.encode2 = X264_frame,
|
.encode2 = X264_frame,
|
||||||
.close = X264_close,
|
.close = X264_close,
|
||||||
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS |
|
||||||
|
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
|
||||||
.priv_class = &X262_class,
|
.priv_class = &X262_class,
|
||||||
.defaults = x264_defaults,
|
.defaults = x264_defaults,
|
||||||
.pix_fmts = pix_fmts_8bit,
|
.pix_fmts = pix_fmts_8bit,
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "libavutil/version.h"
|
#include "libavutil/version.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 58
|
#define LIBAVCODEC_VERSION_MAJOR 58
|
||||||
#define LIBAVCODEC_VERSION_MINOR 10
|
#define LIBAVCODEC_VERSION_MINOR 11
|
||||||
#define LIBAVCODEC_VERSION_MICRO 0
|
#define LIBAVCODEC_VERSION_MICRO 0
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
|
|
Loading…
Reference in New Issue