⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_out_rgb.c

📁 最新osg包
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2000-2003 the xine project and Claudio "KLaN" Ciccani * * This file is part of xine, a free video player. * * xine 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. * * xine 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-1307, USA * * * video_out_rgb.c, general purpose rgb video output xine driver *			by Claudio "KLaN" Ciccani <klan82@cheapnet.it> * * ...someway based on video_ou_xshm.c * * * NOTE: this driver is not able to display videos itself; *       however it can be used in every graphics environment *       and not only for playback (either video processing, *       frame dumping ... what you want) * * *  TODO: a good scaling function, hue, saturation, *        contrast, applying effects and many more *        (eg. SSE2 support, if someone buy me a new procesor). * */#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <pthread.h>#include <fcntl.h>#include <unistd.h>#include "xine.h"#include "xine/xine_internal.h"#include "xine/xineutils.h"#include "xine/video_out.h"#include "video_out_rgb.h"#define THIS  "video_out_rgb"static int s_debugMessages = 0; #define EVAL(exp) \{\	if(!(exp))\	{\		fprintf(stderr, THIS ": <\"" #exp "\"> evaluation failed !!\n");\		fflush(stderr);\		goto FAILURE;\	}\}#define CHECK(exp) \{\	if(!(exp))\	{\		fprintf(stderr, THIS ": <\"" #exp "\"> check failed !!\n");\		fflush(stderr);\	}\}#define release(ptr) \{\	if(ptr) free(ptr);\	ptr = NULL;\}#ifdef __cplusplusextern "C" {#endifstatic inline voidclear(void* dest, uint32_t size){#ifdef COMPILE_ASSEMBLY	__asm__ __volatile__(		"xorl %%eax, %%eax\n\t"		"movl %1, %%ecx\n\t"		"rep; stosl\n\t"		"movl %2, %%ecx\n\t"		"rep; stosb\n\t"				: "=&D" (dest)		: "r" (size >> 2), "r" (size & 3), "0" (dest)		: "eax", "ecx");#endif}#ifdef DEBUGstatic inline uint64_t rdtsc(){	uint64_t t;		__asm__ __volatile__(		".byte 0x0f, 0x31\n\t"		: "=A" (t));		return(t);}#endif /* DEBUG *//* * I'm using this formula for colorspace conversion: * *	R = Y + (1.420705 * U) *	G = Y - (0.698001 * U) - (0.337633 * V) *	B = Y + (1.732446 * V) * * First YUV chunks are converted and put into a * rgb_planar_t structure, then packed into the * specified RGB pixel format. * I'm using this method because I need RGB levels to * be separated for effects stuff (currently only * selecting levels). * *//* floating point factors; used by 3DNow and SSE */static const float fp_factors[] ={        1.420705, 1.420705,        0.698001, 0.698001,        0.337633, 0.337633,        1.732446, 1.732446};/* used by MMX; * each factor is multiplied by 2^14 and rounded */static const int16_t wd_factors[] ={	0x4000,  23277, 0x4000,  23277,	0x4000,  28384, 0x4000,  28384,	 11436,   5532,  11436,   5532};/* used by normal C function; * each factor is multiplied by 2^16 and rounded */static const int32_t dw_factors[] ={	 93107,	 45744,	 22127,	113538,};/* used by 3DNow for rounding values */static const float round[] ={	0.555555,	0.555555};static const uint32_t lsub[] ={	128, 128};static const uint32_t lmask[] ={	0xff, 0xff};static const uint16_t wmask[] ={	0xff, 0xff,	0xff, 0xff};#ifdef COMPILE_ASSEMBLYstatic void__3dnow_convert_yuy2(uint8_t* yuv[], rgb_planar_t* rgb,			 uint32_t pitches[], uint32_t width, uint32_t height){	uint8_t* yuv_data = yuv[0];	uint8_t* r_buffer = rgb->r;	uint8_t* g_buffer = rgb->g;	uint8_t* b_buffer = rgb->b;	uint32_t samples = (width * height) >> 2; /* 4 pixels at once */	__asm__ __volatile__("femms\n\t");	while(samples--)	{		__asm__ __volatile__(			"prefetch 192(%0)\n\t"			"movq (%0), %%mm1\n\t" /* mm1 = [v2 y3 u2 y2 v0 y1 u0 y0] */			"movq %%mm1, %%mm3\n\t" /* mm3 = [v2 y3 u2 y2 v0 y1 u0 y0] */			"pand (%1), %%mm3\n\t" /*  mm3 = [0 y3 0 y2 0 y1 0 y0] */			"movq %%mm1, %%mm2\n\t" /* mm2 = [v2 y3 u2 y2 v0 y1 u0 y0] */			"psrld $8, %%mm2\n\t" /* mm2 = [0 v2 y3 u2 0 v0 y1 u0] */			"pand (%2), %%mm2\n\t" /* mm2 = [0 0 0 u2 0 0 0 u0] */			"psubd (%3), %%mm2\n\t" /* mm2 = [u2 - 128 | u2 - 128] */			"pi2fd %%mm2, %%mm2\n\t"			"psrld $24, %%mm1\n\t" /* mm1 = [0 0 0 v2 0 0 0 v0] */			"psubd (%3), %%mm1\n\t" /* mm1 = [v2 - 128 | v0 - 128] */			"pi2fd %%mm1, %%mm1\n\t"			"addl $8, %0\n\t"			: "=&r" (yuv_data)			: "r" (wmask), "r" (lmask), "r" (lsub), "0" (yuv_data)			: "memory");		__asm__ __volatile__(			"prefetchw 320(%0)\n\t"			"movq %%mm1, %%mm0\n\t" /* mm0 = [v2 | v0] */			"pfmul (%3), %%mm0\n\t" /* mm0 = [v2 * 1.420705 | v0 * 1.420705] */			"pfadd (%4), %%mm0\n\t" /* rounded */			"pf2id %%mm0, %%mm0\n\t"			"packssdw %%mm0, %%mm0\n\t" /* mm0 = [v2 * 1.420705 | v0 * 1.420705 | ...] */			"punpckhwd %%mm0, %%mm0\n\t" /* mm0 = [v2 * 1.420705 | v2 * 1.420705 |							 	v0 * 1.420705 | v0 * 1.420705] */			"paddw %%mm3, %%mm0\n\t" /* mm0 = [0 r3 0 r2 0 r1 0 r0] */			"packuswb %%mm0, %%mm0\n\t" /* mm0 = [r3 r2 r1 r0 r3 r2 r1 r0] */			"movd %%mm0, (%0)\n\t"			"prefetchw 320(%2)\n\t"			"movq %%mm2, %%mm0\n\t" /* mm0 = [u2 | u0] */			"pfmul 24(%3), %%mm0\n\t" /* mm0 = [u2 * 1.732446 | u0 * 1.732446] */			"pfadd (%4), %%mm0\n\t" /* rounded */			"pf2id %%mm0, %%mm0\n\t"			"packssdw %%mm0, %%mm0\n\t" /* mm0 = [u2 * 1.732446 | u0 * 1.732446 | ...] */			"punpckhwd %%mm0, %%mm0\n\t" /* mm0 = [u2 * 1.732446 | u2 * 1.732446 |								u0 * 1.732446 | u0 * 1.732446] */			"paddw %%mm3, %%mm0\n\t" /* mm0 = [0 b3 0 b2 0 b1 0 b0] */			"packuswb %%mm0, %%mm0\n\t" /* mm0 = [b3 b2 b1 b0 b3 b2 b1 b0] */			"movd %%mm0, (%2)\n\t"			"prefetchw 320(%1)\n\t"			"pfmul 8(%3), %%mm1\n\t" /* mm1 = [v2 * 0.698001 | v0 * 0.698001] */			"pfmul 16(%3), %%mm2\n\t" /* mm2 = [u2 * 0.337633 | u0 * 0.337633] */			"pfadd %%mm1, %%mm2\n\t" /* mm2 = [(v2 * 0.698001) + (u2 * 0.337633) | ...] */			"pfadd (%4), %%mm2\n\t" /* rounded */			"pf2id %%mm2, %%mm2\n\t"			"packssdw %%mm2, %%mm2\n\t" /* mm2 = [(v2 * 0.698001) + (u2 * 0.337633) |								(v0 * 0.698001) + (u0 * 0.337633)| ...] */			"punpckhwd %%mm2, %%mm2\n\t" /* mm2 = [(v2 * 0.698001) + (u2 * 0.337633) |								(v2 * 0.698001) + (u2 * 0.337633)| ...] */			"psubw %%mm2, %%mm3\n\t" /* mm3 = [0 g3 0 g2 0 g1 0 g0] */			"packuswb %%mm3, %%mm3\n\t" /* mm3 = [g3 g2 g1 g0 g3 g2 g1 g0] */			"movd %%mm3, (%1)\n\t"			"addl $4, %0\n\t"			"addl $4, %1\n\t"			"addl $4, %2\n\t"			: "=&r" (r_buffer), "=&r" (g_buffer), "=&r" (b_buffer)			: "r" (fp_factors), "r" (round),			  "0" (r_buffer), "1" (g_buffer), "2" (b_buffer)			: "memory");	}	__asm__ __volatile__("femms\n\t");}static void__3dnow_convert_yv12(uint8_t* yuv[], rgb_planar_t* rgb,			 uint32_t pitches[], uint32_t width, uint32_t height){	uint8_t* y_data = yuv[0];	uint8_t* u_data = yuv[1];	uint8_t* v_data = yuv[2];	uint8_t* r_buffer = rgb->r;	uint8_t* g_buffer = rgb->g;	uint8_t* b_buffer = rgb->b;	uint32_t line_size = width >> 2; /* 4 pixels at once */	uint32_t samples   = line_size * (height >> 1);	__asm__ __volatile__(		"femms\n\t"		"pxor %%mm7, %%mm7\n\t"		::: "memory");	while(samples--)	{		__asm__ __volatile__(			"prefetch 192(%0)\n\t"			"prefetch 192(%1)\n\t"			"prefetch 192(%2)\n\t"			"prefetch 192(%3)\n\t"			"movd (%0), %%mm6\n\t" /* mm6 = [0 0 0 0 y03 y02 y01 y00] */			"movd (%1), %%mm5\n\t" /* mm5 = [0 0 0 0 y13 y12 y11 y10] */			"movd (%2), %%mm1\n\t" /* mm1 = [0 0 0 0 u12 u8 u4 u0] */			"movd (%3), %%mm0\n\t" /* mm0 = [0 0 0 0 v12 v8 v4 v0] */			"punpcklbw %%mm7, %%mm6\n\t" /* mm6 = [0 y03 0 y02 0 y01 0 y00] */			"punpcklbw %%mm7, %%mm5\n\t" /* mm5 = [0 y13 0 y12 0 y11 0 y10] */			"punpcklbw %%mm7, %%mm1\n\t" /* mm1 = [0 u12 0 u8 0 u4 0 u0] */			"punpcklwd %%mm7, %%mm1\n\t" /* mm1 = [0 0 0 u4 0 0 0 u0] */			"psubd (%4), %%mm1\n\t" /* mm1 = [u4 - 128 | u0 - 128] */			"pi2fd %%mm1, %%mm1\n\t"			"punpcklbw %%mm7, %%mm0\n\t" /* mm0 = [0 v12 0 v8 0 v4 0 v0] */			"punpcklwd %%mm7, %%mm0\n\t" /* mm0 = [0 0 0 v4 0 0 0 v0] */			"psubd (%4), %%mm0\n\t" /* mm0 = [v4 - 128 | v0 - 128] */			"pi2fd %%mm0, %%mm0\n\t"			:: "r" (y_data), "r" (y_data + pitches[0]),			   "r" (u_data), "r" (v_data), "r" (lsub)			: "memory");		__asm__ __volatile__(			"movq %%mm0, %%mm3\n\t" /* mm3 = [v4 | v0] */			"pfmul (%0), %%mm3\n\t" /* mm3 = [v4 * 1.420705 | v0 * 1.420705] */			"pfadd (%1), %%mm3\n\t" /* rounded */			"pf2id %%mm3, %%mm3\n\t"			"packssdw %%mm3, %%mm3\n\t" /* mm3 = [v4 * 1.420705 | v0 * 1.420705 | ...] */			"punpckhwd %%mm3, %%mm3\n\t" /* mm3 = [v4 * 1.420705 | v4 * 1.420705 |							 	v0 * 1.420705 | v0 * 1.420705] */			"movq %%mm1, %%mm2\n\t" /* mm2 = [u4 | u0] */			"pfmul 24(%0), %%mm2\n\t" /* mm2 = [u4 * 1.732446 | u0 * 1.732446] */			"pfadd (%1), %%mm2\n\t" /* rounded */			"pf2id %%mm2, %%mm2\n\t"			"packssdw %%mm2, %%mm2\n\t" /* mm2 = [u4 * 1.732446 | u0 * 1.732446 | ...] */			"punpckhwd %%mm2, %%mm2\n\t" /* mm2 = [u4 * 1.732446 | u4 * 1.732446 |								u0 * 1.732446 | u0 * 1.732446] */			"pfmul 8(%0), %%mm0\n\t" /* mm0 = [v4 * 0.698001 | v0 * 0.698001] */			"pfmul 16(%0), %%mm1\n\t" /* mm1 = [u4 * 0.337633 | u0 * 0.337633] */			"pfadd %%mm0, %%mm1\n\t" /* mm1 = [(v4 * 0.698001) + (u4 * 0.337633) | ...] */			"pfadd (%1), %%mm1\n\t" /* rounded */			"pf2id %%mm1, %%mm1\n\t"			"packssdw %%mm1, %%mm1\n\t" /* mm1 = [(v4 * 0.698001) + (u4 * 0.337633) |								(v0 * 0.698001) + (u0 * 0.337633)| ...] */			"punpckhwd %%mm1, %%mm1\n\t" /* mm1 = [(v4 * 0.698001) + (u4 * 0.337633) |								(v4 * 0.698001) + (u4 * 0.337633)| ...] */			:: "r" (fp_factors), "r" (round)			: "memory");		__asm__ __volatile__(			"prefetchw 320(%0)\n\t"			"movq %%mm6, %%mm0\n\t"			"paddw %%mm3, %%mm0\n\t" /* mm0 = [0 r03 0 r02 0 r01 0 r00] */			"packuswb %%mm0, %%mm0\n\t" /* mm0 = [r03 r02 r01 r00 r03 r02 r01 r00] */			"movd %%mm0, (%0)\n\t"			"paddw %%mm5, %%mm3\n\t" /* mm3 = [0 r13 0 r12 0 r11 0 r10] */			"packuswb %%mm3, %%mm3\n\t" /* mm3 = [r13 r12 r11 r10 r13 r12 r11 r10] */			"movd %%mm3, (%1)\n\t"			"addl $4, %0\n\t"			: "=&r" (r_buffer)			: "r" (r_buffer + width), "0" (r_buffer)			: "memory");		__asm__ __volatile__(			"prefetchw 320(%0)\n\t"			"movq %%mm6, %%mm0\n\t"			"paddw %%mm2, %%mm0\n\t" /* mm0 = [0 b03 0 b02 0 b01 0 b00] */			"packuswb %%mm0, %%mm0\n\t" /* mm0 = [b03 b02 b01 b00 b03 b02 b01 b00] */			"movd %%mm0, (%0)\n\t"			"paddw %%mm5, %%mm2\n\t" /* mm2 = [0 b13 0 b12 0 b11 0 b10] */			"packuswb %%mm2, %%mm2\n\t" /* mm2 = [b13 b12 b11 b10 b13 b12 b11 b10] */			"movd %%mm2, (%1)\n\t"			"addl $4, %0\n\t"			: "=&r" (b_buffer)			: "r" (b_buffer + width), "0" (b_buffer)			: "memory");		__asm__ __volatile__(			"prefetchw 320(%0)\n\t"			"psubw %%mm1, %%mm6\n\t" /* mm6 = [0 g03 0 g02 0 g01 0 g00] */			"packuswb %%mm6, %%mm6\n\t" /* mm6 = [g03 g02 g01 g00 g03 g02 g01 g00] */			"movd %%mm6, (%0)\n\t"			"psubw %%mm1, %%mm5\n\t" /* mm5 = [0 g13 0 g12 0 g11 0 g10] */			"packuswb %%mm5, %%mm5\n\t" /* mm5 = [g13 g12 g11 g10 g13 g12 g11 g10] */			"movd %%mm5, (%1)\n\t"			"addl $4, %0\n\t"			: "=&r" (g_buffer)			: "r" (g_buffer + width), "0" (g_buffer)			: "memory");		y_data += 4;		u_data += 2;		v_data += 2;		if(!(--line_size))		{			line_size = width >> 2;			y_data   += pitches[0];			r_buffer += width;			g_buffer += width;			b_buffer += width;		}	}	__asm__ __volatile__("femms\n\t");}/* packed floats operations are slower with SSE; * therefore I process only 2 pixels at once in both functions */static void__sse_convert_yuy2(uint8_t* yuv[], rgb_planar_t* rgb,			uint32_t pitches[], uint32_t width, uint32_t height){	uint8_t* yuv_data = yuv[0];	uint8_t* r_buffer = rgb->r;	uint8_t* g_buffer = rgb->g;	uint8_t* b_buffer = rgb->b;	uint32_t samples = (width * height) >> 1;	__asm__ __volatile__(		"pxor %%mm7, %%mm7\n\t"		"movss   (%0), %%xmm7\n\t"		"movss  8(%0), %%xmm6\n\t"		"movss 16(%0), %%xmm5\n\t"		"movss 24(%0), %%xmm4\n\t"		:: "r" (fp_factors)		: "memory");	while(samples--)	{		__asm__ __volatile__(			"prefetchnta 192(%0)\n\t"			"movd (%0), %%mm3\n\t" /* mm3 = [0 0 0 0 v0 y1 u0 y0] */			"punpcklwd %%mm7, %%mm3\n\t" /* mm3 = [0 0 v0 y1 0 0 u0 y0] */			"pand (%1), %%mm3\n\t" /* mm3 = [0 0 0 y1 0 0 0 y0] */			"movzbl 1(%0), %%eax\n\t" /* eax = u0 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -