diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-04-26 18:22:12 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-04-30 23:14:05 +0200 |
commit | 617e866e25b72fa5d9f9d6bbcbd7e4bd69e63a54 (patch) | |
tree | c0f7f9671172f90455510d7555b802eea83b6e9b /libavcodec/imgconvert.c | |
parent | 8ff72924cfeb3c8fa8fc57cfea3f78ca0caaec0f (diff) | |
download | ffmpeg-617e866e25b72fa5d9f9d6bbcbd7e4bd69e63a54.tar.gz |
Move av_find_best_pix_fmt_of_2() from avcodec to avutil
This avoids a dependancy of libavfilter on libavcodec
See Ticket 3592
Fixes Ticket2784
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/imgconvert.c')
-rw-r--r-- | libavcodec/imgconvert.c | 188 |
1 files changed, 3 insertions, 185 deletions
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index cabd3fd26b..27c984a670 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -40,12 +40,6 @@ #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" -#define FF_COLOR_NA -1 -#define FF_COLOR_RGB 0 /**< RGB color space */ -#define FF_COLOR_GRAY 1 /**< gray color space */ -#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ -#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ - #if HAVE_MMX_EXTERNAL #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx #define deinterlace_line ff_deinterlace_line_mmx @@ -54,10 +48,6 @@ #define deinterlace_line deinterlace_line_c #endif -#define pixdesc_has_alpha(pixdesc) \ - ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL) - - void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); @@ -66,189 +56,17 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift = desc->log2_chroma_h; } -static int get_color_type(const AVPixFmtDescriptor *desc) { - if (desc->flags & AV_PIX_FMT_FLAG_PAL) - return FF_COLOR_RGB; - - if(desc->nb_components == 1 || desc->nb_components == 2) - return FF_COLOR_GRAY; - - if(desc->name && !strncmp(desc->name, "yuvj", 4)) - return FF_COLOR_YUV_JPEG; - - if(desc->flags & AV_PIX_FMT_FLAG_RGB) - return FF_COLOR_RGB; - - if(desc->nb_components == 0) - return FF_COLOR_NA; - - return FF_COLOR_YUV; -} - -static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - int i; - - if (!desc || !desc->nb_components) { - *min = *max = 0; - return AVERROR(EINVAL); - } - - *min = INT_MAX, *max = -INT_MAX; - for (i = 0; i < desc->nb_components; i++) { - *min = FFMIN(desc->comp[i].depth_minus1+1, *min); - *max = FFMAX(desc->comp[i].depth_minus1+1, *max); - } - return 0; -} - -static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, - enum AVPixelFormat src_pix_fmt, - unsigned *lossp, unsigned consider) -{ - const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); - const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); - int src_color, dst_color; - int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; - int ret, loss, i, nb_components; - int score = INT_MAX - 1; - - if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE) - return ~0; - - /* compute loss */ - *lossp = loss = 0; - - if (dst_pix_fmt == src_pix_fmt) - return INT_MAX; - - if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) - return ret; - if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) - return ret; - - src_color = get_color_type(src_desc); - dst_color = get_color_type(dst_desc); - if (dst_pix_fmt == AV_PIX_FMT_PAL8) - nb_components = FFMIN(src_desc->nb_components, 4); - else - nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components); - - for (i = 0; i < nb_components; i++) { - int depth_minus1 = (dst_pix_fmt == AV_PIX_FMT_PAL8) ? 7/nb_components : dst_desc->comp[i].depth_minus1; - if (src_desc->comp[i].depth_minus1 > depth_minus1 && (consider & FF_LOSS_DEPTH)) { - loss |= FF_LOSS_DEPTH; - score -= 65536 >> depth_minus1; - } - } - - if (consider & FF_LOSS_RESOLUTION) { - if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) { - 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; - } - // don't 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) { - case FF_COLOR_RGB: - if (src_color != FF_COLOR_RGB && - src_color != FF_COLOR_GRAY) - loss |= FF_LOSS_COLORSPACE; - break; - case FF_COLOR_GRAY: - if (src_color != FF_COLOR_GRAY) - loss |= FF_LOSS_COLORSPACE; - break; - case FF_COLOR_YUV: - if (src_color != FF_COLOR_YUV) - loss |= FF_LOSS_COLORSPACE; - break; - case FF_COLOR_YUV_JPEG: - if (src_color != FF_COLOR_YUV_JPEG && - src_color != FF_COLOR_YUV && - src_color != FF_COLOR_GRAY) - loss |= FF_LOSS_COLORSPACE; - break; - default: - /* fail safe test */ - if (src_color != dst_color) - loss |= FF_LOSS_COLORSPACE; - break; - } - if(loss & FF_LOSS_COLORSPACE) - score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1); - - 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 av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); } enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) { - enum AVPixelFormat dst_pix_fmt; - int loss1, loss2, loss_mask; - const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1); - const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2); - int score1, score2; - - loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ - if(!has_alpha) - loss_mask &= ~FF_LOSS_ALPHA; - - dst_pix_fmt = AV_PIX_FMT_NONE; - score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); - score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); - - if (score1 == score2) { - if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { - dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; - } else { - dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; - } - } else { - dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; - } - - if (loss_ptr) - *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); - return dst_pix_fmt; + return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr); } #if AV_HAVE_INCOMPATIBLE_LIBAV_ABI @@ -657,7 +475,7 @@ int main(void){ av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip); skip = 0; } - av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d colortype:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc), get_color_type(desc)); + av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc)); if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) { av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n"); err = 1; |