This avoids a dependancy of libavfilter on libavcodec See Ticket 3592 Fixes Ticket2784
Unified · Split
| @@ -4690,30 +4690,8 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int · 4689 unmodified lines | ||
| 4690 | 4690 | */ |
| 4691 | 4691 | unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt); |
| 4692 | 4692 | |
| 4693 | −#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ | |
| 4694 | −#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ | |
| 4695 | −#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ | |
| 4696 | −#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ | |
| 4697 | −#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ | |
| 4698 | −#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ | |
| 4699 | − | |
| 4700 | −/** | |
| 4701 | − * Compute what kind of losses will occur when converting from one specific | |
| 4702 | − * pixel format to another. | |
| 4703 | − * When converting from one pixel format to another, information loss may occur. | |
| 4704 | − * For example, when converting from RGB24 to GRAY, the color information will | |
| 4705 | − * be lost. Similarly, other losses occur when converting from some formats to | |
| 4706 | − * other formats. These losses can involve loss of chroma, but also loss of | |
| 4707 | − * resolution, loss of color depth, loss due to the color space conversion, loss | |
| 4708 | − * of the alpha bits or loss due to color quantization. | |
| 4709 | − * avcodec_get_fix_fmt_loss() informs you about the various types of losses | |
| 4710 | − * which will occur when converting from one pixel format to another. | |
| 4711 | − * | |
| 4712 | − * @param[in] dst_pix_fmt destination pixel format | |
| 4713 | − * @param[in] src_pix_fmt source pixel format | |
| 4714 | − * @param[in] has_alpha Whether the source pixel format alpha channel is used. | |
| 4715 | − * @return Combination of flags informing you what kind of losses will occur | |
| 4716 | − * (maximum loss for an invalid dst_pix_fmt). | |
| 4693 | +/** | |
| 4694 | + * @deprecated see av_get_pix_fmt_loss() | |
| 4717 | 4695 | */ |
| 4718 | 4696 | int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, |
| 4719 | 4697 | int has_alpha); |
| @@ -4740,34 +4718,7 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *p · 20 unmodified lines | ||
| 4740 | 4718 | int has_alpha, int *loss_ptr); |
| 4741 | 4719 | |
| 4742 | 4720 | /** |
| 4743 | − * Find the best pixel format to convert to given a certain source pixel | |
| 4744 | − * format and a selection of two destination pixel formats. When converting from | |
| 4745 | − * one pixel format to another, information loss may occur. For example, when converting | |
| 4746 | − * from RGB24 to GRAY, the color information will be lost. Similarly, other losses occur when | |
| 4747 | − * converting from some formats to other formats. avcodec_find_best_pix_fmt_of_2() selects which of | |
| 4748 | − * the given pixel formats should be used to suffer the least amount of loss. | |
| 4749 | − * | |
| 4750 | − * If one of the destination formats is AV_PIX_FMT_NONE the other pixel format (if valid) will be | |
| 4751 | − * returned. | |
| 4752 | − * | |
| 4753 | − * @code | |
| 4754 | − * src_pix_fmt = AV_PIX_FMT_YUV420P; | |
| 4755 | − * dst_pix_fmt1= AV_PIX_FMT_RGB24; | |
| 4756 | − * dst_pix_fmt2= AV_PIX_FMT_GRAY8; | |
| 4757 | − * dst_pix_fmt3= AV_PIX_FMT_RGB8; | |
| 4758 | − * loss= FF_LOSS_CHROMA; // don't care about chroma loss, so chroma loss will be ignored. | |
| 4759 | − * dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, alpha, &loss); | |
| 4760 | − * dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt, dst_pix_fmt3, src_pix_fmt, alpha, &loss); | |
| 4761 | − * @endcode | |
| 4762 | − * | |
| 4763 | − * @param[in] dst_pix_fmt1 One of the two destination pixel formats to choose from | |
| 4764 | − * @param[in] dst_pix_fmt2 The other of the two destination pixel formats to choose from | |
| 4765 | − * @param[in] src_pix_fmt Source pixel format | |
| 4766 | − * @param[in] has_alpha Whether the source pixel format alpha channel is used. | |
| 4767 | − * @param[in, out] loss_ptr Combination of loss flags. In: selects which of the losses to ignore, i.e. | |
| 4768 | − * NULL or value of zero means we care about all losses. Out: the loss | |
| 4769 | − * that occurs when converting from src to selected dst pixel format. | |
| 4770 | − * @return The best pixel format to convert to or -1 if none was found. | |
| 4721 | + * @deprecated see av_find_best_pix_fmt_of_2() | |
| 4771 | 4722 | */ |
| 4772 | 4723 | enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, |
| 4773 | 4724 | enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); |
| @@ -40,12 +40,6 @@ · 39 unmodified lines | ||
| 40 | 40 | #include "libavutil/pixdesc.h" |
| 41 | 41 | #include "libavutil/imgutils.h" |
| 42 | 42 | |
| 43 | −#define FF_COLOR_NA -1 | |
| 44 | −#define FF_COLOR_RGB 0 /**< RGB color space */ | |
| 45 | −#define FF_COLOR_GRAY 1 /**< gray color space */ | |
| 46 | −#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ | |
| 47 | −#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ | |
| 48 | − | |
| 49 | 43 | #if HAVE_MMX_EXTERNAL |
| 50 | 44 | #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx |
| 51 | 45 | #define deinterlace_line ff_deinterlace_line_mmx |
| @@ -54,10 +48,6 @@ · 2 unmodified lines | ||
| 54 | 48 | #define deinterlace_line deinterlace_line_c |
| 55 | 49 | #endif |
| 56 | 50 | |
| 57 | −#define pixdesc_has_alpha(pixdesc) \ | |
| 58 | − ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL) | |
| 59 | − | |
| 60 | − | |
| 61 | 51 | void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift) |
| 62 | 52 | { |
| 63 | 53 | 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 · 2 unmodified lines | ||
| 66 | 56 | *v_shift = desc->log2_chroma_h; |
| 67 | 57 | } |
| 68 | 58 | |
| 69 | −static int get_color_type(const AVPixFmtDescriptor *desc) { | |
| 70 | − if (desc->flags & AV_PIX_FMT_FLAG_PAL) | |
| 71 | − return FF_COLOR_RGB; | |
| 72 | − | |
| 73 | − if(desc->nb_components == 1 || desc->nb_components == 2) | |
| 74 | − return FF_COLOR_GRAY; | |
| 75 | − | |
| 76 | − if(desc->name && !strncmp(desc->name, "yuvj", 4)) | |
| 77 | − return FF_COLOR_YUV_JPEG; | |
| 78 | − | |
| 79 | − if(desc->flags & AV_PIX_FMT_FLAG_RGB) | |
| 80 | − return FF_COLOR_RGB; | |
| 81 | − | |
| 82 | − if(desc->nb_components == 0) | |
| 83 | − return FF_COLOR_NA; | |
| 84 | − | |
| 85 | − return FF_COLOR_YUV; | |
| 86 | −} | |
| 87 | − | |
| 88 | −static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt) | |
| 89 | −{ | |
| 90 | − const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
| 91 | − int i; | |
| 92 | − | |
| 93 | − if (!desc || !desc->nb_components) { | |
| 94 | − *min = *max = 0; | |
| 95 | − return AVERROR(EINVAL); | |
| 96 | − } | |
| 97 | − | |
| 98 | − *min = INT_MAX, *max = -INT_MAX; | |
| 99 | − for (i = 0; i < desc->nb_components; i++) { | |
| 100 | − *min = FFMIN(desc->comp[i].depth_minus1+1, *min); | |
| 101 | − *max = FFMAX(desc->comp[i].depth_minus1+1, *max); | |
| 102 | − } | |
| 103 | − return 0; | |
| 104 | −} | |
| 105 | − | |
| 106 | −static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, | |
| 107 | − enum AVPixelFormat src_pix_fmt, | |
| 108 | − unsigned *lossp, unsigned consider) | |
| 109 | −{ | |
| 110 | − const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); | |
| 111 | − const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); | |
| 112 | − int src_color, dst_color; | |
| 113 | − int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; | |
| 114 | − int ret, loss, i, nb_components; | |
| 115 | − int score = INT_MAX - 1; | |
| 116 | − | |
| 117 | − if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE) | |
| 118 | − return ~0; | |
| 119 | − | |
| 120 | − /* compute loss */ | |
| 121 | − *lossp = loss = 0; | |
| 122 | − | |
| 123 | − if (dst_pix_fmt == src_pix_fmt) | |
| 124 | − return INT_MAX; | |
| 125 | − | |
| 126 | − if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) | |
| 127 | − return ret; | |
| 128 | − if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) | |
| 129 | − return ret; | |
| 130 | − | |
| 131 | − src_color = get_color_type(src_desc); | |
| 132 | − dst_color = get_color_type(dst_desc); | |
| 133 | − if (dst_pix_fmt == AV_PIX_FMT_PAL8) | |
| 134 | − nb_components = FFMIN(src_desc->nb_components, 4); | |
| 135 | − else | |
| 136 | − nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components); | |
| 137 | − | |
| 138 | − for (i = 0; i < nb_components; i++) { | |
| 139 | − int depth_minus1 = (dst_pix_fmt == AV_PIX_FMT_PAL8) ? 7/nb_components : dst_desc->comp[i].depth_minus1; | |
| 140 | − if (src_desc->comp[i].depth_minus1 > depth_minus1 && (consider & FF_LOSS_DEPTH)) { | |
| 141 | − loss |= FF_LOSS_DEPTH; | |
| 142 | − score -= 65536 >> depth_minus1; | |
| 143 | − } | |
| 144 | − } | |
| 145 | − | |
| 146 | − if (consider & FF_LOSS_RESOLUTION) { | |
| 147 | − if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) { | |
| 148 | − loss |= FF_LOSS_RESOLUTION; | |
| 149 | − score -= 256 << dst_desc->log2_chroma_w; | |
| 150 | − } | |
| 151 | − if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) { | |
| 152 | − loss |= FF_LOSS_RESOLUTION; | |
| 153 | − score -= 256 << dst_desc->log2_chroma_h; | |
| 154 | − } | |
| 155 | − // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side | |
| 156 | − if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 && | |
| 157 | − dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) { | |
| 158 | − score += 512; | |
| 159 | − } | |
| 160 | − } | |
| 161 | − | |
| 162 | − if(consider & FF_LOSS_COLORSPACE) | |
| 163 | − switch(dst_color) { | |
| 164 | − case FF_COLOR_RGB: | |
| 165 | − if (src_color != FF_COLOR_RGB && | |
| 166 | − src_color != FF_COLOR_GRAY) | |
| 167 | − loss |= FF_LOSS_COLORSPACE; | |
| 168 | − break; | |
| 169 | − case FF_COLOR_GRAY: | |
| 170 | − if (src_color != FF_COLOR_GRAY) | |
| 171 | − loss |= FF_LOSS_COLORSPACE; | |
| 172 | − break; | |
| 173 | − case FF_COLOR_YUV: | |
| 174 | − if (src_color != FF_COLOR_YUV) | |
| 175 | − loss |= FF_LOSS_COLORSPACE; | |
| 176 | − break; | |
| 177 | − case FF_COLOR_YUV_JPEG: | |
| 178 | − if (src_color != FF_COLOR_YUV_JPEG && | |
| 179 | − src_color != FF_COLOR_YUV && | |
| 180 | − src_color != FF_COLOR_GRAY) | |
| 181 | − loss |= FF_LOSS_COLORSPACE; | |
| 182 | − break; | |
| 183 | − default: | |
| 184 | − /* fail safe test */ | |
| 185 | − if (src_color != dst_color) | |
| 186 | − loss |= FF_LOSS_COLORSPACE; | |
| 187 | − break; | |
| 188 | − } | |
| 189 | − if(loss & FF_LOSS_COLORSPACE) | |
| 190 | − score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1); | |
| 191 | − | |
| 192 | − if (dst_color == FF_COLOR_GRAY && | |
| 193 | − src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) { | |
| 194 | − loss |= FF_LOSS_CHROMA; | |
| 195 | − score -= 2 * 65536; | |
| 196 | − } | |
| 197 | − if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) { | |
| 198 | − loss |= FF_LOSS_ALPHA; | |
| 199 | − score -= 65536; | |
| 200 | − } | |
| 201 | − if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) && | |
| 202 | − (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) { | |
| 203 | − loss |= FF_LOSS_COLORQUANT; | |
| 204 | − score -= 65536; | |
| 205 | − } | |
| 206 | − | |
| 207 | − *lossp = loss; | |
| 208 | − return score; | |
| 209 | −} | |
| 210 | − | |
| 211 | 59 | int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, |
| 212 | 60 | enum AVPixelFormat src_pix_fmt, |
| 213 | 61 | int has_alpha) |
| 214 | 62 | { |
| 215 | − int loss; | |
| 216 | − int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA); | |
| 217 | − if (ret < 0) | |
| 218 | − return ret; | |
| 219 | − return loss; | |
| 63 | + return av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); | |
| 220 | 64 | } |
| 221 | 65 | |
| 222 | 66 | enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, |
| 223 | 67 | enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) |
| 224 | 68 | { |
| 225 | − enum AVPixelFormat dst_pix_fmt; | |
| 226 | − int loss1, loss2, loss_mask; | |
| 227 | − const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1); | |
| 228 | − const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2); | |
| 229 | − int score1, score2; | |
| 230 | − | |
| 231 | − loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ | |
| 232 | − if(!has_alpha) | |
| 233 | − loss_mask &= ~FF_LOSS_ALPHA; | |
| 234 | − | |
| 235 | − dst_pix_fmt = AV_PIX_FMT_NONE; | |
| 236 | − score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); | |
| 237 | − score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); | |
| 238 | − | |
| 239 | − if (score1 == score2) { | |
| 240 | − if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { | |
| 241 | − dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; | |
| 242 | − } else { | |
| 243 | − dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; | |
| 244 | − } | |
| 245 | − } else { | |
| 246 | − dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; | |
| 247 | − } | |
| 248 | − | |
| 249 | − if (loss_ptr) | |
| 250 | − *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); | |
| 251 | − return dst_pix_fmt; | |
| 69 | + return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr); | |
| 252 | 70 | } |
| 253 | 71 | |
| 254 | 72 | #if AV_HAVE_INCOMPATIBLE_LIBAV_ABI |
| @@ -657,7 +475,7 @@ int main(void){ · 402 unmodified lines | ||
| 657 | 475 | av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip); |
| 658 | 476 | skip = 0; |
| 659 | 477 | } |
| 660 | − 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)); | |
| 478 | + 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)); | |
| 661 | 479 | if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) { |
| 662 | 480 | av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n"); |
| 663 | 481 | err = 1; |
| @@ -31,7 +31,6 @@ · 30 unmodified lines | ||
| 31 | 31 | #include "libavutil/internal.h" |
| 32 | 32 | #include "libavutil/opt.h" |
| 33 | 33 | #include "libavutil/pixdesc.h" |
| 34 | −#include "libavcodec/avcodec.h" // avcodec_find_best_pix_fmt_of_2() | |
| 35 | 34 | |
| 36 | 35 | #include "avfilter.h" |
| 37 | 36 | #include "formats.h" |
| @@ -628,7 +627,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 590 unmodified lines | ||
| 628 | 627 | int i; |
| 629 | 628 | for (i=0; i<link->in_formats->nb_formats; i++) { |
| 630 | 629 | enum AVPixelFormat p = link->in_formats->formats[i]; |
| 631 | − best= avcodec_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL); | |
| 630 | + best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL); | |
| 632 | 631 | } |
| 633 | 632 | av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n", |
| 634 | 633 | av_get_pix_fmt_name(best), link->in_formats->nb_formats, |
| @@ -164,6 +164,7 @@ TESTPROGS = adler32 \ · 163 unmodified lines | ||
| 164 | 164 | opt \ |
| 165 | 165 | pca \ |
| 166 | 166 | parseutils \ |
| 167 | + pixdesc \ | |
| 167 | 168 | random_seed \ |
| 168 | 169 | rational \ |
| 169 | 170 | ripemd \ |
| @@ -2082,3 +2082,226 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) · 2081 unmodified lines | ||
| 2082 | 2082 | |
| 2083 | 2083 | return get_pix_fmt_internal(name); |
| 2084 | 2084 | } |
| 2085 | + | |
| 2086 | +#define FF_COLOR_NA -1 | |
| 2087 | +#define FF_COLOR_RGB 0 /**< RGB color space */ | |
| 2088 | +#define FF_COLOR_GRAY 1 /**< gray color space */ | |
| 2089 | +#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ | |
| 2090 | +#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ | |
| 2091 | + | |
| 2092 | +#define pixdesc_has_alpha(pixdesc) \ | |
| 2093 | + ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL) | |
| 2094 | + | |
| 2095 | + | |
| 2096 | +static int get_color_type(const AVPixFmtDescriptor *desc) { | |
| 2097 | + if (desc->flags & AV_PIX_FMT_FLAG_PAL) | |
| 2098 | + return FF_COLOR_RGB; | |
| 2099 | + | |
| 2100 | + if(desc->nb_components == 1 || desc->nb_components == 2) | |
| 2101 | + return FF_COLOR_GRAY; | |
| 2102 | + | |
| 2103 | + if(desc->name && !strncmp(desc->name, "yuvj", 4)) | |
| 2104 | + return FF_COLOR_YUV_JPEG; | |
| 2105 | + | |
| 2106 | + if(desc->flags & AV_PIX_FMT_FLAG_RGB) | |
| 2107 | + return FF_COLOR_RGB; | |
| 2108 | + | |
| 2109 | + if(desc->nb_components == 0) | |
| 2110 | + return FF_COLOR_NA; | |
| 2111 | + | |
| 2112 | + return FF_COLOR_YUV; | |
| 2113 | +} | |
| 2114 | + | |
| 2115 | +static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt) | |
| 2116 | +{ | |
| 2117 | + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); | |
| 2118 | + int i; | |
| 2119 | + | |
| 2120 | + if (!desc || !desc->nb_components) { | |
| 2121 | + *min = *max = 0; | |
| 2122 | + return AVERROR(EINVAL); | |
| 2123 | + } | |
| 2124 | + | |
| 2125 | + *min = INT_MAX, *max = -INT_MAX; | |
| 2126 | + for (i = 0; i < desc->nb_components; i++) { | |
| 2127 | + *min = FFMIN(desc->comp[i].depth_minus1+1, *min); | |
| 2128 | + *max = FFMAX(desc->comp[i].depth_minus1+1, *max); | |
| 2129 | + } | |
| 2130 | + return 0; | |
| 2131 | +} | |
| 2132 | + | |
| 2133 | +static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, | |
| 2134 | + enum AVPixelFormat src_pix_fmt, | |
| 2135 | + unsigned *lossp, unsigned consider) | |
| 2136 | +{ | |
| 2137 | + const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); | |
| 2138 | + const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); | |
| 2139 | + int src_color, dst_color; | |
| 2140 | + int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; | |
| 2141 | + int ret, loss, i, nb_components; | |
| 2142 | + int score = INT_MAX - 1; | |
| 2143 | + | |
| 2144 | + if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE) | |
| 2145 | + return ~0; | |
| 2146 | + | |
| 2147 | + /* compute loss */ | |
| 2148 | + *lossp = loss = 0; | |
| 2149 | + | |
| 2150 | + if (dst_pix_fmt == src_pix_fmt) | |
| 2151 | + return INT_MAX; | |
| 2152 | + | |
| 2153 | + if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) | |
| 2154 | + return ret; | |
| 2155 | + if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) | |
| 2156 | + return ret; | |
| 2157 | + | |
| 2158 | + src_color = get_color_type(src_desc); | |
| 2159 | + dst_color = get_color_type(dst_desc); | |
| 2160 | + if (dst_pix_fmt == AV_PIX_FMT_PAL8) | |
| 2161 | + nb_components = FFMIN(src_desc->nb_components, 4); | |
| 2162 | + else | |
| 2163 | + nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components); | |
| 2164 | + | |
| 2165 | + for (i = 0; i < nb_components; i++) { | |
| 2166 | + int depth_minus1 = (dst_pix_fmt == AV_PIX_FMT_PAL8) ? 7/nb_components : dst_desc->comp[i].depth_minus1; | |
| 2167 | + if (src_desc->comp[i].depth_minus1 > depth_minus1 && (consider & FF_LOSS_DEPTH)) { | |
| 2168 | + loss |= FF_LOSS_DEPTH; | |
| 2169 | + score -= 65536 >> depth_minus1; | |
| 2170 | + } | |
| 2171 | + } | |
| 2172 | + | |
| 2173 | + if (consider & FF_LOSS_RESOLUTION) { | |
| 2174 | + if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) { | |
| 2175 | + loss |= FF_LOSS_RESOLUTION; | |
| 2176 | + score -= 256 << dst_desc->log2_chroma_w; | |
| 2177 | + } | |
| 2178 | + if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) { | |
| 2179 | + loss |= FF_LOSS_RESOLUTION; | |
| 2180 | + score -= 256 << dst_desc->log2_chroma_h; | |
| 2181 | + } | |
| 2182 | + // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side | |
| 2183 | + if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 && | |
| 2184 | + dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) { | |
| 2185 | + score += 512; | |
| 2186 | + } | |
| 2187 | + } | |
| 2188 | + | |
| 2189 | + if(consider & FF_LOSS_COLORSPACE) | |
| 2190 | + switch(dst_color) { | |
| 2191 | + case FF_COLOR_RGB: | |
| 2192 | + if (src_color != FF_COLOR_RGB && | |
| 2193 | + src_color != FF_COLOR_GRAY) | |
| 2194 | + loss |= FF_LOSS_COLORSPACE; | |
| 2195 | + break; | |
| 2196 | + case FF_COLOR_GRAY: | |
| 2197 | + if (src_color != FF_COLOR_GRAY) | |
| 2198 | + loss |= FF_LOSS_COLORSPACE; | |
| 2199 | + break; | |
| 2200 | + case FF_COLOR_YUV: | |
| 2201 | + if (src_color != FF_COLOR_YUV) | |
| 2202 | + loss |= FF_LOSS_COLORSPACE; | |
| 2203 | + break; | |
| 2204 | + case FF_COLOR_YUV_JPEG: | |
| 2205 | + if (src_color != FF_COLOR_YUV_JPEG && | |
| 2206 | + src_color != FF_COLOR_YUV && | |
| 2207 | + src_color != FF_COLOR_GRAY) | |
| 2208 | + loss |= FF_LOSS_COLORSPACE; | |
| 2209 | + break; | |
| 2210 | + default: | |
| 2211 | + /* fail safe test */ | |
| 2212 | + if (src_color != dst_color) | |
| 2213 | + loss |= FF_LOSS_COLORSPACE; | |
| 2214 | + break; | |
| 2215 | + } | |
| 2216 | + if(loss & FF_LOSS_COLORSPACE) | |
| 2217 | + score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1); | |
| 2218 | + | |
| 2219 | + if (dst_color == FF_COLOR_GRAY && | |
| 2220 | + src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) { | |
| 2221 | + loss |= FF_LOSS_CHROMA; | |
| 2222 | + score -= 2 * 65536; | |
| 2223 | + } | |
| 2224 | + if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) { | |
| 2225 | + loss |= FF_LOSS_ALPHA; | |
| 2226 | + score -= 65536; | |
| 2227 | + } | |
| 2228 | + if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) && | |
| 2229 | + (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) { | |
| 2230 | + loss |= FF_LOSS_COLORQUANT; | |
| 2231 | + score -= 65536; | |
| 2232 | + } | |
| 2233 | + | |
| 2234 | + *lossp = loss; | |
| 2235 | + return score; | |
| 2236 | +} | |
| 2237 | + | |
| 2238 | +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, | |
| 2239 | + enum AVPixelFormat src_pix_fmt, | |
| 2240 | + int has_alpha) | |
| 2241 | +{ | |
| 2242 | + int loss; | |
| 2243 | + int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA); | |
| 2244 | + if (ret < 0) | |
| 2245 | + return ret; | |
| 2246 | + return loss; | |
| 2247 | +} | |
| 2248 | + | |
| 2249 | +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, | |
| 2250 | + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) | |
| 2251 | +{ | |
| 2252 | + enum AVPixelFormat dst_pix_fmt; | |
| 2253 | + int loss1, loss2, loss_mask; | |
| 2254 | + const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1); | |
| 2255 | + const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2); | |
| 2256 | + int score1, score2; | |
| 2257 | + | |
| 2258 | + loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ | |
| 2259 | + if(!has_alpha) | |
| 2260 | + loss_mask &= ~FF_LOSS_ALPHA; | |
| 2261 | + | |
| 2262 | + dst_pix_fmt = AV_PIX_FMT_NONE; | |
| 2263 | + score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); | |
| 2264 | + score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); | |
| 2265 | + | |
| 2266 | + if (score1 == score2) { | |
| 2267 | + if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { | |
| 2268 | + dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; | |
| 2269 | + } else { | |
| 2270 | + dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; | |
| 2271 | + } | |
| 2272 | + } else { | |
| 2273 | + dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; | |
| 2274 | + } | |
| 2275 | + | |
| 2276 | + if (loss_ptr) | |
| 2277 | + *loss_ptr = av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); | |
| 2278 | + return dst_pix_fmt; | |
| 2279 | +} | |
| 2280 | + | |
| 2281 | +#ifdef TEST | |
| 2282 | + | |
| 2283 | +int main(void){ | |
| 2284 | + int i; | |
| 2285 | + int err=0; | |
| 2286 | + int skip = 0; | |
| 2287 | + | |
| 2288 | + for (i=0; i<AV_PIX_FMT_NB*2; i++) { | |
| 2289 | + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i); | |
| 2290 | + if(!desc || !desc->name) { | |
| 2291 | + skip ++; | |
| 2292 | + continue; | |
| 2293 | + } | |
| 2294 | + if (skip) { | |
| 2295 | + av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip); | |
| 2296 | + skip = 0; | |
| 2297 | + } | |
| 2298 | + av_log(NULL, AV_LOG_INFO, "pix fmt %s avg_bpp:%d colortype:%d\n", desc->name, av_get_padded_bits_per_pixel(desc), get_color_type(desc)); | |
| 2299 | + if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) { | |
| 2300 | + av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n"); | |
| 2301 | + err = 1; | |
| 2302 | + } | |
| 2303 | + } | |
| 2304 | + return err; | |
| 2305 | +} | |
| 2306 | + | |
| 2307 | +#endif | |
| @@ -255,7 +255,7 @@ enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); · 254 unmodified lines | ||
| 255 | 255 | * Utility function to access log2_chroma_w log2_chroma_h from |
| 256 | 256 | * the pixel format AVPixFmtDescriptor. |
| 257 | 257 | * |
| 258 | − * See avcodec_get_chroma_sub_sample() for a function that asserts a | |
| 258 | + * See av_get_chroma_sub_sample() for a function that asserts a | |
| 259 | 259 | * valid pixel format instead of returning an error code. |
| 260 | 260 | * Its recommanded that you use avcodec_get_chroma_sub_sample unless |
| 261 | 261 | * you do check the return code! |
| @@ -287,5 +287,53 @@ void ff_check_pixfmt_descriptors(void); · 25 unmodified lines | ||
| 287 | 287 | */ |
| 288 | 288 | enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt); |
| 289 | 289 | |
| 290 | +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ | |
| 291 | +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ | |
| 292 | +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ | |
| 293 | +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ | |
| 294 | +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ | |
| 295 | +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ | |
| 290 | 296 | |
| 297 | +/** | |
| 298 | + * Compute what kind of losses will occur when converting from one specific | |
| 299 | + * pixel format to another. | |
| 300 | + * When converting from one pixel format to another, information loss may occur. | |
| 301 | + * For example, when converting from RGB24 to GRAY, the color information will | |
| 302 | + * be lost. Similarly, other losses occur when converting from some formats to | |
| 303 | + * other formats. These losses can involve loss of chroma, but also loss of | |
| 304 | + * resolution, loss of color depth, loss due to the color space conversion, loss | |
| 305 | + * of the alpha bits or loss due to color quantization. | |
| 306 | + * av_get_fix_fmt_loss() informs you about the various types of losses | |
| 307 | + * which will occur when converting from one pixel format to another. | |
| 308 | + * | |
| 309 | + * @param[in] dst_pix_fmt destination pixel format | |
| 310 | + * @param[in] src_pix_fmt source pixel format | |
| 311 | + * @param[in] has_alpha Whether the source pixel format alpha channel is used. | |
| 312 | + * @return Combination of flags informing you what kind of losses will occur | |
| 313 | + * (maximum loss for an invalid dst_pix_fmt). | |
| 314 | + */ | |
| 315 | +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, | |
| 316 | + enum AVPixelFormat src_pix_fmt, | |
| 317 | + int has_alpha); | |
| 318 | + | |
| 319 | +/** | |
| 320 | + * Compute what kind of losses will occur when converting from one specific | |
| 321 | + * pixel format to another. | |
| 322 | + * When converting from one pixel format to another, information loss may occur. | |
| 323 | + * For example, when converting from RGB24 to GRAY, the color information will | |
| 324 | + * be lost. Similarly, other losses occur when converting from some formats to | |
| 325 | + * other formats. These losses can involve loss of chroma, but also loss of | |
| 326 | + * resolution, loss of color depth, loss due to the color space conversion, loss | |
| 327 | + * of the alpha bits or loss due to color quantization. | |
| 328 | + * av_get_fix_fmt_loss() informs you about the various types of losses | |
| 329 | + * which will occur when converting from one pixel format to another. | |
| 330 | + * | |
| 331 | + * @param[in] dst_pix_fmt destination pixel format | |
| 332 | + * @param[in] src_pix_fmt source pixel format | |
| 333 | + * @param[in] has_alpha Whether the source pixel format alpha channel is used. | |
| 334 | + * @return Combination of flags informing you what kind of losses will occur | |
| 335 | + * (maximum loss for an invalid dst_pix_fmt). | |
| 336 | + */ | |
| 337 | +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, | |
| 338 | + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); | |
| 291 | 339 | #endif /* AVUTIL_PIXDESC_H */ |