- // Ignore.
- } else {
- if (avctx->coded_width < constraints->min_width ||
- avctx->coded_height < constraints->min_height ||
- avctx->coded_width > constraints->max_width ||
- avctx->coded_height > constraints->max_height) {
- av_log(avctx, AV_LOG_ERROR, "Hardware does not support image "
- "size %dx%d (constraints: width %d-%d height %d-%d).\n",
- avctx->coded_width, avctx->coded_height,
- constraints->min_width, constraints->max_width,
- constraints->min_height, constraints->max_height);
- err = AVERROR(EINVAL);
- goto fail;
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (avctx->coded_width < constraints->min_width ||
+ avctx->coded_height < constraints->min_height ||
+ avctx->coded_width > constraints->max_width ||
+ avctx->coded_height > constraints->max_height) {
+ av_log(avctx, AV_LOG_ERROR, "Hardware does not support image "
+ "size %dx%d (constraints: width %d-%d height %d-%d).\n",
+ avctx->coded_width, avctx->coded_height,
+ constraints->min_width, constraints->max_width,
+ constraints->min_height, constraints->max_height);
+ err = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (!constraints->valid_sw_formats ||
+ constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) {
+ av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any "
+ "usable surface formats.\n");
+ err = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ // Find the first format in the list which matches the expected
+ // bit depth and subsampling. If none are found (this can happen
+ // when 10-bit streams are decoded to 8-bit surfaces, for example)
+ // then just take the first format on the list.
+ ctx->surface_format = constraints->valid_sw_formats[0];
+ sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
+ for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
+ desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]);
+ if (desc->nb_components != sw_desc->nb_components ||
+ desc->log2_chroma_w != sw_desc->log2_chroma_w ||
+ desc->log2_chroma_h != sw_desc->log2_chroma_h)
+ continue;
+ for (j = 0; j < desc->nb_components; j++) {
+ if (desc->comp[j].depth != sw_desc->comp[j].depth)
+ break;