示例#1
0
文件: evas.c 项目: chouquette/vlc
static void
FmtUpdate( vout_display_t *vd )
{
    vout_display_sys_t *sys = vd->sys;
    vout_display_place_t place;
    video_format_t src;

    vout_display_PlacePicture( &place, &vd->source, vd->cfg, false );

    if( sys->b_apply_rotation )
    {
        video_format_ApplyRotation( &src, &vd->source );
        vd->fmt.orientation = 0;
    }
    else
        src = vd->source;

    vd->fmt.i_width  = src.i_width  * place.width / src.i_visible_width;
    vd->fmt.i_height = src.i_height * place.height / src.i_visible_height;

    vd->fmt.i_visible_width  = place.width;
    vd->fmt.i_visible_height = place.height;
    vd->fmt.i_x_offset = src.i_x_offset * place.width / src.i_visible_width;
    vd->fmt.i_y_offset = src.i_y_offset * place.height / src.i_visible_height;

    sys->i_width  = vd->fmt.i_visible_width;
    sys->i_height = vd->fmt.i_visible_height;
}
示例#2
0
文件: x11.c 项目: maniacs-m/vlc
/**
 * Return a direct buffer
 */
static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
{
    vout_display_sys_t *sys = vd->sys;
    (void)requested_count;

    if (sys->pool)
        return sys->pool;

    vout_display_place_t place;

    vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);

    /* */
    const uint32_t values[] = { place.x, place.y, place.width, place.height };
    xcb_configure_window (sys->conn, sys->window,
                          XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
                          XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
                          values);

    picture_t *pic = picture_NewFromFormat (&vd->fmt);
    if (!pic)
        return NULL;

    assert (pic->i_planes == 1);

    picture_resource_t res = {
        .p = {
            [0] = {
                .i_lines = pic->p->i_lines,
                .i_pitch = pic->p->i_pitch,
            },
        },
    };
    picture_Release (pic);

    unsigned count;
    picture_t *pic_array[MAX_PICTURES];
    const size_t size = res.p->i_pitch * res.p->i_lines;
    for (count = 0; count < MAX_PICTURES; count++)
    {
        xcb_shm_seg_t seg = (sys->seg_base != 0) ? (sys->seg_base + count) : 0;

        if (XCB_picture_Alloc (vd, &res, size, sys->conn, seg))
            break;
        pic_array[count] = XCB_picture_NewFromResource (&vd->fmt, &res,
                                                        sys->conn);
        if (unlikely(pic_array[count] == NULL))
            break;
    }
    xcb_flush (sys->conn);

    if (count == 0)
        return NULL;

    sys->pool = picture_pool_New (count, pic_array);
    if (unlikely(sys->pool == NULL))
        while (count > 0)
            picture_Release(pic_array[--count]);
    return sys->pool;
}
示例#3
0
event_thread_t *EventThreadCreate( vout_display_t *vd)
{
     /* Create the Vout EventThread, this thread is created by us to isolate
     * the Win32 PeekMessage function calls. We want to do this because
     * Windows can stay blocked inside this call for a long time, and when
     * this happens it thus blocks vlc's video_output thread.
     * Vout EventThread will take care of the creation of the video
     * window (because PeekMessage has to be called from the same thread which
     * created the window). */
    msg_Dbg( vd, "creating Vout EventThread" );
    event_thread_t *p_event = malloc( sizeof(*p_event) );
    if( !p_event )
        return NULL;

    p_event->vd = vd;
    vlc_mutex_init( &p_event->lock );
    vlc_cond_init( &p_event->wait );

    p_event->is_cursor_hidden = false;
    p_event->button_pressed = 0;
    p_event->psz_title = NULL;
    p_event->source = vd->source;
    vout_display_PlacePicture(&p_event->place, &vd->source, vd->cfg, false);

    _snprintf( p_event->class_main, sizeof(p_event->class_main)/sizeof(*p_event->class_main),
               _T("VLC MSW %p"), p_event );
    _snprintf( p_event->class_video, sizeof(p_event->class_video)/sizeof(*p_event->class_video),
               _T("VLC MSW video %p"), p_event );
    return p_event;
}
示例#4
0
文件: evas.c 项目: chouquette/vlc
static int
Control( vout_display_t *vd, int i_query, va_list ap )
{
    vout_display_sys_t *sys = vd->sys;

    switch( i_query )
    {
    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
    {
        const video_format_t *p_source;
        vout_display_place_t place;
        video_format_t fmt;

        msg_Dbg( vd, "VOUT_DISPLAY_CHANGE_SOURCE_ASPECT" );

        p_source = va_arg( ap, const video_format_t * );

        video_format_ApplyRotation( &fmt, p_source );
        vout_display_PlacePicture( &place, &fmt, vd->cfg, false );

        if( place.width != (unsigned) sys->i_width
         && place.height != (unsigned) sys->i_height )
        {
            if( vd->info.has_pictures_invalid )
            {
                msg_Warn( vd, "ratio changed: invalidate pictures" );
                vout_display_SendEventPicturesInvalid( vd );
            }
            else
                return VLC_EGENERIC;
        }
        return VLC_SUCCESS;
    }
    case VOUT_DISPLAY_CHANGE_FULLSCREEN:
        return VLC_SUCCESS;
    case VOUT_DISPLAY_RESET_PICTURES:
        msg_Dbg( vd, "VOUT_DISPLAY_RESET_PICTURES" );

        EcoreMainLoopCallSync( vd, EvasResetMainloopCb );

        BuffersClean( vd );

        if( sys->p_pool )
        {
            picture_pool_Release( sys->p_pool );
            sys->p_pool = NULL;
        }
        return VLC_SUCCESS;
    case VOUT_DISPLAY_CHANGE_ZOOM:
    case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
    case VOUT_DISPLAY_HIDE_MOUSE:
        return VLC_EGENERIC;
    default:
        msg_Warn( vd, "Unknown request in evas_output" );
        return VLC_EGENERIC;
    }
}
示例#5
0
文件: x11.c 项目: paa/vlc
/**
 * Return a direct buffer
 */
static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
{
    vout_display_sys_t *p_sys = vd->sys;
    (void)requested_count;

    if (!p_sys->pool)
    {
        vout_display_place_t place;

        vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);

        /* */
        const uint32_t values[] = { place.x, place.y, place.width, place.height };
        xcb_configure_window (p_sys->conn, p_sys->window,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
                              XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
                              values);

        picture_t *pic = picture_NewFromFormat (&vd->fmt);
        if (!pic)
            return NULL;

        assert (pic->i_planes == 1);
        memset (p_sys->resource, 0, sizeof(p_sys->resource));

        unsigned count;
        picture_t *pic_array[MAX_PICTURES];
        for (count = 0; count < MAX_PICTURES; count++)
        {
            picture_resource_t *res = &p_sys->resource[count];

            res->p->i_lines = pic->p->i_lines;
            res->p->i_pitch = pic->p->i_pitch;
            if (PictureResourceAlloc (vd, res, res->p->i_pitch * res->p->i_lines,
                                      p_sys->conn, p_sys->shm))
                break;
            pic_array[count] = picture_NewFromResource (&vd->fmt, res);
            if (!pic_array[count])
            {
                PictureResourceFree (res, p_sys->conn);
                memset (res, 0, sizeof(*res));
                break;
            }
        }
        picture_Release (pic);

        if (count == 0)
            return NULL;

        p_sys->pool = picture_pool_New (count, pic_array);
        /* TODO release picture resources if NULL */
        xcb_flush (p_sys->conn);
    }

    return p_sys->pool;
}
示例#6
0
/**
 * Move or resize overlay surface on video display.
 *
 * This function is used to move or resize an overlay surface on the screen.
 * Ususally the overlay is moved by the user and thus, by a move or resize
 * event.
 */
static int DirectXUpdateOverlay(vout_display_t *vd, LPDIRECTDRAWSURFACE2 surface)
{
    vout_display_sys_t *sys = vd->sys;

    RECT src = sys->rect_src_clipped;
    RECT dst = sys->rect_dest_clipped;

    if (sys->use_wallpaper) {
        src.left   = vd->source.i_x_offset;
        src.top    = vd->source.i_y_offset;
        src.right  = vd->source.i_x_offset + vd->source.i_visible_width;
        src.bottom = vd->source.i_y_offset + vd->source.i_visible_height;
        AlignRect(&src, sys->i_align_src_boundary, sys->i_align_src_size);

        vout_display_cfg_t cfg = *vd->cfg;
        cfg.display.width  = sys->rect_display.right;
        cfg.display.height = sys->rect_display.bottom;

        vout_display_place_t place;
        vout_display_PlacePicture(&place, &vd->source, &cfg, true);

        dst.left   = sys->rect_display.left + place.x;
        dst.top    = sys->rect_display.top  + place.y;
        dst.right  = dst.left + place.width;
        dst.bottom = dst.top  + place.height;
        AlignRect(&dst, sys->i_align_dest_boundary, sys->i_align_dest_size);
    }

    if (!surface) {
        if (!sys->pool)
            return VLC_EGENERIC;
        surface = sys->resource.p_sys->front_surface;
    }

    /* The new window dimensions should already have been computed by the
     * caller of this function */

    /* Position and show the overlay */
    DDOVERLAYFX ddofx;
    ZeroMemory(&ddofx, sizeof(ddofx));
    ddofx.dwSize = sizeof(ddofx);
    ddofx.dckDestColorkey.dwColorSpaceLowValue = sys->i_colorkey;
    ddofx.dckDestColorkey.dwColorSpaceHighValue = sys->i_colorkey;

    HRESULT hr = IDirectDrawSurface2_UpdateOverlay(surface,
                 &src, sys->display, &dst,
                 DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE, &ddofx);
    sys->restore_overlay = hr != DD_OK;

    if (hr != DD_OK) {
        msg_Warn(vd, "DirectDrawUpdateOverlay cannot move/resize overlay");
        return VLC_EGENERIC;
    }
    return VLC_SUCCESS;
}
示例#7
0
文件: events.c 项目: FLYKingdom/vlc
static void HandleMotionNotify (vout_display_t *vd,
                                xcb_motion_notify_event_t *ev)
{
    vout_display_place_t place;

    /* TODO it could be saved */
    vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);

    if (place.width <= 0 || place.height <= 0)
        return;

    const int x = vd->source.i_x_offset +
        (int64_t)(ev->event_x -0*place.x) * vd->source.i_visible_width / place.width;
    const int y = vd->source.i_y_offset +
        (int64_t)(ev->event_y -0*place.y) * vd->source.i_visible_height/ place.height;

    /* TODO show the cursor ? */
    if (x >= vd->source.i_x_offset && x < vd->source.i_x_offset + vd->source.i_visible_width &&
        y >= vd->source.i_y_offset && y < vd->source.i_y_offset + vd->source.i_visible_height)
        vout_display_SendEventMouseMoved (vd, x, y);
}
示例#8
0
文件: common.c 项目: videolan/vlc
/*****************************************************************************
* UpdateRects: update clipping rectangles
*****************************************************************************
* This function is called when the window position or size are changed, and
* its job is to update the source and destination RECTs used to display the
* picture.
*****************************************************************************/
void CommonPlacePicture(vlc_object_t *obj, display_win32_area_t *area, vout_display_sys_win32_t *sys)
{
    /* Update the window position and size */
    vout_display_cfg_t place_cfg = area->vdcfg;

#if (defined(MODULE_NAME_IS_glwin32))
    /* Reverse vertical alignment as the GL tex are Y inverted */
    if (place_cfg.align.vertical == VLC_VIDEO_ALIGN_TOP)
        place_cfg.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
    else if (place_cfg.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
        place_cfg.align.vertical = VLC_VIDEO_ALIGN_TOP;
#endif

    vout_display_place_t before_place = area->place;
    vout_display_PlacePicture(&area->place, &area->texture_source, &place_cfg);

    /* Signal the change in size/position */
    if (!vout_display_PlaceEquals(&before_place, &area->place))
    {
        area->place_changed |= true;

#ifndef NDEBUG
        msg_Dbg(obj, "UpdateRects source offset: %i,%i visible: %ix%i decoded: %ix%i",
            area->texture_source.i_x_offset, area->texture_source.i_y_offset,
            area->texture_source.i_visible_width, area->texture_source.i_visible_height,
            area->texture_source.i_width, area->texture_source.i_height);
        msg_Dbg(obj, "UpdateRects image_dst coords: %i,%i %ix%i",
            area->place.x, area->place.y, area->place.width, area->place.height);
#endif

#if !VLC_WINSTORE_APP
        if (sys->event != NULL)
        {
            CommonChangeThumbnailClip(obj, sys, true);
        }
#endif
    }
}
示例#9
0
文件: caca.c 项目: 0xheart0/vlc
/**
 * Compute the place in canvas unit.
 */
static void Place(vout_display_t *vd, vout_display_place_t *place)
{
    vout_display_sys_t *sys = vd->sys;

    vout_display_PlacePicture(place, &vd->source, vd->cfg, false);

    const int canvas_width   = cucul_get_canvas_width(sys->cv);
    const int canvas_height  = cucul_get_canvas_height(sys->cv);
    const int display_width  = caca_get_display_width(sys->dp);
    const int display_height = caca_get_display_height(sys->dp);

    if (display_width > 0 && display_height > 0) {
        place->x      =  place->x      * canvas_width  / display_width;
        place->y      =  place->y      * canvas_height / display_height;
        place->width  = (place->width  * canvas_width  + display_width/2)  / display_width;
        place->height = (place->height * canvas_height + display_height/2) / display_height;
    } else {
        place->x = 0;
        place->y = 0;
        place->width  = canvas_width;
        place->height = display_height;
    }
}
示例#10
0
文件: sdl.c 项目: shanewfx/vlc-arib
/**
 * Control for vout display
 */
static int Control(vout_display_t *vd, int query, va_list args)
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
    case VOUT_DISPLAY_HIDE_MOUSE:
        SDL_ShowCursor(0);
        return VLC_SUCCESS;

    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: {
        const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);

        /* */
        sys->display = SDL_SetVideoMode(cfg->display.width,
                                        cfg->display.height,
                                        sys->display_bpp, sys->display_flags);
        if (!sys->display) {
            sys->display = SDL_SetVideoMode(vd->cfg->display.width,
                                            vd->cfg->display.height,
                                            sys->display_bpp, sys->display_flags);
            return VLC_EGENERIC;
        }
        if (sys->overlay)
            vout_display_PlacePicture(&sys->place, &vd->source, cfg, !sys->overlay);
        else
            vout_display_SendEventPicturesInvalid(vd);
        return VLC_SUCCESS;
    }
    case VOUT_DISPLAY_CHANGE_FULLSCREEN: {
        vout_display_cfg_t cfg = *va_arg(args, const vout_display_cfg_t *);

        /* Fix flags */
        sys->display_flags &= ~(SDL_FULLSCREEN | SDL_RESIZABLE);
        sys->display_flags |= cfg.is_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE;

        if (cfg.is_fullscreen) {
            cfg.display.width = sys->desktop_width;
            cfg.display.height = sys->desktop_height;
        }

        if (sys->overlay) {
            sys->display = SDL_SetVideoMode(cfg.display.width, cfg.display.height,
                                            sys->display_bpp, sys->display_flags);

            vout_display_PlacePicture(&sys->place, &vd->source, &cfg, !sys->overlay);
        }
        vout_display_SendEventDisplaySize(vd, cfg.display.width, cfg.display.height, cfg.is_fullscreen);
        return VLC_SUCCESS;
    }
    case VOUT_DISPLAY_CHANGE_ZOOM:
    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT: {
        const vout_display_cfg_t *cfg;
        const video_format_t *source;

        if (query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT) {
            source = va_arg(args, const video_format_t *);
            cfg = vd->cfg;
        } else {
            source = &vd->source;
            cfg = va_arg(args, const vout_display_cfg_t *);
        }
        if (sys->overlay) {
            sys->display = SDL_SetVideoMode(cfg->display.width, cfg->display.height,
                                            sys->display_bpp, sys->display_flags);

            vout_display_PlacePicture(&sys->place, source, cfg, !sys->overlay);
        } else {
            vout_display_SendEventPicturesInvalid(vd);
        }
        return VLC_SUCCESS;
    }
示例#11
0
文件: sdl.c 项目: shanewfx/vlc-arib
/**
 * This function initializes SDL vout method.
 */
static int Open(vlc_object_t *object)
{
    vout_display_t *vd = (vout_display_t *)object;
    vout_display_sys_t *sys;

    /* XXX: check for conflicts with the SDL audio output */
    vlc_mutex_lock(&sdl_lock);

    /* Check if SDL video module has been initialized */
    if (SDL_WasInit(SDL_INIT_VIDEO) != 0) {
        vlc_mutex_unlock(&sdl_lock);
        return VLC_EGENERIC;
    }

    vd->sys = sys = calloc(1, sizeof(*sys));
    if (!sys) {
        vlc_mutex_unlock(&sdl_lock);
        return VLC_ENOMEM;
    }

#ifdef HAVE_SETENV
    char *psz_driver = var_CreateGetNonEmptyString(vd, "sdl-video-driver");
    if (psz_driver) {
        setenv("SDL_VIDEODRIVER", psz_driver, 1);
        free(psz_driver);
    }
#endif

    /* */
    int sdl_flags = SDL_INIT_VIDEO;
#ifndef WIN32
    /* Win32 SDL implementation doesn't support SDL_INIT_EVENTTHREAD yet*/
    sdl_flags |= SDL_INIT_EVENTTHREAD;
#endif
#ifndef NDEBUG
    /* In debug mode you may want vlc to dump a core instead of staying stuck */
    sdl_flags |= SDL_INIT_NOPARACHUTE;
#endif

    /* Initialize library */
    if (SDL_Init(sdl_flags) < 0) {
        vlc_mutex_unlock(&sdl_lock);

        msg_Err(vd, "cannot initialize SDL (%s)", SDL_GetError());
        free(sys);
        return VLC_EGENERIC;
    }
    vlc_mutex_unlock(&sdl_lock);

    /* Translate keys into unicode */
    SDL_EnableUNICODE(1);

    /* Get the desktop resolution */
    /* FIXME: SDL has a problem with virtual desktop */
    sys->desktop_width  = SDL_GetVideoInfo()->current_w;
    sys->desktop_height = SDL_GetVideoInfo()->current_h;

    /* */
    video_format_t fmt = vd->fmt;

    /* */
    vout_display_info_t info = vd->info;

    /* Set main window's size */
    int display_width;
    int display_height;
    if (vd->cfg->is_fullscreen) {
        display_width  = sys->desktop_width;
        display_height = sys->desktop_height;
    } else {
        display_width  = vd->cfg->display.width;
        display_height = vd->cfg->display.height;
    }

    /* Initialize flags and cursor */
    sys->display_flags = SDL_ANYFORMAT | SDL_HWPALETTE | SDL_HWSURFACE | SDL_DOUBLEBUF;
    sys->display_flags |= vd->cfg->is_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE;

    sys->display_bpp = SDL_VideoModeOK(display_width, display_height,
                                       16, sys->display_flags);
    if (sys->display_bpp == 0) {
        msg_Err(vd, "no video mode available");
        goto error;
    }

    sys->display = SDL_SetVideoMode(display_width, display_height,
                                    sys->display_bpp, sys->display_flags);
    if (!sys->display) {
        msg_Err(vd, "cannot set video mode");
        goto error;
    }

    /* We keep the surface locked forever */
    SDL_LockSurface(sys->display);

    /* */
    vlc_fourcc_t forced_chroma = 0;
    char *psz_chroma = var_CreateGetNonEmptyString(vd, "sdl-chroma");
    if (psz_chroma) {
        forced_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_chroma);
        if (forced_chroma)
            msg_Dbg(vd, "Forcing chroma to 0x%.8x (%4.4s)",
                    forced_chroma, (const char*)&forced_chroma);
        free(psz_chroma);
    }

    /* Try to open an overlay if requested */
    sys->overlay = NULL;
    const bool is_overlay = var_CreateGetBool(vd, "overlay");
    if (is_overlay) {
        static const struct
        {
            vlc_fourcc_t vlc;
            uint32_t     sdl;
        } vlc_to_sdl[] = {
            { VLC_CODEC_YV12, SDL_YV12_OVERLAY },
            { VLC_CODEC_I420, SDL_IYUV_OVERLAY },
            { VLC_CODEC_YUYV, SDL_YUY2_OVERLAY },
            { VLC_CODEC_UYVY, SDL_UYVY_OVERLAY },
            { VLC_CODEC_YVYU, SDL_YVYU_OVERLAY },

            { 0, 0 }
        };
        const vlc_fourcc_t forced_chromas[] = {
            forced_chroma, 0
        };
        const vlc_fourcc_t *fallback_chromas =
            vlc_fourcc_GetYUVFallback(fmt.i_chroma);
        const vlc_fourcc_t *chromas = forced_chroma ? forced_chromas : fallback_chromas;

        for (int pass = forced_chroma ? 1 : 0; pass < 2 && !sys->overlay; pass++) {
            for (int i = 0; chromas[i] != 0; i++) {
                const vlc_fourcc_t vlc = chromas[i];

                uint32_t sdl = 0;
                for (int j = 0; vlc_to_sdl[j].vlc != 0 && !sdl; j++) {
                    if (vlc_to_sdl[j].vlc == vlc)
                        sdl = vlc_to_sdl[j].sdl;
                }
                if (!sdl)
                    continue;

                sys->overlay = SDL_CreateYUVOverlay(fmt.i_width, fmt.i_height,
                                                    sdl, sys->display);
                if (sys->overlay && !sys->overlay->hw_overlay && pass == 0) {
                    /* Ignore non hardware overlay surface in first pass */
                    SDL_FreeYUVOverlay(sys->overlay);
                    sys->overlay = NULL;
                }
                if (sys->overlay) {
                    /* We keep the surface locked forever */
                    SDL_LockYUVOverlay(sys->overlay);

                    fmt.i_chroma = vlc;
                    sys->is_uv_swapped = vlc_fourcc_AreUVPlanesSwapped(fmt.i_chroma,
                                                                       vd->fmt.i_chroma);
                    if (sys->is_uv_swapped)
                        fmt.i_chroma = vd->fmt.i_chroma;
                    break;
                }
            }
        }
    } else {
        msg_Warn(vd, "SDL overlay disabled by the user");
    }

    /* */
    vout_display_cfg_t place_cfg = *vd->cfg;
    place_cfg.display.width  = display_width;
    place_cfg.display.height = display_height;
    vout_display_PlacePicture(&sys->place, &vd->source, &place_cfg, !sys->overlay);

    /* If no overlay, fallback to software output */
    if (!sys->overlay) {
        /* */
        switch (sys->display->format->BitsPerPixel) {
        case 8:
            fmt.i_chroma = VLC_CODEC_RGB8;
            break;
        case 15:
            fmt.i_chroma = VLC_CODEC_RGB15;
            break;
        case 16:
            fmt.i_chroma = VLC_CODEC_RGB16;
            break;
        case 24:
            fmt.i_chroma = VLC_CODEC_RGB24;
            break;
        case 32:
            fmt.i_chroma = VLC_CODEC_RGB32;
            break;
        default:
            msg_Err(vd, "unknown screen depth %i",
                    sys->display->format->BitsPerPixel);
            goto error;
        }

        /* All we have is an RGB image with square pixels */
        fmt.i_width  = display_width;
        fmt.i_height = display_height;
        fmt.i_rmask = sys->display->format->Rmask;
        fmt.i_gmask = sys->display->format->Gmask;
        fmt.i_bmask = sys->display->format->Bmask;

        info.has_pictures_invalid = true;
    }

    if (vd->cfg->display.title)
        SDL_WM_SetCaption(vd->cfg->display.title,
                          vd->cfg->display.title);
    else if (!sys->overlay)
        SDL_WM_SetCaption(VOUT_TITLE " (software RGB SDL output)",
                          VOUT_TITLE " (software RGB SDL output)");
    else if (sys->overlay->hw_overlay)
        SDL_WM_SetCaption(VOUT_TITLE " (hardware YUV SDL output)",
                          VOUT_TITLE " (hardware YUV SDL output)");
    else
        SDL_WM_SetCaption(VOUT_TITLE " (software YUV SDL output)",
                          VOUT_TITLE " (software YUV SDL output)");

    /* Setup events */
    SDL_EventState(SDL_KEYUP, SDL_IGNORE);               /* ignore keys up */

    /* Setup vout_display now that everything is fine */
    vd->fmt = fmt;
    vd->info = info;

    vd->get     = Get;
    vd->prepare = NULL;
    vd->display = Display;
    vd->control = Control;
    vd->manage  = Manage;

    /* */
    vout_display_SendEventDisplaySize(vd, display_width, display_height, vd->cfg->is_fullscreen);
    return VLC_SUCCESS;

error:
    msg_Err(vd, "cannot set up SDL (%s)", SDL_GetError());

    if (sys->display) {
        SDL_UnlockSurface(sys->display);
        SDL_FreeSurface(sys->display);
    }

    vlc_mutex_lock(&sdl_lock);
    SDL_QuitSubSystem(SDL_INIT_VIDEO);
    vlc_mutex_unlock(&sdl_lock);

    free(sys);
    return VLC_EGENERIC;
}
示例#12
0
/**
 * ProjectM update thread which do the rendering
 * @param p_this: the p_thread object
 */
static void *Thread( void *p_data )
{
    filter_t  *p_filter = (filter_t*)p_data;
    filter_sys_t *p_sys = p_filter->p_sys;

    video_format_t fmt;
    vlc_gl_t *gl;
    unsigned int i_last_width  = 0;
    unsigned int i_last_height = 0;
    locale_t loc;
    locale_t oldloc;

    projectM *p_projectm;
#ifndef HAVE_PROJECTM2
    char *psz_config;
#else
    char *psz_preset_path;
    char *psz_title_font;
    char *psz_menu_font;
    projectM::Settings settings;
#endif

    vlc_savecancel();

    /* Create the openGL provider */
    p_sys->p_vout =
        (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) );
    if( !p_sys->p_vout )
        goto error;

    /* */
    video_format_Init( &fmt, 0 );
    video_format_Setup( &fmt, VLC_CODEC_RGB32,
                        p_sys->i_width, p_sys->i_height, 0, 1 );
    fmt.i_sar_num = 1;
    fmt.i_sar_den = 1;

    vout_display_state_t state;
    memset( &state, 0, sizeof(state) );
    state.cfg.display.sar.num = 1;
    state.cfg.display.sar.den = 1;
    state.cfg.is_display_filled = true;
    state.cfg.zoom.num = 1;
    state.cfg.zoom.den = 1;
    state.sar.num = 1;
    state.sar.den = 1;

    p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl",
                                   300000, 1000000 );
    if( !p_sys->p_vd )
    {
        vlc_object_release( p_sys->p_vout );
        goto error;
    }
    var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL );
    var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd );

    gl = vout_GetDisplayOpengl( p_sys->p_vd );
    if( !gl )
    {
        vout_DeleteDisplay( p_sys->p_vd, NULL );
        vlc_object_release( p_sys->p_vout );
        goto error;
    }

    /* Work-around the projectM locale bug */
    loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
    oldloc = uselocale (loc);

    /* Create the projectM object */
#ifndef HAVE_PROJECTM2
    psz_config = var_InheritString( p_filter, "projectm-config" );
    p_projectm = new projectM( psz_config );
    free( psz_config );
#else
    psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" );
#ifdef WIN32
    if ( psz_preset_path == NULL )
    {
        char *psz_data_path = config_GetDataDir( p_filter );
        asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path );
        free( psz_data_path );
    }
#endif

    psz_title_font                = var_InheritString( p_filter, "projectm-title-font" );
    psz_menu_font                 = var_InheritString( p_filter, "projectm-menu-font" );

    settings.meshX                = var_InheritInteger( p_filter, "projectm-meshx" );
    settings.meshY                = var_InheritInteger( p_filter, "projectm-meshy" );
    settings.fps                  = 35;
    settings.textureSize          = var_InheritInteger( p_filter, "projectm-texture-size" );
    settings.windowWidth          = p_sys->i_width;
    settings.windowHeight         = p_sys->i_height;
    settings.presetURL            = psz_preset_path;
    settings.titleFontURL         = psz_title_font;
    settings.menuFontURL          = psz_menu_font;
    settings.smoothPresetDuration = 5;
    settings.presetDuration       = 30;
    settings.beatSensitivity      = 10;
    settings.aspectCorrection     = 1;
    settings.easterEgg            = 1;
    settings.shuffleEnabled       = 1;

    p_projectm = new projectM( settings );

    free( psz_menu_font );
    free( psz_title_font );
    free( psz_preset_path );
#endif /* HAVE_PROJECTM2 */

    p_sys->i_buffer_size = p_projectm->pcm()->maxsamples;
    p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size,
                                      sizeof( float ) );

    vlc_sem_post( &p_sys->ready );

    /* Choose a preset randomly or projectM will always show the first one */
    if ( p_projectm->getPlaylistSize() > 0 )
        p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() );

    /* */
    for( ;; )
    {
        const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */
        /* Manage the events */
        vout_ManageDisplay( p_sys->p_vd, true );
        if( p_sys->p_vd->cfg->display.width  != i_last_width ||
            p_sys->p_vd->cfg->display.height != i_last_height )
        {
            /* FIXME it is not perfect as we will have black bands */
            vout_display_place_t place;
            vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false );
            p_projectm->projectM_resetGL( place.width, place.height );

            i_last_width  = p_sys->p_vd->cfg->display.width;
            i_last_height = p_sys->p_vd->cfg->display.height;
        }

        /* Render the image and swap the buffers */
        vlc_mutex_lock( &p_sys->lock );
        if( p_sys->i_nb_samples > 0 )
        {
            p_projectm->pcm()->addPCMfloat( p_sys->p_buffer,
                                            p_sys->i_nb_samples );
            p_sys->i_nb_samples = 0;
        }
        if( p_sys->b_quit )
        {
            vlc_mutex_unlock( &p_sys->lock );

            delete p_projectm;
            vout_DeleteDisplay( p_sys->p_vd, NULL );
            vlc_object_release( p_sys->p_vout );
            if (loc != (locale_t)0)
            {
                uselocale (oldloc);
                freelocale (loc);
            }
            return NULL;
        }
        vlc_mutex_unlock( &p_sys->lock );

        p_projectm->renderFrame();

        /* */
        mwait( i_deadline );

        if( !vlc_gl_Lock(gl) )
        {
            vlc_gl_Swap( gl );
            vlc_gl_Unlock( gl );
        }
    }
    abort();

error:
    p_sys->b_error = true;
    vlc_sem_post( &p_sys->ready );
    return NULL;
}
示例#13
0
文件: vout.c 项目: Kubink/vlc
static int configure_display(vout_display_t *vd, const vout_display_cfg_t *cfg,
                const video_format_t *fmt)
{
    vout_display_sys_t *sys = vd->sys;
    vout_display_place_t place;
    MMAL_DISPLAYREGION_T display_region;
    MMAL_STATUS_T status;

    if (!cfg && !fmt)
        return -EINVAL;

    if (fmt) {
        sys->input->format->es->video.par.num = fmt->i_sar_num;
        sys->input->format->es->video.par.den = fmt->i_sar_den;

        status = mmal_port_format_commit(sys->input);
        if (status != MMAL_SUCCESS) {
            msg_Err(vd, "Failed to commit format for input port %s (status=%"PRIx32" %s)",
                            sys->input->name, status, mmal_status_to_string(status));
            return -EINVAL;
        }
    } else {
        fmt = &vd->source;
    }

    if (!cfg)
        cfg = vd->cfg;

    vout_display_PlacePicture(&place, fmt, cfg, false);

    display_region.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
    display_region.hdr.size = sizeof(MMAL_DISPLAYREGION_T);
    display_region.fullscreen = MMAL_FALSE;
    display_region.src_rect.x = fmt->i_x_offset;
    display_region.src_rect.y = fmt->i_y_offset;
    display_region.src_rect.width = fmt->i_visible_width;
    display_region.src_rect.height = fmt->i_visible_height;
    display_region.dest_rect.x = place.x;
    display_region.dest_rect.y = place.y;
    display_region.dest_rect.width = place.width;
    display_region.dest_rect.height = place.height;
    display_region.layer = sys->layer;
    display_region.set = MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_SRC_RECT |
            MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_LAYER;
    status = mmal_port_parameter_set(sys->input, &display_region.hdr);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to set display region (status=%"PRIx32" %s)",
                        status, mmal_status_to_string(status));
        return -EINVAL;
    }

    show_background(vd, cfg->is_fullscreen);
    sys->adjust_refresh_rate = var_InheritBool(vd, MMAL_ADJUST_REFRESHRATE_NAME);
    sys->native_interlaced = var_InheritBool(vd, MMAL_NATIVE_INTERLACED);
    if (sys->adjust_refresh_rate) {
        adjust_refresh_rate(vd, fmt);
        set_latency_target(vd, true);
    }

    return 0;
}
示例#14
0
文件: x11.c 项目: maniacs-m/vlc
static int Control (vout_display_t *vd, int query, va_list ap)
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
    {
        const vout_display_cfg_t *p_cfg =
            (const vout_display_cfg_t*)va_arg (ap, const vout_display_cfg_t *);
        vout_display_place_t place;

        vout_display_PlacePicture (&place, &vd->source, p_cfg, false);

        if (place.width  != vd->fmt.i_visible_width ||
            place.height != vd->fmt.i_visible_height)
        {
            vout_display_SendEventPicturesInvalid (vd);
            return VLC_SUCCESS;
        }

        /* Move the picture within the window */
        const uint32_t values[] = { place.x, place.y };
        xcb_configure_window (sys->conn, sys->window,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                              values);
        return VLC_SUCCESS;
    }

    case VOUT_DISPLAY_CHANGE_ZOOM:
    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
    case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
        /* I am not sure it is always necessary, but it is way simpler ... */
        vout_display_SendEventPicturesInvalid (vd);
        return VLC_SUCCESS;

    case VOUT_DISPLAY_RESET_PICTURES:
    {
        ResetPictures (vd);

        vout_display_place_t place;
        vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);

        video_format_t src;
        video_format_ApplyRotation(&src, &vd->source);

        vd->fmt.i_width  = src.i_width  * place.width / src.i_visible_width;
        vd->fmt.i_height = src.i_height * place.height / src.i_visible_height;

        vd->fmt.i_visible_width  = place.width;
        vd->fmt.i_visible_height = place.height;
        vd->fmt.i_x_offset = src.i_x_offset * place.width / src.i_visible_width;
        vd->fmt.i_y_offset = src.i_y_offset * place.height / src.i_visible_height;
        return VLC_SUCCESS;
    }

    /* Hide the mouse. It will be send when
     * vout_display_t::info.b_hide_mouse is false */
    case VOUT_DISPLAY_HIDE_MOUSE:
        xcb_change_window_attributes (sys->conn, sys->embed->handle.xid,
                                  XCB_CW_CURSOR, &(uint32_t){ sys->cursor });
        xcb_flush (sys->conn);
        return VLC_SUCCESS;

    default:
        msg_Err (vd, "Unknown request in XCB vout display");
        return VLC_EGENERIC;
    }
}
示例#15
0
/**
 * ProjectM update thread which do the rendering
 * @param p_this: the p_thread object
 */
static void *Thread( void *p_data )
{
    filter_t     *p_filter = (filter_t*)p_data;
    filter_sys_t *p_sys = p_filter->p_sys;
    int cancel = vlc_savecancel();
    video_format_t fmt;
    vout_opengl_t *gl;
    int i_last_width  = 0;
    int i_last_height = 0;
#ifdef HAVE_PROJECTM2
    projectM::Settings settings;
#endif

    /* Create the openGL provider */
    p_sys->p_vout =
        (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) );
    if( !p_sys->p_vout )
        goto error;

    vlc_object_attach( p_sys->p_vout, p_filter );

    /* */
    video_format_Init( &fmt, 0 );
    video_format_Setup( &fmt, VLC_CODEC_RGB32,
                        p_sys->i_width, p_sys->i_height, 0, 1 );
    fmt.i_sar_num = 1;
    fmt.i_sar_den = 1;

    vout_display_state_t state;
    memset( &state, 0, sizeof(state) );
    state.cfg.display.sar.num = 1;
    state.cfg.display.sar.den = 1;
    state.cfg.is_display_filled = true;
    state.cfg.zoom.num = 1;
    state.cfg.zoom.den = 1;
    state.sar.num = 1;
    state.sar.den = 1;

    p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl",
                                   300000, 1000000 );
    if( !p_sys->p_vd )
    {
        vlc_object_release( p_sys->p_vout );
        goto error;
    }
    var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL );
    var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd );

    gl = vout_GetDisplayOpengl( p_sys->p_vd );
    if( !gl )
    {
        vout_DeleteDisplay( p_sys->p_vd, NULL );
        vlc_object_release( p_sys->p_vout );
        goto error;
    }

    /* Create the projectM object */
#ifndef HAVE_PROJECTM2
    p_sys->p_projectm = new projectM( p_sys->psz_config );
#else
    settings.meshX = 32;
    settings.meshY = 24;
    settings.fps = 35;
    settings.textureSize = 1024;
    settings.windowWidth = p_sys->i_width;
    settings.windowHeight = p_sys->i_height;
    settings.presetURL = p_sys->psz_preset_path;
    settings.titleFontURL =  p_sys->psz_title_font;
    settings.menuFontURL = p_sys->psz_menu_font;
    settings.smoothPresetDuration = 5;
    settings.presetDuration = 30;
    settings.beatSensitivity = 10;
    settings.aspectCorrection = 1;
    settings.easterEgg = 1;
    settings.shuffleEnabled = 1;
    p_sys->p_projectm = new projectM( settings );
#endif
    p_sys->i_buffer_size = p_sys->p_projectm->pcm()->maxsamples;
    p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size,
                                      sizeof( float ) );

    vlc_sem_post( &p_sys->ready );

    /* TODO: Give to projectm the name of the input
    p_sys->p_projectm->projectM_setTitle( "" ); */

    /* */
    for( ;; )
    {
        const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */
        /* Manage the events */
        vout_ManageDisplay( p_sys->p_vd, true );
        if( p_sys->p_vd->cfg->display.width  != i_last_width ||
            p_sys->p_vd->cfg->display.height != i_last_height )
        {
            /* FIXME it is not perfect as we will have black bands */
            vout_display_place_t place;
            vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false );
            p_sys->p_projectm->projectM_resetGL( place.width, place.height );

            i_last_width  = p_sys->p_vd->cfg->display.width;
            i_last_height = p_sys->p_vd->cfg->display.height;
        }

        /* Render the image and swap the buffers */
        vlc_mutex_lock( &p_sys->lock );
        if( p_sys->i_nb_samples > 0 )
        {
            p_sys->p_projectm->pcm()->addPCMfloat( p_sys->p_buffer,
                                                   p_sys->i_nb_samples );
            p_sys->i_nb_samples = 0;
        }
        if( p_sys->b_quit )
        {
            vlc_mutex_unlock( &p_sys->lock );

            delete p_sys->p_projectm;
            vout_DeleteDisplay( p_sys->p_vd, NULL );
            vlc_object_release( p_sys->p_vout );
            return NULL;
        }
        vlc_mutex_unlock( &p_sys->lock );

        p_sys->p_projectm->renderFrame();

        /* */
        mwait( i_deadline );

        if( !vout_opengl_Lock(gl) )
        {
            vout_opengl_Swap( gl );
            vout_opengl_Unlock( gl );
        }
    }
    abort();

error:
    p_sys->b_error = true;
    vlc_sem_post( &p_sys->ready );
    return NULL;
}
示例#16
0
文件: x11.c 项目: paa/vlc
static int Control (vout_display_t *vd, int query, va_list ap)
{
    vout_display_sys_t *p_sys = vd->sys;

    switch (query)
    {
    case VOUT_DISPLAY_CHANGE_FULLSCREEN:
    {
        const vout_display_cfg_t *c = va_arg (ap, const vout_display_cfg_t *);
        return vout_window_SetFullScreen (p_sys->embed, c->is_fullscreen);
    }

    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
    {
        const vout_display_cfg_t *p_cfg =
            (const vout_display_cfg_t*)va_arg (ap, const vout_display_cfg_t *);
        const bool is_forced = (bool)va_arg (ap, int);

        if (is_forced
         && vout_window_SetSize (p_sys->embed,
                                 p_cfg->display.width,
                                 p_cfg->display.height))
            return VLC_EGENERIC;

        vout_display_place_t place;
        vout_display_PlacePicture (&place, &vd->source, p_cfg, false);

        if (place.width  != vd->fmt.i_visible_width ||
            place.height != vd->fmt.i_visible_height)
        {
            vout_display_SendEventPicturesInvalid (vd);
            return VLC_SUCCESS;
        }

        /* Move the picture within the window */
        const uint32_t values[] = { place.x, place.y };
        xcb_configure_window (p_sys->conn, p_sys->window,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                              values);
        return VLC_SUCCESS;
    }
    case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
    {
        unsigned state = va_arg (ap, unsigned);
        return vout_window_SetState (p_sys->embed, state);
    }

    case VOUT_DISPLAY_CHANGE_ZOOM:
    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
    case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
        /* I am not sure it is always necessary, but it is way simpler ... */
        vout_display_SendEventPicturesInvalid (vd);
        return VLC_SUCCESS;

    case VOUT_DISPLAY_RESET_PICTURES:
    {
        ResetPictures (vd);

        vout_display_place_t place;
        vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);

        vd->fmt.i_width  = vd->source.i_width  * place.width  / vd->source.i_visible_width;
        vd->fmt.i_height = vd->source.i_height * place.height / vd->source.i_visible_height;

        vd->fmt.i_visible_width  = place.width;
        vd->fmt.i_visible_height = place.height;
        vd->fmt.i_x_offset = vd->source.i_x_offset * place.width  / vd->source.i_visible_width;
        vd->fmt.i_y_offset = vd->source.i_y_offset * place.height / vd->source.i_visible_height;
        return VLC_SUCCESS;
    }

    /* Hide the mouse. It will be send when
     * vout_display_t::info.b_hide_mouse is false */
    case VOUT_DISPLAY_HIDE_MOUSE:
        xcb_change_window_attributes (p_sys->conn, p_sys->embed->handle.xid,
                                  XCB_CW_CURSOR, &(uint32_t){ p_sys->cursor });
        xcb_flush (p_sys->conn);
        return VLC_SUCCESS;

    default:
        msg_Err (vd, "Unknown request in XCB vout display");
        return VLC_EGENERIC;
    }
}
示例#17
0
文件: shm.c 项目: videolan/vlc
static int Control(vout_display_t *vd, int query, va_list ap)
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
        case VOUT_DISPLAY_RESET_PICTURES:
        {
            const vout_display_cfg_t *cfg = va_arg(ap, const vout_display_cfg_t *);
            video_format_t *fmt = va_arg(ap, video_format_t *);
            vout_display_place_t place;
            video_format_t src;
            assert(sys->viewport == NULL);

            vout_display_PlacePicture(&place, &vd->source, cfg);
            video_format_ApplyRotation(&src, &vd->source);

            fmt->i_width  = src.i_width * place.width
                                        / src.i_visible_width;
            fmt->i_height = src.i_height * place.height
                                         / src.i_visible_height;
            fmt->i_visible_width  = place.width;
            fmt->i_visible_height = place.height;
            fmt->i_x_offset = src.i_x_offset * place.width
                                             / src.i_visible_width;
            fmt->i_y_offset = src.i_y_offset * place.height
                                             / src.i_visible_height;
            break;
        }

        case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
        case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
        case VOUT_DISPLAY_CHANGE_ZOOM:
        case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
        case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
        {
            const vout_display_cfg_t *cfg = va_arg(ap, const vout_display_cfg_t *);
            sys->display_width = cfg->display.width;
            sys->display_height = cfg->display.height;

            if (sys->viewport != NULL)
            {
                video_format_t fmt;
                vout_display_place_t place;

                video_format_ApplyRotation(&fmt, &vd->source);
                vout_display_PlacePicture(&place, &vd->source, cfg);

                wp_viewport_set_source(sys->viewport,
                                wl_fixed_from_int(fmt.i_x_offset),
                                wl_fixed_from_int(fmt.i_y_offset),
                                wl_fixed_from_int(fmt.i_visible_width),
                                wl_fixed_from_int(fmt.i_visible_height));
                wp_viewport_set_destination(sys->viewport,
                                            place.width, place.height);
            }
            else
                return VLC_EGENERIC;
            break;
        }
        default:
             msg_Err(vd, "unknown request %d", query);
             return VLC_EGENERIC;
    }
    return VLC_SUCCESS;
}
示例#18
0
文件: x11.c 项目: Annovae/vlc
static int Control (vout_display_t *vd, int query, va_list ap)
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
    case VOUT_DISPLAY_CHANGE_FULLSCREEN:
    {
        const vout_display_cfg_t *c = va_arg (ap, const vout_display_cfg_t *);
        return vout_window_SetFullScreen (sys->embed, c->is_fullscreen);
    }

    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
    {
        const vout_display_cfg_t *p_cfg =
            (const vout_display_cfg_t*)va_arg (ap, const vout_display_cfg_t *);
        const bool is_forced = (bool)va_arg (ap, int);

        if (is_forced)
        {   /* Changing the dimensions of the parent window takes place
             * asynchronously (in the X server). Also it might fail or result
             * in different dimensions than requested. Request the size change
             * and return a failure since the size is not (yet) changed.
             * If the change eventually succeeds, HandleParentStructure()
             * will trigger a non-forced display size change later. */
            vout_window_SetSize (sys->embed, p_cfg->display.width,
                                 p_cfg->display.height);
            return VLC_EGENERIC;
        }

        vout_display_place_t place;
        vout_display_PlacePicture (&place, &vd->source, p_cfg, false);

        if (place.width  != vd->fmt.i_visible_width ||
            place.height != vd->fmt.i_visible_height)
        {
            vout_display_SendEventPicturesInvalid (vd);
            return VLC_SUCCESS;
        }

        /* Move the picture within the window */
        const uint32_t values[] = { place.x, place.y };
        xcb_configure_window (sys->conn, sys->window,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                              values);
        return VLC_SUCCESS;
    }
    case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
    {
        unsigned state = va_arg (ap, unsigned);
        return vout_window_SetState (sys->embed, state);
    }

    case VOUT_DISPLAY_CHANGE_ZOOM:
    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
    case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
        /* I am not sure it is always necessary, but it is way simpler ... */
        vout_display_SendEventPicturesInvalid (vd);
        return VLC_SUCCESS;

    case VOUT_DISPLAY_RESET_PICTURES:
    {
        ResetPictures (vd);

        vout_display_place_t place;
        vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);

        vd->fmt.i_width  = vd->source.i_width  * place.width  / vd->source.i_visible_width;
        vd->fmt.i_height = vd->source.i_height * place.height / vd->source.i_visible_height;

        vd->fmt.i_visible_width  = place.width;
        vd->fmt.i_visible_height = place.height;
        vd->fmt.i_x_offset = vd->source.i_x_offset * place.width  / vd->source.i_visible_width;
        vd->fmt.i_y_offset = vd->source.i_y_offset * place.height / vd->source.i_visible_height;
        return VLC_SUCCESS;
    }

    /* Hide the mouse. It will be send when
     * vout_display_t::info.b_hide_mouse is false */
    case VOUT_DISPLAY_HIDE_MOUSE:
        xcb_change_window_attributes (sys->conn, sys->embed->handle.xid,
                                  XCB_CW_CURSOR, &(uint32_t){ sys->cursor });
        xcb_flush (sys->conn);
        return VLC_SUCCESS;

    default:
        msg_Err (vd, "Unknown request in XCB vout display");
        return VLC_EGENERIC;
    }
}
示例#19
0
文件: gl.c 项目: banketree/faplayer
static int Control (vout_display_t *vd, int query, va_list ap)
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
      case VOUT_DISPLAY_HIDE_MOUSE: /* FIXME TODO */
        break;
#ifndef NDEBUG
      case VOUT_DISPLAY_RESET_PICTURES: // not needed
        assert(0);
#endif
      case VOUT_DISPLAY_CHANGE_FULLSCREEN:
      {
        const vout_display_cfg_t *cfg =
            va_arg (ap, const vout_display_cfg_t *);

        return vout_window_SetFullScreen (sys->window, cfg->is_fullscreen);
      }

      case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
      {
        unsigned state = va_arg (ap, unsigned);

        return vout_window_SetState (sys->window, state);
      }

      case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
      case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
      case VOUT_DISPLAY_CHANGE_ZOOM:
      {
        const vout_display_cfg_t *cfg = va_arg (ap, const vout_display_cfg_t *);
        const video_format_t *src = &vd->source;

        if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE)
        {
            bool force = false;

            force = va_arg (ap, int);
            if (force
             && (cfg->display.width  != vd->cfg->display.width
              || cfg->display.height != vd->cfg->display.height)
             && vout_window_SetSize (sys->window,
                                     cfg->display.width, cfg->display.height))
                return VLC_EGENERIC;
        }

        vout_display_place_t place;

        vout_display_PlacePicture (&place, src, cfg, false);
        glViewport (0, 0, place.width, place.height);
        return VLC_SUCCESS;
      }

      case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
      case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
      {
        const vout_display_cfg_t *cfg = vd->cfg;
        const video_format_t *src = va_arg (ap, const video_format_t *);
        vout_display_place_t place;

        vout_display_PlacePicture (&place, src, cfg, false);
        glViewport (0, 0, place.width, place.height);
        return VLC_SUCCESS;
      }

      case VOUT_DISPLAY_GET_OPENGL:
      {
        vlc_gl_t **pgl = va_arg (ap, vlc_gl_t **);

        *pgl = sys->gl;
        return VLC_SUCCESS;
      }

      default:
        msg_Err (vd, "Unknown request %d", query);
    }
示例#20
0
/*****************************************************************************
 * UpdateRects: update clipping rectangles
 *****************************************************************************
 * This function is called when the window position or size are changed, and
 * its job is to update the source and destination RECTs used to display the
 * picture.
 *****************************************************************************/
void UpdateRects(vout_display_t *vd,
                 const vout_display_cfg_t *cfg,
                 const video_format_t *source,
                 bool is_forced)
{
    vout_display_sys_t *sys = vd->sys;
#define rect_src sys->rect_src
#define rect_src_clipped sys->rect_src_clipped
#define rect_dest sys->rect_dest
#define rect_dest_clipped sys->rect_dest_clipped

    RECT  rect;
    POINT point;

    /* */
    if (!cfg)
        cfg = vd->cfg;
    if (!source)
        source = &vd->source;

    /* Retrieve the window size */
    GetClientRect(sys->hwnd, &rect);

    /* Retrieve the window position */
    point.x = point.y = 0;
    ClientToScreen(sys->hwnd, &point);

    /* If nothing changed, we can return */
    bool has_moved;
    bool is_resized;
    EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized,
                                    point.x, point.y,
                                    rect.right, rect.bottom);
    if (is_resized)
        vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom, cfg->is_fullscreen);
    if (!is_forced && !has_moved && !is_resized )
        return;

    /* Update the window position and size */
    vout_display_cfg_t place_cfg = *cfg;
    place_cfg.display.width  = rect.right;
    place_cfg.display.height = rect.bottom;

    vout_display_place_t place;
    vout_display_PlacePicture(&place, source, &place_cfg, false);

    EventThreadUpdateSourceAndPlace(sys->event, source, &place);

    if (sys->hvideownd)
        SetWindowPos(sys->hvideownd, 0,
                     place.x, place.y, place.width, place.height,
                     SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS);

    /* Destination image position and dimensions */
#if defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d)
    rect_dest.left   = 0;
    rect_dest.right  = place.width;
    rect_dest.top    = 0;
    rect_dest.bottom = place.height;
#else
    rect_dest.left = point.x + place.x;
    rect_dest.right = rect_dest.left + place.width;
    rect_dest.top = point.y + place.y;
    rect_dest.bottom = rect_dest.top + place.height;

#ifdef MODULE_NAME_IS_directdraw
    /* Apply overlay hardware constraints */
    if (sys->use_overlay)
        AlignRect(&rect_dest, sys->i_align_dest_boundary, sys->i_align_dest_size);
#endif

#endif

#if defined(MODULE_NAME_IS_directdraw)
    /* UpdateOverlay directdraw function doesn't automatically clip to the
     * display size so we need to do it otherwise it will fail */

    /* Clip the destination window */
    if (!IntersectRect(&rect_dest_clipped, &rect_dest,
                       &sys->rect_display)) {
        SetRectEmpty(&rect_src_clipped);
        goto exit;
    }

#ifndef NDEBUG
    msg_Dbg(vd, "DirectXUpdateRects image_dst_clipped coords:"
            " %li,%li,%li,%li",
            rect_dest_clipped.left, rect_dest_clipped.top,
            rect_dest_clipped.right, rect_dest_clipped.bottom);
#endif

#else

    /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
    rect_dest_clipped = rect_dest;

#endif

    /* the 2 following lines are to fix a bug when clicking on the desktop */
    if ((rect_dest_clipped.right - rect_dest_clipped.left) == 0 ||
            (rect_dest_clipped.bottom - rect_dest_clipped.top) == 0) {
        SetRectEmpty(&rect_src_clipped);
        goto exit;
    }

    /* src image dimensions */
    rect_src.left   = 0;
    rect_src.top    = 0;
    rect_src.right  = source->i_width;
    rect_src.bottom = source->i_height;

    /* Clip the source image */
    rect_src_clipped.left = source->i_x_offset +
                            (rect_dest_clipped.left - rect_dest.left) *
                            source->i_visible_width / (rect_dest.right - rect_dest.left);
    rect_src_clipped.right = source->i_x_offset +
                             source->i_visible_width -
                             (rect_dest.right - rect_dest_clipped.right) *
                             source->i_visible_width / (rect_dest.right - rect_dest.left);
    rect_src_clipped.top = source->i_y_offset +
                           (rect_dest_clipped.top - rect_dest.top) *
                           source->i_visible_height / (rect_dest.bottom - rect_dest.top);
    rect_src_clipped.bottom = source->i_y_offset +
                              source->i_visible_height -
                              (rect_dest.bottom - rect_dest_clipped.bottom) *
                              source->i_visible_height / (rect_dest.bottom - rect_dest.top);

#ifdef MODULE_NAME_IS_directdraw
    /* Apply overlay hardware constraints */
    if (sys->use_overlay)
        AlignRect(&rect_src_clipped, sys->i_align_src_boundary, sys->i_align_src_size);
#elif defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d)
    /* Needed at least with YUV content */
    rect_src_clipped.left &= ~1;
    rect_src_clipped.right &= ~1;
    rect_src_clipped.top &= ~1;
    rect_src_clipped.bottom &= ~1;
#endif

#ifndef NDEBUG
    msg_Dbg(vd, "DirectXUpdateRects image_src_clipped"
            " coords: %li,%li,%li,%li",
            rect_src_clipped.left, rect_src_clipped.top,
            rect_src_clipped.right, rect_src_clipped.bottom);
#endif

#ifdef MODULE_NAME_IS_directdraw
    /* The destination coordinates need to be relative to the current
     * directdraw primary surface (display) */
    rect_dest_clipped.left -= sys->rect_display.left;
    rect_dest_clipped.right -= sys->rect_display.left;
    rect_dest_clipped.top -= sys->rect_display.top;
    rect_dest_clipped.bottom -= sys->rect_display.top;
#endif

    CommonChangeThumbnailClip(vd, true);

exit:
    /* Signal the change in size/position */
    sys->changes |= DX_POSITION_CHANGE;

#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
}
示例#21
0
文件: vout.c 项目: Kubink/vlc
static int Open(vlc_object_t *object)
{
    vout_display_t *vd = (vout_display_t *)object;
    vout_display_sys_t *sys;
    uint32_t buffer_pitch, buffer_height;
    vout_display_place_t place;
    MMAL_DISPLAYREGION_T display_region;
    uint32_t offsets[3];
    MMAL_STATUS_T status;
    int ret = VLC_SUCCESS;
    unsigned i;

    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;

    sys = calloc(1, sizeof(struct vout_display_sys_t));
    if (!sys)
        return VLC_ENOMEM;
    vd->sys = sys;

    sys->layer = var_InheritInteger(vd, MMAL_LAYER_NAME);
    bcm_host_init();

    vd->info.has_hide_mouse = true;
    sys->opaque = vd->fmt.i_chroma == VLC_CODEC_MMAL_OPAQUE;

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to create MMAL component %s (status=%"PRIx32" %s)",
                        MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)vd;
    status = mmal_port_enable(sys->component->control, control_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to enable control port %s (status=%"PRIx32" %s)",
                        sys->component->control->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->input = sys->component->input[0];
    sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)vd;

    if (sys->opaque) {
        sys->input->format->encoding = MMAL_ENCODING_OPAQUE;
        sys->i_planes = 1;
        sys->buffer_size = sys->input->buffer_size_recommended;
    } else {
        sys->input->format->encoding = MMAL_ENCODING_I420;
        vd->fmt.i_chroma = VLC_CODEC_I420;
        buffer_pitch = align(vd->fmt.i_width, 32);
        buffer_height = align(vd->fmt.i_height, 16);
        sys->i_planes = 3;
        sys->buffer_size = 3 * buffer_pitch * buffer_height / 2;
    }

    sys->input->format->es->video.width = vd->fmt.i_width;
    sys->input->format->es->video.height = vd->fmt.i_height;
    sys->input->format->es->video.crop.x = 0;
    sys->input->format->es->video.crop.y = 0;
    sys->input->format->es->video.crop.width = vd->fmt.i_width;
    sys->input->format->es->video.crop.height = vd->fmt.i_height;
    sys->input->format->es->video.par.num = vd->source.i_sar_num;
    sys->input->format->es->video.par.den = vd->source.i_sar_den;

    status = mmal_port_format_commit(sys->input);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to commit format for input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }
    sys->input->buffer_size = sys->input->buffer_size_recommended;

    vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
    display_region.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
    display_region.hdr.size = sizeof(MMAL_DISPLAYREGION_T);
    display_region.fullscreen = MMAL_FALSE;
    display_region.src_rect.x = vd->fmt.i_x_offset;
    display_region.src_rect.y = vd->fmt.i_y_offset;
    display_region.src_rect.width = vd->fmt.i_visible_width;
    display_region.src_rect.height = vd->fmt.i_visible_height;
    display_region.dest_rect.x = place.x;
    display_region.dest_rect.y = place.y;
    display_region.dest_rect.width = place.width;
    display_region.dest_rect.height = place.height;
    display_region.layer = sys->layer;
    display_region.set = MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_SRC_RECT |
            MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_LAYER;
    status = mmal_port_parameter_set(sys->input, &display_region.hdr);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to set display region (status=%"PRIx32" %s)",
                        status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    offsets[0] = 0;
    for (i = 0; i < sys->i_planes; ++i) {
        sys->planes[i].i_lines = buffer_height;
        sys->planes[i].i_pitch = buffer_pitch;
        sys->planes[i].i_visible_lines = vd->fmt.i_visible_height;
        sys->planes[i].i_visible_pitch = vd->fmt.i_visible_width;

        if (i > 0) {
            offsets[i] = offsets[i - 1] + sys->planes[i - 1].i_pitch * sys->planes[i - 1].i_lines;
            sys->planes[i].i_lines /= 2;
            sys->planes[i].i_pitch /= 2;
            sys->planes[i].i_visible_lines /= 2;
            sys->planes[i].i_visible_pitch /= 2;
        }

        sys->planes[i].p_pixels = (uint8_t *)offsets[i];
    }

    vlc_mutex_init(&sys->buffer_mutex);
    vlc_cond_init(&sys->buffer_cond);
    vlc_mutex_init(&sys->manage_mutex);

    vd->pool = vd_pool;
    vd->prepare = vd_prepare;
    vd->display = vd_display;
    vd->control = vd_control;
    vd->manage = vd_manage;

    vc_tv_register_callback(tvservice_cb, vd);

    if (query_resolution(vd, &sys->display_width, &sys->display_height) >= 0) {
        vout_display_SendEventDisplaySize(vd, sys->display_width, sys->display_height);
    } else {
        sys->display_width = vd->cfg->display.width;
        sys->display_height = vd->cfg->display.height;
    }

    sys->dmx_handle = vc_dispmanx_display_open(0);
    vd->info.subpicture_chromas = subpicture_chromas;

out:
    if (ret != VLC_SUCCESS)
        Close(object);

    return ret;
}
示例#22
0
文件: render.c 项目: mstorsjo/vlc
static void CreateBuffers(vout_display_t *vd, const vout_display_cfg_t *cfg)
{
    const video_format_t *fmt = &vd->source;
    vout_display_sys_t *sys = vd->sys;
    xcb_connection_t *conn = sys->conn;

    xcb_create_pixmap(conn, 32, sys->drawable.crop, sys->root,
                      fmt->i_visible_width, fmt->i_visible_height);
    xcb_create_pixmap(conn, 32, sys->drawable.scale, sys->root,
                      cfg->display.width, cfg->display.height);
    xcb_render_create_picture(conn, sys->picture.crop, sys->drawable.crop,
                              sys->format.argb, 0, NULL);
    xcb_render_create_picture(conn, sys->picture.scale, sys->drawable.scale,
                              sys->format.argb, 0, NULL);

    vout_display_place_t *place = &sys->place;
    vout_display_PlacePicture(place, fmt, cfg);

    /* Homogeneous coordinates transform from destination(place)
     * to source(fmt) */
    int32_t ax = place->height; /* multiply x instead of dividing y */
    int32_t ay = place->width; /* multiply y instead of dividing x */
    int32_t bx = 0;
    int32_t by = 0;

    switch (fmt->orientation) {
        case ORIENT_TOP_LEFT:
        case ORIENT_LEFT_TOP:
            break;
        case ORIENT_TOP_RIGHT:
        case ORIENT_RIGHT_TOP:
            ax *= -1;
            bx -= place->width;
            break;
        case ORIENT_BOTTOM_LEFT:
        case ORIENT_LEFT_BOTTOM:
            ay *= -1;
            by -= place->height;
            break;
        case ORIENT_BOTTOM_RIGHT:
        case ORIENT_RIGHT_BOTTOM:
            ax *= -1;
            ay *= -1;
            bx -= place->width;
            by -= place->height;
            break;
    }

    sys->src_x = bx;
    sys->src_y = by;

    xcb_render_transform_t transform = {
        0, 0, 0,
        0, 0, 0,
        /* Multiply z by width and height to compensate for x and y above */
        0, 0, place->width * place->height,
    };

    if (ORIENT_IS_SWAP(fmt->orientation)) {
        transform.matrix12 = ay * fmt->i_visible_width;
        transform.matrix21 = ax * fmt->i_visible_height;
    } else {
        transform.matrix11 = ax * fmt->i_visible_width;
        transform.matrix22 = ay * fmt->i_visible_height;
    }

    xcb_render_set_picture_transform(conn, sys->picture.crop, transform);

    if (likely(sys->filter != NULL))
        xcb_render_set_picture_filter(conn, sys->picture.crop,
                                      strlen(sys->filter), sys->filter,
                                      0, NULL);
}
示例#23
0
/**
 * VSXu update thread which do the rendering
 * @param p_this: the p_thread object
 */
static void *Thread( void *p_data )
{
    filter_t  *p_filter = (filter_t*)p_data;
    filter_sys_t *p_sys = p_filter->p_sys;

    // our abstract manager holder
    vsx_manager_abs* manager = 0;

    // temp audio buffer for sending to vsxu through manager
    float f_sample_buf[512];

    // vsxu logo intro
    vsx_logo_intro* intro = 0;

    vout_display_t *p_vd;

    video_format_t fmt;
    vlc_gl_t *gl;

    unsigned int i_last_width  = 0;
    unsigned int i_last_height = 0;
    bool first = true;
    bool run = true;

    /* Create the openGL provider */
    vout_thread_t  *p_vout;

    p_vout = (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) );
    if( !p_vout )
        goto error;

    video_format_Init( &fmt, 0 );
    video_format_Setup( &fmt, VLC_CODEC_RGB32,
                        p_sys->i_width, p_sys->i_height, 0, 1 );
    fmt.i_sar_num = 1;
    fmt.i_sar_den = 1;

    vout_display_state_t state;
    memset( &state, 0, sizeof(state) );
    state.cfg.display.sar.num = 1;
    state.cfg.display.sar.den = 1;
    state.cfg.is_display_filled = true;
    state.cfg.zoom.num = 1;
    state.cfg.zoom.den = 1;
    state.sar.num = 1;
    state.sar.den = 1;

    p_vd = vout_NewDisplay( p_vout, &fmt, &state, "opengl", 300000, 1000000 );
    if( !p_vd )
    {
        vlc_object_release( p_vout );
        goto error;
    }
    var_Create( p_vout, "fullscreen", VLC_VAR_BOOL );
    var_AddCallback( p_vout, "fullscreen", VoutCallback, p_vd );

    gl = vout_GetDisplayOpengl( p_vd );
    if( !gl )
    {
        var_DelCallback( p_vout, "fullscreen", VoutCallback, p_vd );
        vout_DeleteDisplay( p_vd, NULL );
        vlc_object_release( p_vout );
        goto error;
    }

    // tell main thread we are ready
    vlc_sem_post( &p_sys->ready );

    while ( run )
    {
        /* Manage the events */
        vout_ManageDisplay( p_vd, true );
        if( p_vd->cfg->display.width  != i_last_width ||
            p_vd->cfg->display.height != i_last_height )
        {
            /* FIXME it is not perfect as we will have black bands */
            vout_display_place_t place;
            vout_display_PlacePicture( &place, &p_vd->source, p_vd->cfg, false );

            i_last_width  = p_vd->cfg->display.width;
            i_last_height = p_vd->cfg->display.height;
        }

        // look for control commands from outside the thread
        vlc_mutex_lock( &p_sys->lock );
            if( p_sys->b_quit )
            {
                run = false;
            }
        vlc_mutex_unlock( &p_sys->lock );

        if (first)
        {
            // only run this once
            first = false;

            // create a new manager
            manager = manager_factory();

            // init manager with the shared path and sound input type.
            manager->init( 0, "media_player" );

            // only show logo once
            // keep track of iterations
            static int i_iterations = 0;
            if ( i_iterations++ < 1 )
            {
                intro = new vsx_logo_intro();
                intro->set_destroy_textures( false );
            }
        }

        // lock cyclic buffer mutex and copy floats
        vlc_mutex_lock( &p_sys->cyclic_block_mutex );
            block_holder* bh = p_sys->vsxu_cyclic_buffer->consume();
            memcpy( &f_sample_buf[0], (void*)(&bh->data[0]), sizeof(float) * 512 );
        vlc_mutex_unlock( &p_sys->cyclic_block_mutex );

        // send sound pointer to vsxu
        manager->set_sound_wave( &f_sample_buf[0] );

        // render vsxu engine
        if (manager) manager->render();

        // render intro
        if (intro) intro->draw();

        // swap buffers etc.
        if( !vlc_gl_Lock(gl) )
        {
            vlc_gl_Swap( gl );
            vlc_gl_Unlock( gl );
        }
    }

    // stop vsxu nicely (unloads textures and frees memory)
    if (manager) manager->stop();

    // call manager factory to destruct our manager object
    if (manager) manager_destroy( manager );

    // delete the intro (if ever allocated)
    if (intro) delete intro;

    var_DelCallback( p_vout, "fullscreen", VoutCallback, p_vd );

    // clean out vlc opengl stuff
    vout_DeleteDisplay( p_vd, NULL );
    vlc_object_release( p_vout );

    // clean up the cyclic buffer
    vlc_mutex_lock( &p_sys->cyclic_block_mutex );
        p_sys->vsxu_cyclic_buffer->reset();
    vlc_mutex_unlock( &p_sys->cyclic_block_mutex );

    // die
    return NULL;

error:
    p_sys->b_error = true;
    vlc_sem_post( &p_sys->ready );
    return NULL;
}
示例#24
0
文件: glspectrum.c 项目: AsamQi/vlc
/**
 * Update thread which do the rendering
 * @param p_this: the p_thread object
 */
static void *Thread( void *p_data )
{
    filter_t  *p_filter = (filter_t*)p_data;
    filter_sys_t *p_sys = p_filter->p_sys;

    video_format_t fmt;
    vlc_gl_t *gl;
    unsigned int i_last_width = 0;
    unsigned int i_last_height = 0;

    /* Create the openGL provider */
    p_sys->p_vout =
        (vout_thread_t *)vlc_object_create(p_filter, sizeof(vout_thread_t));
    if (!p_sys->p_vout)
        goto error;

    /* Configure the video format for the opengl provider. */
    video_format_Init(&fmt, 0);
    video_format_Setup(&fmt, VLC_CODEC_RGB32,
                       p_sys->i_width, p_sys->i_height, 0, 1 );
    fmt.i_sar_num = 1;
    fmt.i_sar_den = 1;

    /* Init vout state. */
    vout_display_state_t state;
    memset(&state, 0, sizeof(state));
    state.cfg.display.sar.num = 1;
    state.cfg.display.sar.den = 1;
    state.cfg.is_display_filled = true;
    state.cfg.zoom.num = 1;
    state.cfg.zoom.den = 1;
    state.sar.num = 1;
    state.sar.den = 1;

    p_sys->p_vd = vout_NewDisplay(p_sys->p_vout, &fmt, &state,
                                  "opengl", 1000000, 1000000);
    if (!p_sys->p_vd)
    {
        vlc_object_release(p_sys->p_vout);
        goto error;
    }

    gl = vout_GetDisplayOpengl(p_sys->p_vd);
    if (!gl)
    {
        vout_DeleteDisplay(p_sys->p_vd, NULL);
        vlc_object_release(p_sys->p_vout);
        goto error;
    }

    vlc_sem_post(&p_sys->ready);

    initOpenGLScene();

    float height[NB_BANDS] = {0};

    while (1)
    {
        block_t *block = block_FifoGet(p_sys->fifo);

        int canc = vlc_savecancel();

        /* Manage the events */
        vout_ManageDisplay(p_sys->p_vd, true);
        if (p_sys->p_vd->cfg->display.width != i_last_width ||
            p_sys->p_vd->cfg->display.height != i_last_height)
        {
            /* FIXME it is not perfect as we will have black bands */
            vout_display_place_t place;
            vout_display_PlacePicture(&place, &p_sys->p_vd->source,
                                      p_sys->p_vd->cfg, false);

            i_last_width  = p_sys->p_vd->cfg->display.width;
            i_last_height = p_sys->p_vd->cfg->display.height;
        }

        /* Horizontal scale for 20-band equalizer */
        const unsigned xscale[] = {0,1,2,3,4,5,6,7,8,11,15,20,27,
                                   36,47,62,82,107,141,184,255};

        fft_state *p_state; /* internal FFT data */

        unsigned i, j;
        float p_output[FFT_BUFFER_SIZE];           /* Raw FFT Result  */
        int16_t p_buffer1[FFT_BUFFER_SIZE];        /* Buffer on which we perform
                                                      the FFT (first channel) */
        int16_t p_dest[FFT_BUFFER_SIZE];           /* Adapted FFT result */
        float *p_buffl = (float*)block->p_buffer;  /* Original buffer */

        int16_t  *p_buffs;                         /* int16_t converted buffer */
        int16_t  *p_s16_buff;                      /* int16_t converted buffer */

        /* Allocate the buffer only if the number of samples change */
        if (block->i_nb_samples != p_sys->i_prev_nb_samples)
        {
            free(p_sys->p_prev_s16_buff);
            p_sys->p_prev_s16_buff = malloc(block->i_nb_samples *
                                            p_sys->i_channels *
                                            sizeof(int16_t));
            if (!p_sys->p_prev_s16_buff)
                goto release;
            p_sys->i_prev_nb_samples = block->i_nb_samples;
        }
        p_buffs = p_s16_buff = p_sys->p_prev_s16_buff;

        /* Convert the buffer to int16_t
           Pasted from float32tos16.c */
        for (i = block->i_nb_samples * p_sys->i_channels; i--;)
        {
            union {float f; int32_t i;} u;

            u.f = *p_buffl + 384.0;
            if (u.i > 0x43c07fff)
                *p_buffs = 32767;
            else if (u.i < 0x43bf8000)
                *p_buffs = -32768;
            else
                *p_buffs = u.i - 0x43c00000;

            p_buffl++; p_buffs++;
        }
        p_state = visual_fft_init();
        if (!p_state)
        {
            msg_Err(p_filter,"unable to initialize FFT transform");
            goto release;
        }
        p_buffs = p_s16_buff;
        for (i = 0 ; i < FFT_BUFFER_SIZE; i++)
        {
            p_output[i] = 0;
            p_buffer1[i] = *p_buffs;

            p_buffs += p_sys->i_channels;
            if (p_buffs >= &p_s16_buff[block->i_nb_samples * p_sys->i_channels])
                p_buffs = p_s16_buff;
        }
        fft_perform (p_buffer1, p_output, p_state);

        for (i = 0; i< FFT_BUFFER_SIZE; ++i)
            p_dest[i] = p_output[i] *  (2 ^ 16)
                        / ((FFT_BUFFER_SIZE / 2 * 32768) ^ 2);

        for (i = 0 ; i < NB_BANDS; i++)
        {
            /* Decrease the previous size of the bar. */
            height[i] -= BAR_DECREMENT;
            if (height[i] < 0)
                height[i] = 0;

            int y = 0;
            /* We search the maximum on one scale
               to determine the current size of the bar. */
            for (j = xscale[i]; j < xscale[i + 1]; j++)
            {
                if (p_dest[j] > y)
                     y = p_dest[j];
            }
            /* Calculate the height of the bar */
            float new_height = y != 0 ? log(y) * 0.4 : 0;
            height[i] = new_height > height[i]
                        ? new_height : height[i];
        }

        /* Determine the camera rotation angle. */
        p_sys->f_rotationAngle += p_sys->f_rotationIncrement;
        if (p_sys->f_rotationAngle <= -ROTATION_MAX)
            p_sys->f_rotationIncrement = ROTATION_INCREMENT;
        else if (p_sys->f_rotationAngle >= ROTATION_MAX)
            p_sys->f_rotationIncrement = -ROTATION_INCREMENT;

        /* Render the frame. */
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glPushMatrix();
            glRotatef(p_sys->f_rotationAngle, 0, 1, 0);
            drawBars(height);
        glPopMatrix();

        /* Wait to swapp the frame on time. */
        mwait(block->i_pts + (block->i_length / 2));
        if (!vlc_gl_Lock(gl))
        {
            vlc_gl_Swap(gl);
            vlc_gl_Unlock(gl);
        }

release:
        block_Release(block);
        vlc_restorecancel(canc);
    }

    assert(0);

error:
    p_sys->b_error = true;
    vlc_sem_post(&p_sys->ready);
    return NULL;
}
示例#25
0
文件: kva.c 项目: IAPark/vlc
/*****************************************************************************
 * Control: control facility for the vout
 *****************************************************************************/
static int Control( vout_display_t *vd, int query, va_list args )
{
    vout_display_sys_t *sys = vd->sys;

    switch (query)
    {
    case VOUT_DISPLAY_HIDE_MOUSE:
    {
        POINTL ptl;

        WinQueryPointerPos( HWND_DESKTOP, &ptl );
        if( !sys->is_mouse_hidden &&
            WinWindowFromPoint( HWND_DESKTOP, &ptl, TRUE ) == sys->client )
        {
            WinShowPointer( HWND_DESKTOP, FALSE );
            sys->is_mouse_hidden = true;
        }

        return VLC_SUCCESS;
    }

    case VOUT_DISPLAY_CHANGE_FULLSCREEN:
    {
        bool fs = va_arg(args, int);

        WinPostMsg( sys->client, WM_VLC_FULLSCREEN_CHANGE, MPFROMLONG(fs), 0 );
        return VLC_SUCCESS;
    }

    case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
    {
        const unsigned state = va_arg( args, unsigned );
        const bool is_on_top = (state & VOUT_WINDOW_STATE_ABOVE) != 0;

        if( is_on_top )
            WinSetWindowPos( sys->frame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER );

        sys->is_on_top = is_on_top;

        return VLC_SUCCESS;
    }

    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
    case VOUT_DISPLAY_CHANGE_ZOOM:
    {
        const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);

        WinPostMsg( sys->client, WM_VLC_SIZE_CHANGE,
                    MPFROMLONG( cfg->display.width ),
                    MPFROMLONG( cfg->display.height ));
        return VLC_SUCCESS;
    }

    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
    case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
    {
        if( query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT )
        {
            vout_display_place_t place;
            vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);

            sys->kvas.ulAspectWidth  = place.width;
            sys->kvas.ulAspectHeight = place.height;
        }
        else
        {
            video_format_t src_rot;
            video_format_ApplyRotation(&src_rot, &vd->source);

            sys->kvas.rclSrcRect.xLeft   = src_rot.i_x_offset;
            sys->kvas.rclSrcRect.yTop    = src_rot.i_y_offset;
            sys->kvas.rclSrcRect.xRight  = src_rot.i_x_offset +
                                           src_rot.i_visible_width;
            sys->kvas.rclSrcRect.yBottom = src_rot.i_y_offset +
                                           src_rot.i_visible_height;
        }

        kvaSetup( &sys->kvas );

        return VLC_SUCCESS;
    }

    case VOUT_DISPLAY_RESET_PICTURES:
    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
        /* TODO */
        break;
    }

    msg_Err(vd, "Unsupported query(=%d) in vout display KVA", query);
    return VLC_EGENERIC;
}