📄 .#video_yuv.c.1.33
字号:
/***************************************************************************** * video_yuv.c: YUV transformation functions * Provides functions to perform the YUV conversion. The functions provided here * are a complete and portable C implementation, and may be replaced in certain * case by optimized functions. ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN * * Authors: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include "defs.h"#include <math.h> /* exp(), pow() */#include <errno.h> /* ENOMEM */#include <stdlib.h> /* free() */#include <string.h> /* strerror() */#include "config.h"#include "common.h"#include "threads.h"#include "mtime.h"#include "plugins.h"#include "video.h"#include "video_output.h"#include "video_yuv.h"#include "intf_msg.h"/***************************************************************************** * Constants *****************************************************************************//* Margins and offsets in conversion tables - Margins are used in case a RGB * RGB conversion would give a value outside the 0-255 range. Offsets have been * calculated to avoid using the same cache line for 2 tables. conversion tables * are 2*MARGIN + 256 long and stores pixels.*/#define RED_MARGIN 178#define GREEN_MARGIN 135#define BLUE_MARGIN 224#define RED_OFFSET 1501 /* 1323 to 1935 */#define GREEN_OFFSET 135 /* 0 to 526 */#define BLUE_OFFSET 818 /* 594 to 1298 */#define RGB_TABLE_SIZE 1935 /* total table size */#define GRAY_MARGIN 384#define GRAY_TABLE_SIZE 1024 /* total table size */#define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table *//* macros used for YUV pixel conversions */#define SHIFT 20#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))#define MMX#ifdef MMX/* hope these constant values are cache line aligned */static unsigned long long mmx_80w = 0x0080008000800080;static unsigned long long mmx_10w = 0x1010101010101010;static unsigned long long mmx_00ffw = 0x00ff00ff00ff00ff;static unsigned long long mmx_Y_coeff = 0x253f253f253f253f;/* hope these constant values are cache line aligned */static unsigned long long mmx_U_green = 0xf37df37df37df37d;static unsigned long long mmx_U_blue = 0x4093409340934093;static unsigned long long mmx_V_red = 0x3312331233123312;static unsigned long long mmx_V_green = 0xe5fce5fce5fce5fc;/* hope these constant values are cache line aligned */static unsigned long long mmx_redmask = 0xf8f8f8f8f8f8f8f8;static unsigned long long mmx_grnmask = 0xfcfcfcfcfcfcfcfc;static unsigned long long mmx_grnshift = 0x03;static unsigned long long mmx_blueshift = 0x03;#endif/***************************************************************************** * Local prototypes *****************************************************************************/static void SetGammaTable ( int *pi_table, double f_gamma );static void SetYUV ( vout_thread_t *p_vout );static void SetOffset ( int i_width, int i_height, int i_pic_width, int i_pic_height, boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset );static void ConvertY4Gray8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertY4Gray16 ( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertY4Gray24 ( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertY4Gray32 ( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV420RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV422RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV444RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width, int i_matrix_coefficients );/***************************************************************************** * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks ***************************************************************************** * These conversion routines are used by YUV conversion functions. * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer, * which is also modified. *****************************************************************************/#define CONVERT_Y_PIXEL( BPP ) \ /* Only Y sample is present */ \ p_ybase = p_yuv + *p_y++; \ *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \ p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \ + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];#define CONVERT_YUV_PIXEL( BPP ) \ /* Y, U and V samples are present */ \ i_uval = *p_u++; \ i_vval = *p_v++; \ i_red = (V_RED_COEF * i_vval) >> SHIFT; \ i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \ i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \ CONVERT_Y_PIXEL( BPP ) \/***************************************************************************** * CONVERT_4YUV_PIXELS, CONVERT_4YUV_PIXELS_SCALE: dither 4 pixels in 8 bpp ***************************************************************************** * These macros dither 4 pixels in 8 bpp, with or without horiz. scaling *****************************************************************************/#define CONVERT_4YUV_PIXELS( CHROMA ) \ *p_pic++ = p_lookup[ \ (((*p_y++ + dither10[i_real_y]) >> 4) << 7) \ + ((*p_u + dither20[i_real_y]) >> 5) * 9 \ + ((*p_v + dither20[i_real_y]) >> 5) ]; \ *p_pic++ = p_lookup[ \ (((*p_y++ + dither11[i_real_y]) >> 4) << 7) \ + ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \ + ((*p_v++ + dither21[i_real_y]) >> 5) ]; \ *p_pic++ = p_lookup[ \ (((*p_y++ + dither12[i_real_y]) >> 4) << 7) \ + ((*p_u + dither22[i_real_y]) >> 5) * 9 \ + ((*p_v + dither22[i_real_y]) >> 5) ]; \ *p_pic++ = p_lookup[ \ (((*p_y++ + dither13[i_real_y]) >> 4) << 7) \ + ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \ + ((*p_v++ + dither23[i_real_y]) >> 5) ]; \#define CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \ *p_pic++ = p_lookup[ \ (((*p_y + dither10[i_real_y]) >> 4) << 7) \ + ((*p_u + dither20[i_real_y]) >> 5) * 9 \ + ((*p_v + dither20[i_real_y]) >> 5) ]; \ b_jump_uv += *p_offset; \ p_y += *p_offset; \ p_u += *p_offset & b_jump_uv; \ p_v += *p_offset++ & b_jump_uv; \ *p_pic++ = p_lookup[ \ (((*p_y + dither11[i_real_y]) >> 4) << 7) \ + ((*p_u + dither21[i_real_y]) >> 5) * 9 \ + ((*p_v + dither21[i_real_y]) >> 5) ]; \ b_jump_uv += *p_offset; \ p_y += *p_offset; \ p_u += *p_offset & b_jump_uv; \ p_v += *p_offset++ & b_jump_uv; \ *p_pic++ = p_lookup[ \ (((*p_y + dither12[i_real_y]) >> 4) << 7) \ + ((*p_u + dither22[i_real_y]) >> 5) * 9 \ + ((*p_v + dither22[i_real_y]) >> 5) ]; \ b_jump_uv += *p_offset; \ p_y += *p_offset; \ p_u += *p_offset & b_jump_uv; \ p_v += *p_offset++ & b_jump_uv; \ *p_pic++ = p_lookup[ \ (((*p_y + dither13[i_real_y]) >> 4) << 7) \ + ((*p_u + dither23[i_real_y]) >> 5) * 9 \ + ((*p_v + dither23[i_real_y]) >> 5) ]; \ b_jump_uv += *p_offset; \ p_y += *p_offset; \ p_u += *p_offset & b_jump_uv; \ p_v += *p_offset++ & b_jump_uv; \/***************************************************************************** * SCALE_WIDTH: scale a line horizontally ***************************************************************************** * This macro scales a line using rendering buffer and offset array. It works * for 1, 2 and 4 Bpp. *****************************************************************************/#define SCALE_WIDTH \ if( b_horizontal_scaling ) \ { \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -