| 315 | }; |
| 316 | |
| 317 | static int vaapi_decode_find_best_format(AVCodecContext *avctx, |
| 318 | AVHWDeviceContext *device, |
| 319 | VAConfigID config_id, |
| 320 | AVHWFramesContext *frames) |
| 321 | { |
| 322 | AVVAAPIDeviceContext *hwctx = device->hwctx; |
| 323 | VAStatus vas; |
| 324 | VASurfaceAttrib *attr; |
| 325 | enum AVPixelFormat source_format, best_format, format; |
| 326 | uint32_t best_fourcc, fourcc; |
| 327 | int i, j, nb_attr; |
| 328 | |
| 329 | source_format = avctx->sw_pix_fmt; |
| 330 | av_assert0(source_format != AV_PIX_FMT_NONE); |
| 331 | |
| 332 | vas = vaQuerySurfaceAttributes(hwctx->display, config_id, |
| 333 | NULL, &nb_attr); |
| 334 | if (vas != VA_STATUS_SUCCESS) { |
| 335 | av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: " |
| 336 | "%d (%s).\n", vas, vaErrorStr(vas)); |
| 337 | return AVERROR(ENOSYS); |
| 338 | } |
| 339 | |
| 340 | attr = av_malloc_array(nb_attr, sizeof(*attr)); |
| 341 | if (!attr) |
| 342 | return AVERROR(ENOMEM); |
| 343 | |
| 344 | vas = vaQuerySurfaceAttributes(hwctx->display, config_id, |
| 345 | attr, &nb_attr); |
| 346 | if (vas != VA_STATUS_SUCCESS) { |
| 347 | av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: " |
| 348 | "%d (%s).\n", vas, vaErrorStr(vas)); |
| 349 | av_freep(&attr); |
| 350 | return AVERROR(ENOSYS); |
| 351 | } |
| 352 | |
| 353 | best_format = AV_PIX_FMT_NONE; |
| 354 | |
| 355 | for (i = 0; i < nb_attr; i++) { |
| 356 | if (attr[i].type != VASurfaceAttribPixelFormat) |
| 357 | continue; |
| 358 | |
| 359 | fourcc = attr[i].value.value.i; |
| 360 | for (j = 0; j < FF_ARRAY_ELEMS(vaapi_format_map); j++) { |
| 361 | if (fourcc == vaapi_format_map[j].fourcc) |
| 362 | break; |
| 363 | } |
| 364 | if (j >= FF_ARRAY_ELEMS(vaapi_format_map)) { |
| 365 | av_log(avctx, AV_LOG_DEBUG, "Ignoring unknown format %#x.\n", |
| 366 | fourcc); |
| 367 | continue; |
| 368 | } |
| 369 | format = vaapi_format_map[j].pix_fmt; |
| 370 | av_log(avctx, AV_LOG_DEBUG, "Considering format %#x -> %s.\n", |
| 371 | fourcc, av_get_pix_fmt_name(format)); |
| 372 | |
| 373 | best_format = av_find_best_pix_fmt_of_2(format, best_format, |
| 374 | source_format, 0, NULL); |
no test coverage detected