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

📄 sdl_yuv_sw.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                                    int rows, int cols, int mod ){    unsigned int* row = (unsigned int*) out;    const int next_row = cols*2+mod;    int x, y;    int cr_r;    int crb_g;    int cb_b;    int cols_2 = cols / 2;    mod+=mod;    y = rows;    while( y-- )    {        x = cols_2;        while( x-- )        {            register int L;            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]                               + colortab[ *cb + 2*256 ];            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];            cr += 4; cb += 4;            L = *lum; lum += 2;            row[0] = row[1] = row[next_row] = row[next_row+1] =                                       (rgb_2_pix[ L + cr_r ] |                                        rgb_2_pix[ L + crb_g ] |                                        rgb_2_pix[ L + cb_b ]);            row += 2;            L = *lum; lum += 2;            row[0] = row[1] = row[next_row] = row[next_row+1] =                                       (rgb_2_pix[ L + cr_r ] |                                        rgb_2_pix[ L + crb_g ] |                                        rgb_2_pix[ L + cb_b ]);            row += 2;        }        row += next_row;    }}/* * How many 1 bits are there in the Uint32. * Low performance, do not call often. */static int number_of_bits_set( Uint32 a ){    if(!a) return 0;    if(a & 1) return 1 + number_of_bits_set(a >> 1);    return(number_of_bits_set(a >> 1));}/* * How many 0 bits are there at least significant end of Uint32. * Low performance, do not call often. */static int free_bits_at_bottom( Uint32 a ){      /* assume char is 8 bits */    if(!a) return sizeof(Uint32) * 8;    if(((Sint32)a) & 1l) return 0;    return 1 + free_bits_at_bottom ( a >> 1);}SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display){	SDL_Overlay *overlay;	struct private_yuvhwdata *swdata;	int *Cr_r_tab;	int *Cr_g_tab;	int *Cb_g_tab;	int *Cb_b_tab;	Uint32 *r_2_pix_alloc;	Uint32 *g_2_pix_alloc;	Uint32 *b_2_pix_alloc;	int i, cpu_mmx;	int CR, CB;	Uint32 Rmask, Gmask, Bmask;	/* Only RGB packed pixel conversion supported */	if ( (display->format->BytesPerPixel != 2) &&	     (display->format->BytesPerPixel != 3) &&	     (display->format->BytesPerPixel != 4) ) {		SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces");		return(NULL);	}	/* Verify that we support the format */	switch (format) {	    case SDL_YV12_OVERLAY:	    case SDL_IYUV_OVERLAY:	    case SDL_YUY2_OVERLAY:	    case SDL_UYVY_OVERLAY:	    case SDL_YVYU_OVERLAY:		break;	    default:		SDL_SetError("Unsupported YUV format");		return(NULL);	}	/* Create the overlay structure */	overlay = (SDL_Overlay *)malloc(sizeof *overlay);	if ( overlay == NULL ) {		SDL_OutOfMemory();		return(NULL);	}	memset(overlay, 0, (sizeof *overlay));	/* Fill in the basic members */	overlay->format = format;	overlay->w = width;	overlay->h = height;	/* Set up the YUV surface function structure */	overlay->hwfuncs = &sw_yuvfuncs;	/* Create the pixel data and lookup tables */	swdata = (struct private_yuvhwdata *)malloc(sizeof *swdata);	overlay->hwdata = swdata;	if ( swdata == NULL ) {		SDL_OutOfMemory();		SDL_FreeYUVOverlay(overlay);		return(NULL);	}	swdata->stretch = NULL;	swdata->display = display;	swdata->pixels = (Uint8 *) malloc(width*height*2);	swdata->colortab = (int *)malloc(4*256*sizeof(int));	Cr_r_tab = &swdata->colortab[0*256];	Cr_g_tab = &swdata->colortab[1*256];	Cb_g_tab = &swdata->colortab[2*256];	Cb_b_tab = &swdata->colortab[3*256];	swdata->rgb_2_pix = (Uint32 *)malloc(3*768*sizeof(Uint32));	r_2_pix_alloc = &swdata->rgb_2_pix[0*768];	g_2_pix_alloc = &swdata->rgb_2_pix[1*768];	b_2_pix_alloc = &swdata->rgb_2_pix[2*768];	if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) {		SDL_OutOfMemory();		SDL_FreeYUVOverlay(overlay);		return(NULL);	}	/* Generate the tables for the display surface */	for (i=0; i<256; i++) {		/* Gamma correction (luminescence table) and chroma correction		   would be done here.  See the Berkeley mpeg_play sources.		*/		CB = CR = (i-128);		Cr_r_tab[i] = (int) ( (0.419/0.299) * CR);		Cr_g_tab[i] = (int) (-(0.299/0.419) * CR);		Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); 		Cb_b_tab[i] = (int) ( (0.587/0.331) * CB);	}	/* 	 * Set up entries 0-255 in rgb-to-pixel value tables.	 */	Rmask = display->format->Rmask;	Gmask = display->format->Gmask;	Bmask = display->format->Bmask;	for ( i=0; i<256; ++i ) {		r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask));		r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask);		g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask));		g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask);		b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask));		b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask);	}	/*	 * If we have 16-bit output depth, then we double the value	 * in the top word. This means that we can write out both	 * pixels in the pixel doubling mode with one op. It is 	 * harmless in the normal case as storing a 32-bit value	 * through a short pointer will lose the top bits anyway.	 */	if( display->format->BytesPerPixel == 2 ) {		for ( i=0; i<256; ++i ) {			r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16;			g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16;			b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16;		}	}	/*	 * Spread out the values we have to the rest of the array so that	 * we do not need to check for overflow.	 */	for ( i=0; i<256; ++i ) {		r_2_pix_alloc[i] = r_2_pix_alloc[256];		r_2_pix_alloc[i+512] = r_2_pix_alloc[511];		g_2_pix_alloc[i] = g_2_pix_alloc[256];		g_2_pix_alloc[i+512] = g_2_pix_alloc[511];		b_2_pix_alloc[i] = b_2_pix_alloc[256];		b_2_pix_alloc[i+512] = b_2_pix_alloc[511];	}	/* You have chosen wisely... */	switch (format) {	    case SDL_YV12_OVERLAY:	    case SDL_IYUV_OVERLAY:		cpu_mmx = CPU_Flags() & MMX_CPU;		if ( display->format->BytesPerPixel == 2 ) {#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)			/* inline assembly functions */			if ( cpu_mmx && (Rmask == 0xF800) &&			                (Gmask == 0x07E0) &&				        (Bmask == 0x001F) &&			                (width & 15) == 0) {/*printf("Using MMX 16-bit 565 dither\n");*/				swdata->Display1X = Color565DitherYV12MMX1X;			} else {/*printf("Using C 16-bit dither\n");*/				swdata->Display1X = Color16DitherYV12Mod1X;			}#else			swdata->Display1X = Color16DitherYV12Mod1X;#endif			swdata->Display2X = Color16DitherYV12Mod2X;		}		if ( display->format->BytesPerPixel == 3 ) {			swdata->Display1X = Color24DitherYV12Mod1X;			swdata->Display2X = Color24DitherYV12Mod2X;		}		if ( display->format->BytesPerPixel == 4 ) {#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)			/* inline assembly functions */			if ( cpu_mmx && (Rmask == 0x00FF0000) &&			                (Gmask == 0x0000FF00) &&				        (Bmask == 0x000000FF) && 			                (width & 15) == 0) {/*printf("Using MMX 32-bit dither\n");*/				swdata->Display1X = ColorRGBDitherYV12MMX1X;			} else {/*printf("Using C 32-bit dither\n");*/				swdata->Display1X = Color32DitherYV12Mod1X;			}#else			swdata->Display1X = Color32DitherYV12Mod1X;#endif			swdata->Display2X = Color32DitherYV12Mod2X;		}		break;	    case SDL_YUY2_OVERLAY:	    case SDL_UYVY_OVERLAY:	    case SDL_YVYU_OVERLAY:		if ( display->format->BytesPerPixel == 2 ) {			swdata->Display1X = Color16DitherYUY2Mod1X;			swdata->Display2X = Color16DitherYUY2Mod2X;		}		if ( display->format->BytesPerPixel == 3 ) {			swdata->Display1X = Color24DitherYUY2Mod1X;			swdata->Display2X = Color24DitherYUY2Mod2X;		}		if ( display->format->BytesPerPixel == 4 ) {			swdata->Display1X = Color32DitherYUY2Mod1X;			swdata->Display2X = Color32DitherYUY2Mod2X;		}		break;	    default:		/* We should never get here (caught above) */		break;	}	/* Find the pitch and offset values for the overlay */	overlay->pitches = swdata->pitches;	overlay->pixels = swdata->planes;	switch (format) {	    case SDL_YV12_OVERLAY:	    case SDL_IYUV_OVERLAY:		overlay->pitches[0] = overlay->w;		overlay->pitches[1] = overlay->pitches[0] / 2;		overlay->pitches[2] = overlay->pitches[0] / 2;	        overlay->pixels[0] = swdata->pixels;	        overlay->pixels[1] = overlay->pixels[0] +		                     overlay->pitches[0] * overlay->h;	        overlay->pixels[2] = overlay->pixels[1] +		                     overlay->pitches[1] * overlay->h / 2;		overlay->planes = 3;		break;	    case SDL_YUY2_OVERLAY:	    case SDL_UYVY_OVERLAY:	    case SDL_YVYU_OVERLAY:		overlay->pitches[0] = overlay->w*2;	        overlay->pixels[0] = swdata->pixels;		overlay->planes = 1;		break;	    default:		/* We should never get here (caught above) */		break;	}	/* We're all done.. */	return(overlay);}int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay){	return(0);}void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay){	return;}int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect){	struct private_yuvhwdata *swdata;	SDL_Surface *stretch;	SDL_Surface *display;	int scale_2x;	Uint8 *lum, *Cr, *Cb;	Uint8 *dst;	int mod;	swdata = overlay->hwdata;	scale_2x = 0;	stretch = 0;	if ( (overlay->w != dstrect->w) || (overlay->h != dstrect->h) ) {		if ( (dstrect->w == 2*overlay->w) &&		     (dstrect->h == 2*overlay->h) ) {			scale_2x = 1;		} else {			if ( ! swdata->stretch ) {				display = swdata->display;				swdata->stretch = SDL_CreateRGBSurface(					SDL_SWSURFACE,					overlay->w, overlay->h,					display->format->BitsPerPixel,					display->format->Rmask,					display->format->Gmask,					display->format->Bmask, 0);				if ( ! swdata->stretch ) {					return(-1);				}			}			stretch = swdata->stretch;		}	}	if ( stretch ) {		display = stretch;	} else {		display = swdata->display;	}	switch (overlay->format) {	    case SDL_YV12_OVERLAY:		lum = overlay->pixels[0];		Cr =  overlay->pixels[1];		Cb =  overlay->pixels[2];		break;	    case SDL_IYUV_OVERLAY:		lum = overlay->pixels[0];		Cr =  overlay->pixels[2];		Cb =  overlay->pixels[1];		break;	    case SDL_YUY2_OVERLAY:		lum = overlay->pixels[0];		Cr = lum + 3;		Cb = lum + 1;		break;	    case SDL_UYVY_OVERLAY:		lum = overlay->pixels[0]+1;		Cr = lum + 1;		Cb = lum - 1;		break;	    case SDL_YVYU_OVERLAY:		lum = overlay->pixels[0];		Cr = lum + 1;		Cb = lum + 3;		break;	    default:		SDL_SetError("Unsupported YUV format in blit");		return(-1);	}	if ( SDL_MUSTLOCK(display) ) {        	if ( SDL_LockSurface(display) < 0 ) {			return(-1);		}	}	if ( stretch ) {		dst = (Uint8 *)stretch->pixels;	} else {		dst = (Uint8 *)display->pixels			+ dstrect->x * display->format->BytesPerPixel			+ dstrect->y * display->pitch;	}	mod = (display->pitch / display->format->BytesPerPixel);	if ( scale_2x ) {		mod -= (overlay->w * 2);		swdata->Display2X(swdata->colortab, swdata->rgb_2_pix,		                  lum, Cr, Cb, dst, overlay->h, overlay->w,mod);	} else {		mod -= overlay->w;		swdata->Display1X(swdata->colortab, swdata->rgb_2_pix,		                  lum, Cr, Cb, dst, overlay->h, overlay->w,mod);	}	if ( SDL_MUSTLOCK(display) ) {		SDL_UnlockSurface(display);	}	if ( stretch ) {		display = swdata->display;		SDL_SoftStretch(stretch, NULL, display, dstrect);	}	SDL_UpdateRects(display, 1, dstrect);	return(0);}void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay){	struct private_yuvhwdata *swdata;	swdata = overlay->hwdata;	if ( swdata ) {		if ( swdata->stretch ) {			SDL_FreeSurface(swdata->stretch);		}		if ( swdata->pixels ) {			free(swdata->pixels);		}		if ( swdata->colortab ) {			free(swdata->colortab);		}		if ( swdata->rgb_2_pix ) {			free(swdata->rgb_2_pix);		}		free(swdata);	}}

⌨️ 快捷键说明

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