X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fvmem.c;h=7ca5e4b9532074c5e803b8bfcce154837a832e2d;hb=2a100fcd186304e600d6d896325855836fa899e6;hp=57e05303e5c39c35cc1954f9fc5d846b9a269571;hpb=24cddfa0efa80557f538d6dbf08f9b0b4b4d52a4;p=vlc diff --git a/modules/video_output/vmem.c b/modules/video_output/vmem.c index 57e05303e5..7ca5e4b953 100644 --- a/modules/video_output/vmem.c +++ b/modules/video_output/vmem.c @@ -29,283 +29,279 @@ # include "config.h" #endif +#include + #include #include -#include - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int Create ( vlc_object_t * ); -static void Destroy ( vlc_object_t * ); - -static int Init ( vout_thread_t * ); -static void End ( vout_thread_t * ); -static int LockPicture ( vout_thread_t *, picture_t * ); -static int UnlockPicture ( vout_thread_t *, picture_t * ); +#include +#include /***************************************************************************** * Module descriptor *****************************************************************************/ -#define T_WIDTH N_( "Width" ) -#define LT_WIDTH N_( "Video memory buffer width." ) +#define T_WIDTH N_("Width") +#define LT_WIDTH N_("Video memory buffer width.") -#define T_HEIGHT N_( "Height" ) -#define LT_HEIGHT N_( "Video memory buffer height." ) +#define T_HEIGHT N_("Height") +#define LT_HEIGHT N_("Video memory buffer height.") -#define T_PITCH N_( "Pitch" ) -#define LT_PITCH N_( "Video memory buffer pitch in bytes." ) +#define T_PITCH N_("Pitch") +#define LT_PITCH N_("Video memory buffer pitch in bytes.") -#define T_CHROMA N_( "Chroma" ) -#define LT_CHROMA N_( "Output chroma for the memory image as a 4-character " \ - "string, eg. \"RV32\"." ) +#define T_CHROMA N_("Chroma") +#define LT_CHROMA N_("Output chroma for the memory image as a 4-character " \ + "string, eg. \"RV32\".") -#define T_LOCK N_( "Lock function" ) -#define LT_LOCK N_( "Address of the locking callback function. This " \ - "function must fill in valid plane memory address " \ - "information for use by the video renderer." ) +static int Open (vlc_object_t *); +static void Close(vlc_object_t *); -#define T_UNLOCK N_( "Unlock function" ) -#define LT_UNLOCK N_( "Address of the unlocking callback function" ) +vlc_module_begin() + set_description(N_("Video memory output")) + set_shortname(N_("Video memory")) -#define T_DATA N_( "Callback data" ) -#define LT_DATA N_( "Data for the locking and unlocking functions" ) + set_category(CAT_VIDEO) + set_subcategory(SUBCAT_VIDEO_VOUT) + set_capability("vout display", 0) -vlc_module_begin () - set_description( N_( "Video memory output" ) ) - set_shortname( N_("Video memory") ) + add_integer("vmem-width", 320, NULL, T_WIDTH, LT_WIDTH, false) + change_private() + add_integer("vmem-height", 200, NULL, T_HEIGHT, LT_HEIGHT, false) + change_private() + add_integer("vmem-pitch", 640, NULL, T_PITCH, LT_PITCH, false) + change_private() + add_string("vmem-chroma", "RV16", NULL, T_CHROMA, LT_CHROMA, true) + change_private() + add_obsolete_string("vmem-lock") /* obsoleted since 1.1.1 */ + add_obsolete_string("vmem-unlock") /* obsoleted since 1.1.1 */ + add_obsolete_string("vmem-data") /* obsoleted since 1.1.1 */ - set_category( CAT_VIDEO ) - set_subcategory( SUBCAT_VIDEO_VOUT ) - set_capability( "video output", 0 ) - - add_integer( "vmem-width", 320, NULL, T_WIDTH, LT_WIDTH, false ) - add_integer( "vmem-height", 200, NULL, T_HEIGHT, LT_HEIGHT, false ) - add_integer( "vmem-pitch", 640, NULL, T_PITCH, LT_PITCH, false ) - add_string( "vmem-chroma", "RV16", NULL, T_CHROMA, LT_CHROMA, true ) - add_string( "vmem-lock", "0", NULL, T_LOCK, LT_LOCK, true ) - add_string( "vmem-unlock", "0", NULL, T_UNLOCK, LT_UNLOCK, true ) - add_string( "vmem-data", "0", NULL, T_DATA, LT_DATA, true ) - - set_callbacks( Create, Destroy ) -vlc_module_end () + set_callbacks(Open, Close) +vlc_module_end() /***************************************************************************** - * vout_sys_t: video output descriptor + * Local prototypes *****************************************************************************/ -struct vout_sys_t -{ - int i_width, i_height, i_pitch; - - void (*pf_lock) (void *, void **); - void (*pf_unlock) (void *); - void *p_data; +struct picture_sys_t { + vout_display_sys_t *sys; + void *id; }; -/***************************************************************************** - * Create: allocates video thread - ***************************************************************************** - * This function allocates and initializes a vout method. - *****************************************************************************/ -static int Create( vlc_object_t *p_this ) -{ - vout_thread_t *p_vout = ( vout_thread_t * )p_this; - - /* Allocate instance and initialize some members */ - p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); - if( ! p_vout->p_sys ) - return VLC_ENOMEM; +struct vout_display_sys_t { + picture_pool_t *pool; + void *(*lock)(void *sys, void **plane); + void (*unlock)(void *sys, void *id, void *const *plane); + void (*display)(void *sys, void *id); + void *opaque; +}; - p_vout->pf_init = Init; - p_vout->pf_end = End; - p_vout->pf_manage = NULL; - p_vout->pf_render = NULL; - p_vout->pf_display = NULL; +static picture_pool_t *Pool (vout_display_t *, unsigned); +static void Display(vout_display_t *, picture_t *); +static int Control(vout_display_t *, int, va_list); +static void Manage (vout_display_t *); - return VLC_SUCCESS; -} +static int Lock(picture_t *); +static void Unlock(picture_t *); /***************************************************************************** - * Init: initialize video thread + * Open: allocates video thread + ***************************************************************************** + * This function allocates and initializes a vout method. *****************************************************************************/ -static int Init( vout_thread_t *p_vout ) +static int Open(vlc_object_t *object) { - int i_index; - picture_t *p_pic; - char *psz_chroma, *psz_tmp; - int i_width, i_height, i_pitch; - vlc_fourcc_t i_chroma; - - i_width = var_CreateGetInteger( p_vout, "vmem-width" ); - i_height = var_CreateGetInteger( p_vout, "vmem-height" ); - i_pitch = var_CreateGetInteger( p_vout, "vmem-pitch" ); - - psz_chroma = var_CreateGetString( p_vout, "vmem-chroma" ); - if( !psz_chroma ) - { - msg_Err( p_vout, "Cannot find chroma information." ); - return VLC_EGENERIC; - } - - i_chroma = vlc_fourcc_GetCodecFromString( VIDEO_ES, psz_chroma ); - free( psz_chroma ); - - if( !i_chroma ) - { - msg_Err( p_vout, "vmem-chroma should be 4 characters long" ); - return VLC_EGENERIC; - } - - psz_tmp = var_CreateGetString( p_vout, "vmem-lock" ); - p_vout->p_sys->pf_lock = (void (*) (void *, void **))(intptr_t)atoll( psz_tmp ); - free( psz_tmp ); - - psz_tmp = var_CreateGetString( p_vout, "vmem-unlock" ); - p_vout->p_sys->pf_unlock = (void (*) (void *))(intptr_t)atoll( psz_tmp ); - free( psz_tmp ); - - psz_tmp = var_CreateGetString( p_vout, "vmem-data" ); - p_vout->p_sys->p_data = (void *)(intptr_t)atoll( psz_tmp ); - free( psz_tmp ); - - if( !p_vout->p_sys->pf_lock || !p_vout->p_sys->pf_unlock ) - { - msg_Err( p_vout, "Invalid lock or unlock callbacks" ); + vout_display_t *vd = (vout_display_t *)object; + + /* */ + char *chroma_format = var_InheritString(vd, "vmem-chroma"); + const vlc_fourcc_t chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma_format); + free(chroma_format); + if (!chroma) { + msg_Err(vd, "vmem-chroma should be 4 characters long"); return VLC_EGENERIC; } - I_OUTPUTPICTURES = 0; + /* */ + video_format_t fmt = vd->fmt; - /* Initialize the output structure */ - p_vout->output.i_chroma = i_chroma; - p_vout->output.pf_setpalette = NULL; - p_vout->output.i_width = i_width; - p_vout->output.i_height = i_height; - p_vout->output.i_aspect = p_vout->output.i_width - * VOUT_ASPECT_FACTOR / p_vout->output.i_height; + fmt.i_chroma = chroma; + fmt.i_width = var_InheritInteger(vd, "vmem-width"); + fmt.i_height = var_InheritInteger(vd, "vmem-height"); /* Define the bitmasks */ - switch( i_chroma ) + switch (chroma) { - case VLC_CODEC_RGB15: - p_vout->output.i_rmask = 0x001f; - p_vout->output.i_gmask = 0x03e0; - p_vout->output.i_bmask = 0x7c00; + case VLC_CODEC_RGB15: + fmt.i_rmask = 0x001f; + fmt.i_gmask = 0x03e0; + fmt.i_bmask = 0x7c00; break; - - case VLC_CODEC_RGB16: - p_vout->output.i_rmask = 0x001f; - p_vout->output.i_gmask = 0x07e0; - p_vout->output.i_bmask = 0xf800; + case VLC_CODEC_RGB16: + fmt.i_rmask = 0x001f; + fmt.i_gmask = 0x07e0; + fmt.i_bmask = 0xf800; break; - - case VLC_CODEC_RGB24: - p_vout->output.i_rmask = 0xff0000; - p_vout->output.i_gmask = 0x00ff00; - p_vout->output.i_bmask = 0x0000ff; + case VLC_CODEC_RGB24: + fmt.i_rmask = 0xff0000; + fmt.i_gmask = 0x00ff00; + fmt.i_bmask = 0x0000ff; break; - - case VLC_CODEC_RGB32: - p_vout->output.i_rmask = 0xff0000; - p_vout->output.i_gmask = 0x00ff00; - p_vout->output.i_bmask = 0x0000ff; + case VLC_CODEC_RGB32: + fmt.i_rmask = 0xff0000; + fmt.i_gmask = 0x00ff00; + fmt.i_bmask = 0x0000ff; + break; + default: + fmt.i_rmask = 0; + fmt.i_gmask = 0; + fmt.i_bmask = 0; break; } - /* Try to initialize 1 direct buffer */ - p_pic = NULL; + /* */ + vout_display_sys_t *sys; + vd->sys = sys = calloc(1, sizeof(*sys)); + if (unlikely(!sys)) + return VLC_ENOMEM; - /* Find an empty picture slot */ - for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) - { - if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) - { - p_pic = p_vout->p_picture + i_index; - break; - } + sys->lock = var_InheritAddress(vd, "vmem-lock"); + if (sys->lock == NULL) { + msg_Err(vd, "Invalid lock callback"); + free(sys); + return VLC_EGENERIC; } - - /* Allocate the picture */ - if( p_pic == NULL ) - { - return VLC_SUCCESS; + sys->unlock = var_InheritAddress(vd, "vmem-unlock"); + sys->display = var_InheritAddress(vd, "vmem-display"); + sys->opaque = var_InheritAddress(vd, "vmem-data"); + + /* */ + const int pitch = var_InheritInteger(vd, "vmem-pitch"); + picture_resource_t rsc; + rsc.p_sys = malloc(sizeof(*rsc.p_sys)); + if(unlikely(!rsc.p_sys)) { + free(sys); + return VLC_ENOMEM; + } + rsc.p_sys->sys = sys; + rsc.p_sys->id = NULL; + for (int i = 0; i < PICTURE_PLANE_MAX; i++) { + /* vmem-lock is responsible for the allocation */ + rsc.p[i].p_pixels = NULL; + rsc.p[i].i_lines = fmt.i_height; + rsc.p[i].i_pitch = pitch; + } + picture_t *picture = picture_NewFromResource(&fmt, &rsc); + if (!picture) { + free(rsc.p_sys); + free(sys); + return VLC_EGENERIC; } - if( picture_Setup( p_pic, p_vout->output.i_chroma, - p_vout->output.i_width, p_vout->output.i_height, - p_vout->output.i_aspect ) ) - { - free( p_pic ); + /* */ + picture_pool_configuration_t pool; + memset(&pool, 0, sizeof(pool)); + pool.picture_count = 1; + pool.picture = &picture; + pool.lock = Lock; + pool.unlock = Unlock; + sys->pool = picture_pool_NewExtended(&pool); + if (!sys->pool) { + picture_Release(picture); + free(sys); return VLC_EGENERIC; } - p_pic->p->i_pitch = i_pitch; + /* */ + vout_display_info_t info = vd->info; + info.has_hide_mouse = true; + + /* */ + vd->fmt = fmt; + vd->info = info; + vd->pool = Pool; + vd->prepare = NULL; + vd->display = Display; + vd->control = Control; + vd->manage = Manage; + + /* */ + vout_display_SendEventFullscreen(vd, false); + vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, false); + return VLC_SUCCESS; +} - p_pic->pf_lock = LockPicture; - p_pic->pf_unlock = UnlockPicture; +static void Close(vlc_object_t *object) +{ + vout_display_t *vd = (vout_display_t *)object; + vout_display_sys_t *sys = vd->sys; - p_pic->i_status = DESTROYED_PICTURE; - p_pic->i_type = DIRECT_PICTURE; + picture_pool_Delete(sys->pool); + free(sys); +} - PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; +/* */ +static picture_pool_t *Pool(vout_display_t *vd, unsigned count) +{ + VLC_UNUSED(count); + return vd->sys->pool; +} - I_OUTPUTPICTURES++; +static void Display(vout_display_t *vd, picture_t *picture) +{ + vout_display_sys_t *sys = vd->sys; - return VLC_SUCCESS; + assert(!picture_IsReferenced(picture)); + if (sys->display != NULL) + sys->display(sys->opaque, picture->p_sys->id); + picture_Release(picture); } -/***************************************************************************** - * End: terminate video thread output method - *****************************************************************************/ -static void End( vout_thread_t *p_vout ) +static int Control(vout_display_t *vd, int query, va_list args) { - (void)p_vout; + switch (query) { + case VOUT_DISPLAY_CHANGE_FULLSCREEN: + case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: { + const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *); + if (cfg->display.width != vd->fmt.i_width || + cfg->display.height != vd->fmt.i_height) + return VLC_EGENERIC; + if (cfg->is_fullscreen) + return VLC_EGENERIC; + return VLC_SUCCESS; + } + default: + return VLC_EGENERIC; + } } - -/***************************************************************************** - * Destroy: destroy video thread - ***************************************************************************** - * Terminate an output method created by Create - *****************************************************************************/ -static void Destroy( vlc_object_t *p_this ) +static void Manage(vout_display_t *vd) { - vout_thread_t *p_vout = ( vout_thread_t * )p_this; - - /* Destroy structure */ - free( p_vout->p_sys ); + VLC_UNUSED(vd); } -/***************************************************************************** - * LockPicture: lock a picture - ***************************************************************************** - * This function locks the picture and prepares it for direct pixel access. - *****************************************************************************/ -static int LockPicture( vout_thread_t *p_vout, picture_t *p_pic ) +/* */ +static int Lock(picture_t *picture) { - int i_index; - void *planes[p_pic->i_planes]; + picture_sys_t *picsys = picture->p_sys; + vout_display_sys_t *sys = picsys->sys; + void *planes[PICTURE_PLANE_MAX]; - p_vout->p_sys->pf_lock( p_vout->p_sys->p_data, planes ); + picsys->id = sys->lock(sys->opaque, planes); - for( i_index = 0; i_index < p_pic->i_planes; i_index++ ) - { - p_pic->p[i_index].p_pixels = planes[i_index]; - } + for (int i = 0; i < picture->i_planes; i++) + picture->p[i].p_pixels = planes[i]; return VLC_SUCCESS; } -/***************************************************************************** - * UnlockPicture: unlock a picture - ***************************************************************************** - * This function unlocks a previously locked picture. - *****************************************************************************/ -static int UnlockPicture( vout_thread_t *p_vout, picture_t *p_pic ) +static void Unlock(picture_t *picture) { - p_vout->p_sys->pf_unlock( p_vout->p_sys->p_data ); + picture_sys_t *picsys = picture->p_sys; + vout_display_sys_t *sys = picsys->sys; - (void)p_pic; + void *planes[PICTURE_PLANE_MAX]; - return VLC_SUCCESS; -} + for (int i = 0; i < picture->i_planes; i++) + planes[i] = picture->p[i].p_pixels; + if (sys->unlock != NULL) + sys->unlock(sys->opaque, picsys->id, planes); +}