History

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

Michael Niedermayer committed 12 years ago

Commit 617e8661 parent 8ff72926 files · +280 −240Browse files

Unified · Split

6 files
  1. libavcodec/avcodec.h +3 −52
  2. libavcodec/imgconvert.c +3 −185
  3. libavfilter/avfiltergraph.c +1 −2
  4. libavutil/Makefile +1 −0
  5. libavutil/pixdesc.c +223 −0
  6. libavutil/pixdesc.h +49 −1
libavcodec/avcodec.h+3−52
@@ -4690,30 +4690,8 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int · 4689 unmodified lines
46904690 */
46914691 unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt);
46924692
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()
47174695 */
47184696 int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt,
47194697 int has_alpha);
@@ -4740,34 +4718,7 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *p · 20 unmodified lines
47404718 int has_alpha, int *loss_ptr);
47414719
47424720 /**
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()
47714722 */
47724723 enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
47734724 enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
libavcodec/imgconvert.c+3−185
@@ -40,12 +40,6 @@ · 39 unmodified lines
4040 #include "libavutil/pixdesc.h"
4141 #include "libavutil/imgutils.h"
4242
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−
4943 #if HAVE_MMX_EXTERNAL
5044 #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
5145 #define deinterlace_line ff_deinterlace_line_mmx
@@ -54,10 +48,6 @@ · 2 unmodified lines
5448 #define deinterlace_line deinterlace_line_c
5549 #endif
5650
57−#define pixdesc_has_alpha(pixdesc) \
58− ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL)
59−
60−
6151 void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
6252 {
6353 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
6656 *v_shift = desc->log2_chroma_h;
6757 }
6858
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−
21159 int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
21260 enum AVPixelFormat src_pix_fmt,
21361 int has_alpha)
21462 {
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);
22064 }
22165
22266 enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
22367 enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
22468 {
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);
25270 }
25371
25472 #if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
@@ -657,7 +475,7 @@ int main(void){ · 402 unmodified lines
657475 av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
658476 skip = 0;
659477 }
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));
661479 if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
662480 av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
663481 err = 1;
libavfilter/avfiltergraph.c+1−2
@@ -31,7 +31,6 @@ · 30 unmodified lines
3131 #include "libavutil/internal.h"
3232 #include "libavutil/opt.h"
3333 #include "libavutil/pixdesc.h"
34−#include "libavcodec/avcodec.h" // avcodec_find_best_pix_fmt_of_2()
3534
3635 #include "avfilter.h"
3736 #include "formats.h"
@@ -628,7 +627,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 590 unmodified lines
628627 int i;
629628 for (i=0; i<link->in_formats->nb_formats; i++) {
630629 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);
632631 }
633632 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
634633 av_get_pix_fmt_name(best), link->in_formats->nb_formats,
libavutil/Makefile+1−0
@@ -164,6 +164,7 @@ TESTPROGS = adler32 \ · 163 unmodified lines
164164 opt \
165165 pca \
166166 parseutils \
167+ pixdesc \
167168 random_seed \
168169 rational \
169170 ripemd \
libavutil/pixdesc.c+223−0
@@ -2082,3 +2082,226 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) · 2081 unmodified lines
20822082
20832083 return get_pix_fmt_internal(name);
20842084 }
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
libavutil/pixdesc.h+49−1
@@ -255,7 +255,7 @@ enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); · 254 unmodified lines
255255 * Utility function to access log2_chroma_w log2_chroma_h from
256256 * the pixel format AVPixFmtDescriptor.
257257 *
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
259259 * valid pixel format instead of returning an error code.
260260 * Its recommanded that you use avcodec_get_chroma_sub_sample unless
261261 * you do check the return code!
@@ -287,5 +287,53 @@ void ff_check_pixfmt_descriptors(void); · 25 unmodified lines
287287 */
288288 enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt);
289289
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) */
290296
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);
291339 #endif /* AVUTIL_PIXDESC_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t