📄 xvmc.c
字号:
/***************************************************************************** * xvmc.c : XVMC plugin for vlc ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN * $Id$ * * Authors: Shane Harper <shanegh@optusnet.com.au> * Vincent Seguin <seguin@via.ecp.fr> * Samuel Hocevar <sam@zoy.org> * David Kennedy <dkennedy@tinytoad.com> * Jean-Paul Saman <jpsaman _at_ videolan _dot_ org> * * 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 *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_interface.h>#include <vlc_vout.h>#include <vlc_keys.h>#ifdef HAVE_MACHINE_PARAM_H /* BSD */# include <machine/param.h># include <sys/types.h> /* typedef ushort */# include <sys/ipc.h>#endif#ifndef WIN32# include <netinet/in.h> /* BSD: struct in_addr */#endif#ifdef HAVE_SYS_SHM_H# include <sys/shm.h> /* shmget(), shmctl() */#endif#include <X11/Xlib.h>#include <X11/Xmd.h>#include <X11/Xutil.h>#include <X11/keysym.h>#ifdef HAVE_SYS_SHM_H# include <X11/extensions/XShm.h>#endif#ifdef DPMSINFO_IN_DPMS_H# include <X11/extensions/dpms.h>#endif#include <X11/extensions/Xv.h>#include <X11/extensions/Xvlib.h>#include <X11/extensions/vldXvMC.h>#include "../../codec/xvmc/accel_xvmc.h"#include "xcommon.h"#include "../../codec/spudec/spudec.h"#include <unistd.h>/* picture structure */#define TOP_FIELD 1#define BOTTOM_FIELD 2#define FRAME_PICTURE 3/* picture coding type */#define I_TYPE 1#define P_TYPE 2#define B_TYPE 3#define D_TYPE 4/***************************************************************************** * Exported prototypes *****************************************************************************/extern int Activate ( vlc_object_t * );extern void Deactivate ( vlc_object_t * );/***************************************************************************** * Module descriptor *****************************************************************************/#define ADAPTOR_TEXT N_("XVMC adaptor number")#define ADAPTOR_LONGTEXT N_( \ "If you graphics card provides several adaptors, this option allows you " \ "to choose which one will be used (you shouldn't have to change this).")#define ALT_FS_TEXT N_("Alternate fullscreen method")#define ALT_FS_LONGTEXT N_( \ "There are two ways to make a fullscreen window, unfortunately each one " \ "has its drawbacks.\n" \ "1) Let the window manager handle your fullscreen window (default), but " \ "things like taskbars will likely show on top of the video.\n" \ "2) Completely bypass the window manager, but then nothing will be able " \ "to show on top of the video.")#define DISPLAY_TEXT N_("X11 display name")#define DISPLAY_LONGTEXT N_( \ "Specify the X11 hardware display you want to use. By default VLC will " \ "use the value of the DISPLAY environment variable.")#define CHROMA_TEXT N_("XVimage chroma format")#define CHROMA_LONGTEXT N_( \ "Force the XVideo renderer to use a specific chroma format instead of " \ "trying to improve performances by using the most efficient one.")#define SHM_TEXT N_("Use shared memory")#define SHM_LONGTEXT N_( \ "Use shared memory to communicate between VLC and the X server.")#define SCREEN_TEXT N_("Screen to be used for fullscreen mode.")#define SCREEN_LONGTEXT N_( \ "Choose the screen you want to use in fullscreen mode. For instance " \ "set it to 0 for first screen, 1 for the second.")#define MODE_TEXT N_("Deinterlace mode")#define MODE_LONGTEXT N_("You can choose the default deinterlace mode")#define CROP_TEXT N_("Crop")#define CROP_LONGTEXT N_("You can choose the crop style to apply.")vlc_module_begin(); set_shortname( "XVMC" ); add_string( "xvmc-display", NULL, NULL, DISPLAY_TEXT, DISPLAY_LONGTEXT, true ); add_integer( "xvmc-adaptor", -1, NULL, ADAPTOR_TEXT, ADAPTOR_LONGTEXT, true ); add_bool( "xvmc-altfullscreen", 0, NULL, ALT_FS_TEXT, ALT_FS_LONGTEXT, true ); add_string( "xvmc-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true );#ifdef HAVE_SYS_SHM_H add_bool( "xvmc-shm", 1, NULL, SHM_TEXT, SHM_LONGTEXT, true );#endif#ifdef HAVE_XINERAMA add_integer ( "xvmc-xineramascreen", 0, NULL, SCREEN_TEXT, SCREEN_LONGTEXT, true );#endif add_string( "xvmc-deinterlace-mode", "bob", NULL, MODE_TEXT, MODE_LONGTEXT, false ); add_string( "xvmc-crop-style", "eq", NULL, CROP_TEXT, CROP_LONGTEXT, false ); set_description( N_("XVMC extension video output") ); set_capability( "video output", 10 ); set_callbacks( Activate, Deactivate );vlc_module_end();/* following functions are local */static const unsigned accel_priority[] = { VLC_XVMC_ACCEL_VLD,};#define NUM_ACCEL_PRIORITY (sizeof(accel_priority)/sizeof(accel_priority[0]))/* * Additional thread safety, since the plugin may decide to destroy a context * while it's surfaces are still active in the video-out loop. * When / If XvMC libs are reasonably thread-safe, the locks can be made * more efficient by allowing multiple threads in that do not destroy * the context or surfaces that may be active in other threads. */static void init_context_lock( context_lock_t *c ){ pthread_cond_init(&c->cond,NULL); pthread_mutex_init(&c->mutex,NULL); c->num_readers = 0;}void free_context_lock( context_lock_t *c ){ pthread_mutex_destroy(&c->mutex); pthread_cond_destroy(&c->cond);}void xvmc_context_reader_lock( context_lock_t *c ){ pthread_mutex_lock(&c->mutex); c->num_readers++; pthread_mutex_unlock(&c->mutex);}void xvmc_context_reader_unlock( context_lock_t *c ){ pthread_mutex_lock(&c->mutex); if (c->num_readers > 0) { if (--(c->num_readers) == 0) { pthread_cond_broadcast(&c->cond); } } pthread_mutex_unlock(&c->mutex);}void xvmc_context_writer_lock( context_lock_t *c ){ pthread_mutex_lock(&c->mutex); while(c->num_readers) { pthread_cond_wait( &c->cond, &c->mutex ); }}void xvmc_context_writer_unlock( context_lock_t *c ){ pthread_mutex_unlock( &c->mutex );}void clear_xx44_palette( xx44_palette_t *p ){ int i; uint32_t *cluts = p->cluts; int *ids = p->lookup_cache; i= p->size; while(i--) *cluts++ = 0; i = 2*OVL_PALETTE_SIZE; while(i--) *ids++ = -1; p->max_used=1;}static void init_xx44_palette( xx44_palette_t *p, unsigned num_entries ){ p->size = (num_entries > XX44_PALETTE_SIZE) ? XX44_PALETTE_SIZE : num_entries;}static void dispose_xx44_palette(xx44_palette_t *p){ /* Nothing to do */}static void colorToPalette( const uint32_t *icolor, unsigned char *palette_p, unsigned num_xvmc_components, char *xvmc_components ){ const clut_t *color = (const clut_t *) icolor; unsigned int i; for (i=0; i<num_xvmc_components; ++i) { switch(xvmc_components[i]) { case 'V': *palette_p = color->cr; break; case 'U': *palette_p = color->cb; break; case 'Y': default: *palette_p = color->y; break; } *palette_p++; }}void xx44_to_xvmc_palette( const xx44_palette_t *p,unsigned char *xvmc_palette, unsigned first_xx44_entry, unsigned num_xx44_entries, unsigned num_xvmc_components, char *xvmc_components ){ unsigned int i; const uint32_t *cluts = p->cluts + first_xx44_entry; for( i=0; i<num_xx44_entries; ++i ) { if( (cluts - p->cluts) < p->size ) { colorToPalette( cluts++, xvmc_palette, num_xvmc_components, xvmc_components ); xvmc_palette += num_xvmc_components; } }}static int xx44_paletteIndex( xx44_palette_t *p, int color, uint32_t clut ){ unsigned int i; uint32_t *cluts = p->cluts; int tmp; if( (tmp = p->lookup_cache[color]) >= 0 ) { if (cluts[tmp] == clut) return tmp; } for (i=0; i<p->max_used; ++i) { if (*cluts++ == clut) { p->lookup_cache[color] = i; return p->lookup_cache[color]; } } if( p->max_used == (p->size -1) ) { //printf("video_out: Warning! Out of xx44 palette colors!\n"); return 1; } p->cluts[p->max_used] = clut; p->lookup_cache[color] = p->max_used++; return p->lookup_cache[color];}static void memblend_xx44( uint8_t *mem, uint8_t val, size_t size, uint8_t mask ){ uint8_t masked_val = val & mask;/* size_t is unsigned, therefore always positive if (size < 0) return;*/ while(size--) { if( (*mem & mask) <= masked_val ) *mem = val; mem++; }}void blend_xx44( uint8_t *dst_img, subpicture_t *sub_img, int dst_width, int dst_height, int dst_pitch, xx44_palette_t *palette, int ia44 ){ int src_width; int src_height; int mask; int x_off; int y_off; int x, y; uint8_t norm_pixel,clip_pixel; uint8_t *dst_y; uint8_t *dst; uint8_t alphamask; int clip_right; int i_len, i_color; uint16_t *p_source = NULL;#if 0 if (!sub_img) return; src_width = sub_img->i_width; src_height = sub_img->i_height; x_off = sub_img->i_x; y_off = sub_img->i_y; alphamask = (ia44) ? 0x0F : 0xF0; p_source = (uint16_t *)sub_img->p_sys->p_data; dst_y = dst_img + dst_pitch*y_off + x_off; if( (x_off + sub_img->i_width) <= dst_width ) clip_right = sub_img->i_width; else clip_right = dst_width - x_off; if ((src_height + y_off) > dst_height) src_height = dst_height - y_off; for (y = 0; y < src_height; y++) { mask = !( (y < sub_img->p_sys->i_y_start) || (y >= sub_img->p_sys->i_y_end) ); dst = dst_y;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -