enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target) { if (codec && codec->pix_fmts) { const enum AVPixelFormat *p = codec->pix_fmts; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target); int has_alpha = desc ? desc->nb_components % 2 == 0 : 0; enum AVPixelFormat best= AV_PIX_FMT_NONE; if (enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { p = get_compliance_unofficial_pix_fmts(enc_ctx->codec_id, p); } for (; *p != AV_PIX_FMT_NONE; p++) { best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL); if (*p == target) break; } if (*p == AV_PIX_FMT_NONE) { if (target != AV_PIX_FMT_NONE) av_log(NULL, AV_LOG_WARNING, "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n", av_get_pix_fmt_name(target), codec->name, av_get_pix_fmt_name(best)); return best; } } return target; }
static char *choose_pix_fmts(OutputStream *ost) { AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0); if(strict_dict) // used by choose_pixel_fmt() and below { av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0); } if(ost->keep_pix_fmt) { if(ost->filter) avfilter_graph_set_auto_convert(ost->filter->graph->graph, AVFILTER_AUTO_CONVERT_NONE); if(ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE) { return NULL; } return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt)); } if(ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) { return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt))); } else if(ost->enc && ost->enc->pix_fmts) { const enum AVPixelFormat *p; AVIOContext *s = NULL; uint8_t *ret; int len; if(avio_open_dyn_buf(&s) < 0) { exit_program(1); } p = ost->enc->pix_fmts; if(ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p); } for(; *p != AV_PIX_FMT_NONE; p++) { const char *name = av_get_pix_fmt_name(*p); avio_printf(s, "%s|", name); } len = avio_close_dyn_buf(s, &ret); ret[len - 1] = 0; return ret; } else { return NULL; } }