lqt_color.c
来自「这个库实现了录象功能」· C语言 代码 · 共 1,099 行 · 第 1/3 页
C
1,099 行
/******************************************************************************* lqt_color.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include "quicktime/colormodels.h"#include <stdlib.h>#include <string.h>#define LOG_DOMAIN "color"typedef struct { char * name; int colormodel; } lqt_colormodel_tab;static lqt_colormodel_tab colormodel_table[] = { { "Compressed", BC_COMPRESSED }, { "16 bpp RGB 565", BC_RGB565 }, { "16 bpp BGR 565", BC_BGR565 }, { "24 bpp BGR", BC_BGR888 }, { "32 bpp BGR", BC_BGR8888 }, { "24 bpp RGB", BC_RGB888 }, { "32 bpp RGBA", BC_RGBA8888 }, { "48 bpp RGB", BC_RGB161616 }, { "64 bpp RGBA", BC_RGBA16161616 }, { "32 bpp YUVA", BC_YUVA8888 }, { "YUV 4:2:2 packed (YUY2)", BC_YUV422 }, { "YUV 4:2:0 planar", BC_YUV420P }, { "YUV 4:2:2 planar", BC_YUV422P }, { "YUV 4:4:4 planar", BC_YUV444P }, { "YUV 4:2:2 planar (16 bit)", BC_YUV422P16 }, { "YUV 4:4:4 planar (16 bit)", BC_YUV444P16 }, { "YUV 4:2:0 planar (jpeg)", BC_YUVJ420P }, { "YUV 4:2:2 planar (jpeg)", BC_YUVJ422P }, { "YUV 4:4:4 planar (jpeg)", BC_YUVJ444P }, { "YUV 4:1:1 planar", BC_YUV411P }, { "Undefined", LQT_COLORMODEL_NONE } };/* Some functions to find out, how cheap a colorspace conversion can be */int lqt_colormodel_is_yuv(int colormodel) { switch(colormodel) { case BC_YUVA8888: case BC_YUV422: case BC_YUV420P: case BC_YUV422P: case BC_YUV444P: case BC_YUV422P16: case BC_YUV444P16: case BC_YUVJ420P: case BC_YUVJ422P: case BC_YUVJ444P: case BC_YUV411P: return 1; default: return 0; } }int lqt_colormodel_is_rgb(int colormodel) { switch(colormodel) { case BC_RGB565: case BC_BGR565: case BC_BGR888: case BC_BGR8888: case BC_RGB888: case BC_RGBA8888: case BC_RGB161616: case BC_RGBA16161616: return 1; default: return 0; } }int lqt_colormodel_has_alpha(int colormodel) { switch(colormodel) { case BC_RGBA8888: case BC_RGBA16161616: case BC_YUVA8888: return 1; default: return 0; } }int lqt_colormodel_is_planar(int colormodel) { switch(colormodel) { case BC_YUV420P: case BC_YUV422P: case BC_YUV444P: case BC_YUV422P16: case BC_YUV444P16: case BC_YUVJ422P: case BC_YUVJ444P: case BC_YUVJ420P: case BC_YUV411P: return 1; default: return 0; } }/* Get chroma subsampling factors */void lqt_colormodel_get_chroma_sub(int colormodel, int * sub_h, int * sub_v) { switch(colormodel) { case BC_YUV420P: case BC_YUVJ420P: *sub_h = 2; *sub_v = 2; break; case BC_YUV422: case BC_YUV422P: case BC_YUVJ422P: case BC_YUV422P16: *sub_h = 2; *sub_v = 1; break; case BC_YUV411P: *sub_h = 4; *sub_v = 1; break; default: *sub_h = 1; *sub_v = 1; break; } }/* * Return the bits of a colormodel. This is used only internally * and returns the sum of the bits of all components. Downsampling isn't * taken into account here, YUV 420 has 24 bits. We need to test this, * because e.g. RGBA8888 -> RGBA16161616 cost extra. */static int colormodel_get_bits(int colormodel) { switch(colormodel) { case BC_RGB565: case BC_BGR565: return 16; case BC_BGR888: case BC_BGR8888: case BC_RGB888: case BC_YUV422: case BC_YUV420P: case BC_YUV422P: case BC_YUV444P: case BC_YUVJ420P: case BC_YUVJ422P: case BC_YUVJ444P: case BC_YUV411P: return 24; case BC_RGBA8888: case BC_YUVA8888: return 32; case BC_RGB161616: case BC_YUV422P16: case BC_YUV444P16: return 48; case BC_RGBA16161616: return 64; default: lqt_log(NULL, LQT_LOG_WARNING, LOG_DOMAIN, "Unknown colormodel (%d)\n",colormodel); return 0; } }/* * Get the "Price" of a colormodel conversion */static int get_conversion_price(int in_colormodel, int out_colormodel) { int input_is_rgb = lqt_colormodel_is_rgb(in_colormodel); int output_is_rgb = lqt_colormodel_is_rgb(out_colormodel); int input_is_yuv = lqt_colormodel_is_yuv(in_colormodel); int output_is_yuv = lqt_colormodel_is_yuv(out_colormodel); int input_has_alpha = lqt_colormodel_has_alpha(in_colormodel); int output_has_alpha = lqt_colormodel_has_alpha(out_colormodel); /* Zero conversions are for free :-) */ if(in_colormodel == out_colormodel) return 0; /* * Don't know what to do here. It can happen for very few * colormodels which aren't supported by any codecs. */ if(!input_is_rgb && !input_is_yuv) { lqt_log(NULL, LQT_LOG_WARNING, LOG_DOMAIN, "Input colorspace is neither RGB nor YUV, can't predict conversion price"); return 7; } if(!output_is_rgb && !output_is_yuv) { lqt_log(NULL, LQT_LOG_WARNING, LOG_DOMAIN, "Output colorspace is neither RGB nor YUV, can't predict conversion price"); return 7; } /* * Adding or removing the alpha channel means losing information or * adding unneccesary information -> too bad */ if(input_has_alpha != output_has_alpha) return 6; /* * YUV <-> RGB conversion costs 4-5 */ if((input_is_yuv && output_is_rgb) || (input_is_rgb && output_is_yuv)) { /* Added check to make sure that staying on the same bit depth is considered as "better" when doing a colorspace conversion. */ if(colormodel_get_bits(in_colormodel) != colormodel_get_bits(out_colormodel)) /* With bit conversion: 5 */ return 5; else /* No bit conversion is better: 4 */ return 4; } /* * Alpha blending is a bit more simple */ if((input_is_yuv && output_is_rgb) || (input_is_rgb && output_is_yuv)) return 3; /* Bit with conversion costs 2 */ if(colormodel_get_bits(in_colormodel) != colormodel_get_bits(out_colormodel)) return 2; /* Reordering of components is cheapest */ return 1; }int lqt_get_decoder_colormodel(quicktime_t * file, int track) { return file->vtracks[track].stream_cmodel; }static intlqt_get_best_colormodel_decode(quicktime_t * file, int track, int * supported) { int ret = LQT_COLORMODEL_NONE; int index; int best_conversion_price; int conversion_price; int decoder_colormodel = LQT_COLORMODEL_NONE; decoder_colormodel = lqt_get_decoder_colormodel(file, track); /* Check, if the decoder colormodel is directly supported */ if(decoder_colormodel != LQT_COLORMODEL_NONE) { index = 0; while(supported[index] != LQT_COLORMODEL_NONE) { if(decoder_colormodel == supported[index]) { ret = supported[index]; break; } else index++; } } else ret = BC_RGB888; if(ret == LQT_COLORMODEL_NONE) { index = 0; best_conversion_price = 10; while(supported[index] != LQT_COLORMODEL_NONE) { if(quicktime_reads_cmodel(file, supported[index], track)) { conversion_price = get_conversion_price(decoder_colormodel, supported[index]); if(conversion_price < best_conversion_price) { best_conversion_price = conversion_price; ret = supported[index]; } } index++; } } if(ret == LQT_COLORMODEL_NONE) ret = BC_RGB888; return ret; }static intlqt_get_best_colormodel_encode(quicktime_t * file, int track, int * supported) { int index_supported; int conversion_price = 0, best_conversion_price = 10; int ret = LQT_COLORMODEL_NONE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?