Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2018-09-19 01:30:58 +0300
committerMark Thompson <sw@jkqxz.net>2018-09-23 16:42:34 +0300
commitbb3503164eed2a1217315f9d54e986e7276183c6 (patch)
treef912d961dbe0658e1bebe875c2b4a121287c0c19 /libavcodec/vaapi_encode_h264.c
parentcc549149d3bcb653976193eb56aedb3589e7347e (diff)
vaapi_encode_h264: Set level based on stream if not set by user
Diffstat (limited to 'libavcodec/vaapi_encode_h264.c')
-rw-r--r--libavcodec/vaapi_encode_h264.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 0774ec25f9..e55ed0f59c 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -30,6 +30,7 @@
#include "cbs.h"
#include "cbs_h264.h"
#include "h264.h"
+#include "h264_levels.h"
#include "h264_sei.h"
#include "internal.h"
#include "vaapi_encode.h"
@@ -294,6 +295,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
H264RawPPS *pps = &priv->raw_pps;
VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params;
VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params;
+ int dpb_frames;
memset(&priv->current_access_unit, 0,
sizeof(priv->current_access_unit));
@@ -319,7 +321,32 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
sps->constraint_set5_flag = ctx->b_per_p == 0;
}
- sps->level_idc = avctx->level;
+ if (ctx->gop_size == 1)
+ dpb_frames = 0;
+ else
+ dpb_frames = 1 + (ctx->b_per_p > 0);
+
+ if (avctx->level != FF_LEVEL_UNKNOWN) {
+ sps->level_idc = avctx->level;
+ } else {
+ const H264LevelDescriptor *level;
+
+ level = ff_h264_guess_level(sps->profile_idc,
+ avctx->bit_rate,
+ priv->mb_width * 16,
+ priv->mb_height * 16,
+ dpb_frames);
+ if (level) {
+ av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
+ if (level->constraint_set3_flag)
+ sps->constraint_set3_flag = 1;
+ sps->level_idc = level->level_idc;
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "Stream will not conform "
+ "to any level: using level 6.2.\n");
+ sps->level_idc = 62;
+ }
+ }
sps->seq_parameter_set_id = 0;
sps->chroma_format_idc = 1;
@@ -329,8 +356,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
sps->log2_max_pic_order_cnt_lsb_minus4 =
av_clip(av_log2(ctx->b_per_p + 1) - 2, 0, 12);
- sps->max_num_ref_frames =
- ctx->gop_size == 1 ? 0 : 1 + (ctx->b_per_p > 0);
+ sps->max_num_ref_frames = dpb_frames;
sps->pic_width_in_mbs_minus1 = priv->mb_width - 1;
sps->pic_height_in_map_units_minus1 = priv->mb_height - 1;
@@ -938,6 +964,12 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
return AVERROR_PATCHWELCOME;
}
+ if (avctx->level != FF_LEVEL_UNKNOWN && avctx->level & ~0xff) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid level %d: must fit "
+ "in 8-bit unsigned integer.\n", avctx->level);
+ return AVERROR(EINVAL);
+ }
+
ctx->desired_packed_headers =
VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS.
VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
@@ -1005,7 +1037,7 @@ static const AVOption vaapi_encode_h264_options[] = {
{ "level", "Set level (level_idc)",
OFFSET(level), AV_OPT_TYPE_INT,
- { .i64 = 51 }, 0x00, 0xff, FLAGS, "level" },
+ { .i64 = FF_LEVEL_UNKNOWN }, FF_LEVEL_UNKNOWN, 0xff, FLAGS, "level" },
#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
{ .i64 = value }, 0, 0, FLAGS, "level"