+static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
+{
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+ VAStatus vas;
+ VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
+ uint32_t ref_l0, ref_l1;
+
+ vas = vaGetConfigAttributes(ctx->hwctx->display,
+ ctx->va_profile,
+ ctx->va_entrypoint,
+ &attr, 1);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
+ "attribute: %d (%s).\n", vas, vaErrorStr(vas));
+ return AVERROR_EXTERNAL;
+ }
+
+ if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
+ ref_l0 = ref_l1 = 0;
+ } else {
+ ref_l0 = attr.value & 0xffff;
+ ref_l1 = attr.value >> 16 & 0xffff;
+ }
+
+ if (avctx->gop_size <= 1) {
+ av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
+ ctx->gop_size = 1;
+ } else if (ref_l0 < 1) {
+ av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
+ "reference frames.\n");
+ return AVERROR(EINVAL);
+ } else if (ref_l1 < 1 || avctx->max_b_frames < 1) {
+ av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
+ "(supported references: %d / %d).\n", ref_l0, ref_l1);
+ ctx->gop_size = avctx->gop_size;
+ ctx->p_per_i = INT_MAX;
+ ctx->b_per_p = 0;
+ } else {
+ av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
+ "(supported references: %d / %d).\n", ref_l0, ref_l1);
+ ctx->gop_size = avctx->gop_size;
+ ctx->p_per_i = INT_MAX;
+ ctx->b_per_p = avctx->max_b_frames;
+ }
+
+ return 0;
+}
+