It needs to create temporary config to query surface attribute.
Showing the changes to libavcodec (2 of 2 files). Show all
Unified · Split
| @@ -1133,6 +1133,68 @@ fail: · 1132 unmodified lines | ||
| 1133 | 1133 | return err; |
| 1134 | 1134 | } |
| 1135 | 1135 | |
| 1136 | +static av_cold int vaapi_encode_surface_alignment(av_unused AVCodecContext *avctx) | |
| 1137 | +{ | |
| 1138 | +#if VA_CHECK_VERSION(1, 21, 0) | |
| 1139 | + VAAPIEncodeContext *ctx = avctx->priv_data; | |
| 1140 | + VASurfaceAttrib *attr_list = NULL; | |
| 1141 | + unsigned int attr_count = 0; | |
| 1142 | + VAConfigID va_config; | |
| 1143 | + VAStatus vas; | |
| 1144 | + int err = 0; | |
| 1145 | + | |
| 1146 | + vas = vaCreateConfig(ctx->hwctx->display, | |
| 1147 | + ctx->va_profile, ctx->va_entrypoint, | |
| 1148 | + NULL, 0, &va_config); | |
| 1149 | + if (vas != VA_STATUS_SUCCESS) { | |
| 1150 | + av_log(avctx, AV_LOG_ERROR, "Failed to create temp encode pipeline " | |
| 1151 | + "configuration: %d (%s).\n", vas, vaErrorStr(vas)); | |
| 1152 | + return AVERROR(EIO); | |
| 1153 | + } | |
| 1154 | + | |
| 1155 | + vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config, | |
| 1156 | + 0, &attr_count); | |
| 1157 | + if (vas != VA_STATUS_SUCCESS) { | |
| 1158 | + av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: " | |
| 1159 | + "%d (%s).\n", vas, vaErrorStr(vas)); | |
| 1160 | + err = AVERROR_EXTERNAL; | |
| 1161 | + goto fail; | |
| 1162 | + } | |
| 1163 | + | |
| 1164 | + attr_list = av_malloc(attr_count * sizeof(*attr_list)); | |
| 1165 | + if (!attr_list) { | |
| 1166 | + err = AVERROR(ENOMEM); | |
| 1167 | + goto fail; | |
| 1168 | + } | |
| 1169 | + | |
| 1170 | + vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config, | |
| 1171 | + attr_list, &attr_count); | |
| 1172 | + if (vas != VA_STATUS_SUCCESS) { | |
| 1173 | + av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: " | |
| 1174 | + "%d (%s).\n", vas, vaErrorStr(vas)); | |
| 1175 | + err = AVERROR_EXTERNAL; | |
| 1176 | + goto fail; | |
| 1177 | + } | |
| 1178 | + | |
| 1179 | + for (unsigned int i = 0; i < attr_count; i++) { | |
| 1180 | + if (attr_list[i].type == VASurfaceAttribAlignmentSize) { | |
| 1181 | + ctx->surface_alignment_width = | |
| 1182 | + 1 << (attr_list[i].value.value.i & 0xf); | |
| 1183 | + ctx->surface_alignment_height = | |
| 1184 | + 1 << ((attr_list[i].value.value.i & 0xf0) >> 4); | |
| 1185 | + break; | |
| 1186 | + } | |
| 1187 | + } | |
| 1188 | + | |
| 1189 | +fail: | |
| 1190 | + av_freep(&attr_list); | |
| 1191 | + vaDestroyConfig(ctx->hwctx->display, va_config); | |
| 1192 | + return err; | |
| 1193 | +#else | |
| 1194 | + return 0; | |
| 1195 | +#endif | |
| 1196 | +} | |
| 1197 | + | |
| 1136 | 1198 | static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = { |
| 1137 | 1199 | // Bitrate Quality |
| 1138 | 1200 | // | Maxrate | HRD/VBV |
| @@ -2111,6 +2173,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 972 unmodified lines | ||
| 2111 | 2173 | if (err < 0) |
| 2112 | 2174 | goto fail; |
| 2113 | 2175 | |
| 2176 | + err = vaapi_encode_surface_alignment(avctx); | |
| 2177 | + if (err < 0) | |
| 2178 | + goto fail; | |
| 2179 | + | |
| 2114 | 2180 | if (ctx->codec->get_encoder_caps) { |
| 2115 | 2181 | err = ctx->codec->get_encoder_caps(avctx); |
| 2116 | 2182 | if (err < 0) |
| @@ -260,6 +260,10 @@ typedef struct VAAPIEncodeContext { · 259 unmodified lines | ||
| 260 | 260 | * This is a RefStruct reference. |
| 261 | 261 | */ |
| 262 | 262 | VABufferID *coded_buffer_ref; |
| 263 | + | |
| 264 | + // Surface alignment required by driver. | |
| 265 | + int surface_alignment_width; | |
| 266 | + int surface_alignment_height; | |
| 263 | 267 | } VAAPIEncodeContext; |
| 264 | 268 | |
| 265 | 269 | typedef struct VAAPIEncodeType { |