提交 5fdcf85b 编写于 作者: M Mark Thompson

vaapi_encode: Convert to send/receive API

This attaches the logic of picking the mode of for the next picture to
the output, which simplifies some choices by removing the concept of
the picture for which input is not yet available.  At the same time,
we allow more complex reference structures and track more reference
metadata (particularly the contents of the DPB) for use in the
codec-specific code.

It also adds flags to explicitly track the available features of the
different codecs.  The new structure also allows open-GOP support, so
that is now available for codecs which can do it.
上级 26ce3a43
......@@ -2807,15 +2807,24 @@ Size / quality tradeoff: higher values are smaller / worse quality.
@end itemize
All encoders support the following options:
@itemize
@item
@option{low_power}
@table @option
@item low_power
Some drivers/platforms offer a second encoder for some codecs intended to use
less power than the default encoder; setting this option will attempt to use
that encoder. Note that it may support a reduced feature set, so some other
options may not be available in this mode.
@end itemize
@item idr_interval
Set the number of normal intra frames between full-refresh (IDR) frames in
open-GOP mode. The intra frames are still IRAPs, but will not include global
headers and may have non-decodable leading pictures.
@item b_depth
Set the B-frame reference depth. When set to one (the default), all B-frames
will refer only to P- or I-frames. When set to greater values multiple layers
of B-frames will be present, frames in each layer only referring to frames in
higher layers.
@end table
Each encoder also has its own specific options:
@table @option
......
此差异已折叠。
......@@ -38,6 +38,7 @@ struct VAAPIEncodePicture;
enum {
MAX_CONFIG_ATTRIBUTES = 4,
MAX_GLOBAL_PARAMS = 4,
MAX_DPB_SIZE = 16,
MAX_PICTURE_REFERENCES = 2,
MAX_REORDER_DELAY = 16,
MAX_PARAM_BUFFER_SIZE = 1024,
......@@ -66,9 +67,10 @@ typedef struct VAAPIEncodePicture {
int64_t display_order;
int64_t encode_order;
int64_t pts;
int force_idr;
int type;
int input_available;
int b_depth;
int encode_issued;
int encode_complete;
......@@ -87,8 +89,26 @@ typedef struct VAAPIEncodePicture {
void *priv_data;
void *codec_picture_params;
int nb_refs;
// Whether this picture is a reference picture.
int is_reference;
// The contents of the DPB after this picture has been decoded.
// This will contain the picture itself if it is a reference picture,
// but not if it isn't.
int nb_dpb_pics;
struct VAAPIEncodePicture *dpb[MAX_DPB_SIZE];
// The reference pictures used in decoding this picture. If they are
// used by later pictures they will also appear in the DPB.
int nb_refs;
struct VAAPIEncodePicture *refs[MAX_PICTURE_REFERENCES];
// The previous reference picture in encode order. Must be in at least
// one of the reference list and DPB list.
struct VAAPIEncodePicture *prev;
// Reference count for other pictures referring to this one through
// the above pointers, directly from incomplete pictures and indirectly
// through completed pictures.
int ref_count[2];
int ref_removed[2];
int nb_slices;
VAAPIEncodeSlice *slices;
......@@ -120,6 +140,12 @@ typedef struct VAAPIEncodeContext {
// Use low power encoding mode.
int low_power;
// Number of I frames between IDR frames.
int idr_interval;
// Desired B frame reference depth.
int desired_b_depth;
// Desired packed headers.
unsigned int desired_packed_headers;
......@@ -207,26 +233,21 @@ typedef struct VAAPIEncodeContext {
// Current encoding window, in display (input) order.
VAAPIEncodePicture *pic_start, *pic_end;
// The next picture to use as the previous reference picture in
// encoding order.
VAAPIEncodePicture *next_prev;
// Next input order index (display order).
int64_t input_order;
// Number of frames that output is behind input.
int64_t output_delay;
// Next encode order index.
int64_t encode_order;
// Number of frames decode output will need to be delayed.
int64_t decode_delay;
// Next output order index (encode order).
// Next output order index (in encode order).
int64_t output_order;
enum {
// All encode operations are done independently (synchronise
// immediately after every operation).
ISSUE_MODE_SERIALISE_EVERYTHING = 0,
// Overlap as many operations as possible.
ISSUE_MODE_MAXIMISE_THROUGHPUT,
// Overlap operations only when satisfying parallel dependencies.
ISSUE_MODE_MINIMISE_LATENCY,
} issue_mode;
// Timestamp handling.
int64_t first_pts;
int64_t dts_pts_diff;
......@@ -240,11 +261,14 @@ typedef struct VAAPIEncodeContext {
// Frame type decision.
int gop_size;
int closed_gop;
int gop_per_idr;
int p_per_i;
int max_b_depth;
int b_per_p;
int force_idr;
int idr_counter;
int gop_counter;
int p_counter;
int end_of_stream;
} VAAPIEncodeContext;
......@@ -253,6 +277,15 @@ enum {
FLAG_SLICE_CONTROL = 1 << 0,
// Codec only supports constant quality (no rate control).
FLAG_CONSTANT_QUALITY_ONLY = 1 << 1,
// Codec is intra-only.
FLAG_INTRA_ONLY = 1 << 2,
// Codec supports B-pictures.
FLAG_B_PICTURES = 1 << 3,
// Codec supports referencing B-pictures.
FLAG_B_PICTURE_REFERENCES = 1 << 4,
// Codec supports non-IDR key pictures (that is, key pictures do
// not necessarily empty the DPB).
FLAG_NON_IDR_KEY_PICTURES = 1 << 5,
};
typedef struct VAAPIEncodeType {
......@@ -327,6 +360,9 @@ typedef struct VAAPIEncodeType {
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *input_image, int *got_packet);
int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
int ff_vaapi_encode_init(AVCodecContext *avctx);
int ff_vaapi_encode_close(AVCodecContext *avctx);
......@@ -336,7 +372,15 @@ int ff_vaapi_encode_close(AVCodecContext *avctx);
"Use low-power encoding mode (only available on some platforms; " \
"may not support all encoding features)", \
OFFSET(common.low_power), AV_OPT_TYPE_BOOL, \
{ .i64 = 0 }, 0, 1, FLAGS }
{ .i64 = 0 }, 0, 1, FLAGS }, \
{ "idr_interval", \
"Distance (in I-frames) between IDR frames", \
OFFSET(common.idr_interval), AV_OPT_TYPE_INT, \
{ .i64 = 0 }, 0, INT_MAX, FLAGS }, \
{ "b_depth", \
"Maximum B-frame reference depth", \
OFFSET(common.desired_b_depth), AV_OPT_TYPE_INT, \
{ .i64 = 1 }, 1, INT_MAX, FLAGS }
#endif /* AVCODEC_VAAPI_ENCODE_H */
......@@ -902,7 +902,9 @@ static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = {
static const VAAPIEncodeType vaapi_encode_type_h264 = {
.profiles = vaapi_encode_h264_profiles,
.flags = FLAG_SLICE_CONTROL,
.flags = FLAG_SLICE_CONTROL |
FLAG_B_PICTURES |
FLAG_NON_IDR_KEY_PICTURES,
.configure = &vaapi_encode_h264_configure,
......@@ -1095,7 +1097,8 @@ AVCodec ff_h264_vaapi_encoder = {
.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(VAAPIEncodeH264Context),
.init = &vaapi_encode_h264_init,
.encode2 = &ff_vaapi_encode2,
.send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &vaapi_encode_h264_close,
.priv_class = &vaapi_encode_h264_class,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
......
......@@ -1082,7 +1082,9 @@ static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = {
static const VAAPIEncodeType vaapi_encode_type_h265 = {
.profiles = vaapi_encode_h265_profiles,
.flags = FLAG_SLICE_CONTROL,
.flags = FLAG_SLICE_CONTROL |
FLAG_B_PICTURES |
FLAG_NON_IDR_KEY_PICTURES,
.configure = &vaapi_encode_h265_configure,
......@@ -1237,7 +1239,8 @@ AVCodec ff_hevc_vaapi_encoder = {
.id = AV_CODEC_ID_HEVC,
.priv_data_size = sizeof(VAAPIEncodeH265Context),
.init = &vaapi_encode_h265_init,
.encode2 = &ff_vaapi_encode2,
.send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &vaapi_encode_h265_close,
.priv_class = &vaapi_encode_h265_class,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
......
......@@ -230,6 +230,8 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
const uint8_t *components;
int t, i, quant_scale, len;
av_assert0(pic->type == PICTURE_TYPE_IDR);
desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);
av_assert0(desc);
if (desc->flags & AV_PIX_FMT_FLAG_RGB)
......@@ -476,7 +478,8 @@ static const VAAPIEncodeProfile vaapi_encode_mjpeg_profiles[] = {
static const VAAPIEncodeType vaapi_encode_type_mjpeg = {
.profiles = vaapi_encode_mjpeg_profiles,
.flags = FLAG_CONSTANT_QUALITY_ONLY,
.flags = FLAG_CONSTANT_QUALITY_ONLY |
FLAG_INTRA_ONLY,
.configure = &vaapi_encode_mjpeg_configure,
......@@ -535,7 +538,6 @@ static const AVOption vaapi_encode_mjpeg_options[] = {
static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {
{ "global_quality", "80" },
{ "b", "0" },
{ "g", "1" },
{ NULL },
};
......@@ -553,7 +555,8 @@ AVCodec ff_mjpeg_vaapi_encoder = {
.id = AV_CODEC_ID_MJPEG,
.priv_data_size = sizeof(VAAPIEncodeMJPEGContext),
.init = &vaapi_encode_mjpeg_init,
.encode2 = &ff_vaapi_encode2,
.send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &vaapi_encode_mjpeg_close,
.priv_class = &vaapi_encode_mjpeg_class,
.capabilities = AV_CODEC_CAP_HARDWARE |
......
......@@ -563,6 +563,8 @@ static const VAAPIEncodeProfile vaapi_encode_mpeg2_profiles[] = {
static const VAAPIEncodeType vaapi_encode_type_mpeg2 = {
.profiles = vaapi_encode_mpeg2_profiles,
.flags = FLAG_B_PICTURES,
.configure = &vaapi_encode_mpeg2_configure,
.sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2),
......@@ -689,7 +691,8 @@ AVCodec ff_mpeg2_vaapi_encoder = {
.id = AV_CODEC_ID_MPEG2VIDEO,
.priv_data_size = sizeof(VAAPIEncodeMPEG2Context),
.init = &vaapi_encode_mpeg2_init,
.encode2 = &ff_vaapi_encode2,
.send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &vaapi_encode_mpeg2_close,
.priv_class = &vaapi_encode_mpeg2_class,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
......
......@@ -246,7 +246,8 @@ AVCodec ff_vp8_vaapi_encoder = {
.id = AV_CODEC_ID_VP8,
.priv_data_size = sizeof(VAAPIEncodeVP8Context),
.init = &vaapi_encode_vp8_init,
.encode2 = &ff_vaapi_encode2,
.send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &ff_vaapi_encode_close,
.priv_class = &vaapi_encode_vp8_class,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
......
......@@ -213,6 +213,8 @@ static const VAAPIEncodeProfile vaapi_encode_vp9_profiles[] = {
static const VAAPIEncodeType vaapi_encode_type_vp9 = {
.profiles = vaapi_encode_vp9_profiles,
.flags = FLAG_B_PICTURES,
.configure = &vaapi_encode_vp9_configure,
.sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9),
......@@ -275,7 +277,8 @@ AVCodec ff_vp9_vaapi_encoder = {
.id = AV_CODEC_ID_VP9,
.priv_data_size = sizeof(VAAPIEncodeVP9Context),
.init = &vaapi_encode_vp9_init,
.encode2 = &ff_vaapi_encode2,
.send_frame = &ff_vaapi_encode_send_frame,
.receive_packet = &ff_vaapi_encode_receive_packet,
.close = &ff_vaapi_encode_close,
.priv_class = &vaapi_encode_vp9_class,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册