You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
imgconvert: add get_pix_fmt_score()
get_pix_fmt_score() returns a score representing the amount of loss when converting a pixel format Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -104,24 +104,25 @@ static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
|
static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt,
|
||||||
enum AVPixelFormat src_pix_fmt,
|
enum AVPixelFormat src_pix_fmt,
|
||||||
int has_alpha)
|
unsigned *lossp, unsigned consider)
|
||||||
{
|
{
|
||||||
const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
|
const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
|
||||||
const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
|
const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
|
||||||
int src_color, dst_color;
|
int src_color, dst_color;
|
||||||
int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
|
int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
|
||||||
int ret, loss, i, nb_components;
|
int ret, loss, i, nb_components;
|
||||||
|
int score = INT_MAX;
|
||||||
|
|
||||||
if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
|
if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
|
||||||
return ~0;
|
return ~0;
|
||||||
|
|
||||||
/* compute loss */
|
/* compute loss */
|
||||||
loss = 0;
|
*lossp = loss = 0;
|
||||||
|
|
||||||
if (dst_pix_fmt == src_pix_fmt)
|
if (dst_pix_fmt == src_pix_fmt)
|
||||||
return 0;
|
return INT_MAX;
|
||||||
|
|
||||||
if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
|
if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -133,13 +134,28 @@ int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
|
|||||||
nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components);
|
nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components);
|
||||||
|
|
||||||
for (i = 0; i < nb_components; i++)
|
for (i = 0; i < nb_components; i++)
|
||||||
if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1)
|
if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1 && (consider & FF_LOSS_DEPTH)) {
|
||||||
loss |= FF_LOSS_DEPTH;
|
loss |= FF_LOSS_DEPTH;
|
||||||
|
score -= 65536 >> dst_desc->comp[i].depth_minus1;
|
||||||
|
}
|
||||||
|
|
||||||
if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
|
if (consider & FF_LOSS_RESOLUTION) {
|
||||||
dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
|
if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) {
|
||||||
loss |= FF_LOSS_RESOLUTION;
|
loss |= FF_LOSS_RESOLUTION;
|
||||||
|
score -= 256 << dst_desc->log2_chroma_w;
|
||||||
|
}
|
||||||
|
if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) {
|
||||||
|
loss |= FF_LOSS_RESOLUTION;
|
||||||
|
score -= 256 << dst_desc->log2_chroma_h;
|
||||||
|
}
|
||||||
|
// dont favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side
|
||||||
|
if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 &&
|
||||||
|
dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) {
|
||||||
|
score += 512;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(consider & FF_LOSS_COLORSPACE)
|
||||||
switch(dst_color) {
|
switch(dst_color) {
|
||||||
case FF_COLOR_RGB:
|
case FF_COLOR_RGB:
|
||||||
if (src_color != FF_COLOR_RGB &&
|
if (src_color != FF_COLOR_RGB &&
|
||||||
@@ -166,15 +182,36 @@ int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
|
|||||||
loss |= FF_LOSS_COLORSPACE;
|
loss |= FF_LOSS_COLORSPACE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dst_color == FF_COLOR_GRAY &&
|
if(loss & FF_LOSS_COLORSPACE)
|
||||||
src_color != FF_COLOR_GRAY)
|
score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1);
|
||||||
loss |= FF_LOSS_CHROMA;
|
|
||||||
if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && has_alpha))
|
|
||||||
loss |= FF_LOSS_ALPHA;
|
|
||||||
if (dst_pix_fmt == AV_PIX_FMT_PAL8 &&
|
|
||||||
(src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && has_alpha))))
|
|
||||||
loss |= FF_LOSS_COLORQUANT;
|
|
||||||
|
|
||||||
|
if (dst_color == FF_COLOR_GRAY &&
|
||||||
|
src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) {
|
||||||
|
loss |= FF_LOSS_CHROMA;
|
||||||
|
score -= 2 * 65536;
|
||||||
|
}
|
||||||
|
if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) {
|
||||||
|
loss |= FF_LOSS_ALPHA;
|
||||||
|
score -= 65536;
|
||||||
|
}
|
||||||
|
if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) &&
|
||||||
|
(src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) {
|
||||||
|
loss |= FF_LOSS_COLORQUANT;
|
||||||
|
score -= 65536;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lossp = loss;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
|
||||||
|
enum AVPixelFormat src_pix_fmt,
|
||||||
|
int has_alpha)
|
||||||
|
{
|
||||||
|
int loss;
|
||||||
|
int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
return loss;
|
return loss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user