X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fvmem.c;h=ede49a4fde5e80d0b01e2838abe0440d67f34a0c;hb=9d4515ac4873076af85af33270d126818c0e8639;hp=135a0f94bc0a9efa92650080cb4aa86112f34a57;hpb=4d9bf01bb1bad90a28100e2a80bb1482b0997a54;p=vlc diff --git a/modules/video_output/vmem.c b/modules/video_output/vmem.c index 135a0f94bc..ede49a4fde 100644 --- a/modules/video_output/vmem.c +++ b/modules/video_output/vmem.c @@ -2,7 +2,7 @@ * vmem.c: memory video driver for vlc ***************************************************************************** * Copyright (C) 2008 the VideoLAN team - * $Id$ + * Copyrgiht (C) 2010 Rémi Denis-Courmont * * Authors: Sam Hocevar * @@ -52,10 +52,6 @@ #define LT_CHROMA N_("Output chroma for the memory image as a 4-character " \ "string, eg. \"RV32\".") -#define T_RATIO N_("Preserve aspect ratio") -#define LT_RATIO N_("Preserve original video image aspect ratio when " \ - "rendering to the given video memory buffer.") - static int Open (vlc_object_t *); static void Close(vlc_object_t *); @@ -75,7 +71,6 @@ vlc_module_begin() change_private() add_string("vmem-chroma", "RV16", T_CHROMA, LT_CHROMA, true) change_private() - add_bool("vmem-preserve-aspect-ratio", true, T_RATIO, LT_RATIO, true) 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 */ @@ -88,25 +83,30 @@ vlc_module_end() *****************************************************************************/ struct picture_sys_t { vout_display_sys_t *sys; - void *original_planes[PICTURE_PLANE_MAX]; /** planes sent by the client */ void *id; }; +/* NOTE: the callback prototypes must match those of LibVLC */ struct vout_display_sys_t { picture_pool_t *pool; - vout_display_place_t place; - int vmem_pitch; - int vmem_width; + unsigned count; + + void *opaque; void *(*lock)(void *sys, void **plane); void (*unlock)(void *sys, void *id, void *const *plane); void (*display)(void *sys, void *id); - void *opaque; + void (*cleanup)(void *sys); + + unsigned pitches[PICTURE_PLANE_MAX]; + unsigned lines[PICTURE_PLANE_MAX]; }; +typedef unsigned (*vlc_format_cb)(void **, char *, unsigned *, unsigned *, + unsigned *, unsigned *); + static picture_pool_t *Pool (vout_display_t *, unsigned); -static void Display(vout_display_t *, picture_t *); +static void Display(vout_display_t *, picture_t *, subpicture_t *); static int Control(vout_display_t *, int, va_list); -static void Manage (vout_display_t *); static int Lock(picture_t *); static void Unlock(picture_t *); @@ -119,25 +119,71 @@ static void Unlock(picture_t *); static int Open(vlc_object_t *object) { vout_display_t *vd = (vout_display_t *)object; + vout_display_sys_t *sys = malloc(sizeof(*sys)); + if (unlikely(!sys)) + return VLC_ENOMEM; - /* */ - 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"); + /* Get the callbacks */ + vlc_format_cb setup = var_InheritAddress(vd, "vmem-setup"); + + sys->lock = var_InheritAddress(vd, "vmem-lock"); + if (sys->lock == NULL) { + msg_Err(vd, "missing lock callback"); + free(sys); return VLC_EGENERIC; } + sys->unlock = var_InheritAddress(vd, "vmem-unlock"); + sys->display = var_InheritAddress(vd, "vmem-display"); + sys->cleanup = var_InheritAddress(vd, "vmem-cleanup"); + sys->opaque = var_InheritAddress(vd, "vmem-data"); + sys->pool = NULL; - /* */ + /* Define the video format */ video_format_t fmt = vd->fmt; - fmt.i_chroma = chroma; - fmt.i_width = var_InheritInteger(vd, "vmem-width"); - fmt.i_height = var_InheritInteger(vd, "vmem-height"); + if (setup != NULL) { + char chroma[5]; + + memcpy(chroma, &fmt.i_chroma, 4); + chroma[4] = '\0'; + memset(sys->pitches, 0, sizeof(sys->pitches)); + memset(sys->lines, 0, sizeof(sys->lines)); + + sys->count = setup(&sys->opaque, chroma, &fmt.i_width, &fmt.i_height, + sys->pitches, sys->lines); + if (sys->count == 0) { + msg_Err(vd, "video format setup failure (no pictures)"); + free(sys); + return VLC_EGENERIC; + } + fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); + + } else { + char *chroma = var_InheritString(vd, "vmem-chroma"); + fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); + free(chroma); + + fmt.i_width = var_InheritInteger(vd, "vmem-width"); + fmt.i_height = var_InheritInteger(vd, "vmem-height"); + sys->pitches[0] = var_InheritInteger(vd, "vmem-pitch"); + sys->lines[0] = fmt.i_height; + for (size_t i = 1; i < PICTURE_PLANE_MAX; i++) + { + sys->pitches[i] = sys->pitches[0]; + sys->lines[i] = sys->lines[0]; + } + sys->count = 1; + sys->cleanup = NULL; + } + + if (!fmt.i_chroma) { + msg_Err(vd, "vmem-chroma should be 4 characters long"); + free(sys); + return VLC_EGENERIC; + } /* Define the bitmasks */ - switch (chroma) + switch (fmt.i_chroma) { case VLC_CODEC_RGB15: fmt.i_rmask = 0x001f; @@ -150,10 +196,6 @@ static int Open(vlc_object_t *object) fmt.i_bmask = 0xf800; break; case VLC_CODEC_RGB24: - fmt.i_rmask = 0xff0000; - fmt.i_gmask = 0x00ff00; - fmt.i_bmask = 0x0000ff; - break; case VLC_CODEC_RGB32: fmt.i_rmask = 0xff0000; fmt.i_gmask = 0x00ff00; @@ -166,90 +208,19 @@ static int Open(vlc_object_t *object) break; } - /* */ - vout_display_sys_t *sys; - vd->sys = sys = calloc(1, sizeof(*sys)); - if (unlikely(!sys)) - return VLC_ENOMEM; - - sys->lock = var_InheritAddress(vd, "vmem-lock"); - if (sys->lock == NULL) { - msg_Err(vd, "Invalid lock callback"); - free(sys); - return VLC_EGENERIC; - } - sys->unlock = var_InheritAddress(vd, "vmem-unlock"); - sys->display = var_InheritAddress(vd, "vmem-display"); - sys->opaque = var_InheritAddress(vd, "vmem-data"); - - sys->vmem_width = fmt.i_width; - - const bool keep_ratio = var_InheritBool(vd, "vmem-preserve-aspect-ratio"); - if (keep_ratio) { - /* place the picture */ - vout_display_cfg_t place_cfg = *vd->cfg; - place_cfg.display.width = fmt.i_width; - place_cfg.display.height = fmt.i_height; - vout_display_PlacePicture(&sys->place, &vd->source, &place_cfg, false); - - - /* Request a slightly different picture */ - fmt.i_width = vd->sys->place.width; - fmt.i_height = vd->sys->place.height; - } else { - sys->place.width = fmt.i_width; - sys->place.height = fmt.i_height; - } - - /* */ - sys->vmem_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 = sys->place.height; - rsc.p[i].i_pitch = sys->vmem_pitch; - } - picture_t *picture = picture_NewFromResource(&fmt, &rsc); - if (!picture) { - free(rsc.p_sys); - free(sys); - return VLC_EGENERIC; - } - - /* */ - 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; - } - /* */ vout_display_info_t info = vd->info; info.has_hide_mouse = true; /* */ + vd->sys = sys; vd->fmt = fmt; vd->info = info; vd->pool = Pool; vd->prepare = NULL; vd->display = Display; vd->control = Control; - vd->manage = Manage; + vd->manage = NULL; /* */ vout_display_SendEventFullscreen(vd, false); @@ -262,6 +233,8 @@ static void Close(vlc_object_t *object) vout_display_t *vd = (vout_display_t *)object; vout_display_sys_t *sys = vd->sys; + if (sys->cleanup) + sys->cleanup(sys->opaque); picture_pool_Delete(sys->pool); free(sys); } @@ -269,11 +242,60 @@ static void Close(vlc_object_t *object) /* */ static picture_pool_t *Pool(vout_display_t *vd, unsigned count) { - VLC_UNUSED(count); - return vd->sys->pool; + vout_display_sys_t *sys = vd->sys; + + if (sys->pool) + return sys->pool; + + if (count > sys->count) + count = sys->count; + + picture_t *pictures[count]; + + for (unsigned i = 0; i < count; i++) { + picture_resource_t rsc; + + rsc.p_sys = malloc(sizeof(*rsc.p_sys)); + if (unlikely(!rsc.p_sys)) { + count = i; + break; + } + + rsc.p_sys->sys = sys; + rsc.p_sys->id = NULL; + + for (unsigned 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 = sys->lines[i]; + rsc.p[i].i_pitch = sys->pitches[i]; + } + + pictures[i] = picture_NewFromResource(&vd->fmt, &rsc); + if (!pictures[i]) { + free(rsc.p_sys); + count = i; + break; + } + } + + /* */ + picture_pool_configuration_t pool; + memset(&pool, 0, sizeof(pool)); + pool.picture_count = count; + pool.picture = pictures; + pool.lock = Lock; + pool.unlock = Unlock; + sys->pool = picture_pool_NewExtended(&pool); + if (!sys->pool) { + for (unsigned i = 0; i < count; i++) + picture_Release(pictures[i]); + } + + return sys->pool; } -static void Display(vout_display_t *vd, picture_t *picture) +static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; @@ -281,6 +303,7 @@ static void Display(vout_display_t *vd, picture_t *picture) if (sys->display != NULL) sys->display(sys->opaque, picture->p_sys->id); picture_Release(picture); + VLC_UNUSED(subpicture); } static int Control(vout_display_t *vd, int query, va_list args) @@ -294,17 +317,12 @@ static int Control(vout_display_t *vd, int query, va_list args) return VLC_EGENERIC; if (cfg->is_fullscreen) return VLC_EGENERIC; - return VLC_SUCCESS; } default: return VLC_EGENERIC; } } -static void Manage(vout_display_t *vd) -{ - VLC_UNUSED(vd); -} /* */ static int Lock(picture_t *picture) @@ -315,17 +333,8 @@ static int Lock(picture_t *picture) picsys->id = sys->lock(sys->opaque, planes); - const int y = sys->place.y; - const int x = sys->place.x; - const int pitch = sys->vmem_pitch; - const int bbp = pitch / sys->vmem_width; - - for (int i = 0; i < picture->i_planes; i++) { - uint8_t *p = planes[i]; - picsys->original_planes[i] = p; - picture->p[i].p_pixels = p + x * bbp + y * pitch; - picture->p[i].i_lines = sys->place.height; - } + for (int i = 0; i < picture->i_planes; i++) + picture->p[i].p_pixels = planes[i]; return VLC_SUCCESS; } @@ -338,7 +347,7 @@ static void Unlock(picture_t *picture) void *planes[PICTURE_PLANE_MAX]; for (int i = 0; i < picture->i_planes; i++) - planes[i] = picsys->original_planes[i]; + planes[i] = picture->p[i].p_pixels; if (sys->unlock != NULL) sys->unlock(sys->opaque, picsys->id, planes);