Exemple #1
0
static int DirectXCreatePool(vout_display_t *vd,
                             bool *use_overlay, video_format_t *fmt)
{
    vout_display_sys_t *sys = vd->sys;

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

    if (DirectXCreatePictureResource(vd, use_overlay, fmt))
        return VLC_EGENERIC;

    /* Create the associated picture */
    picture_resource_t resource = { .p_sys = sys->picsys };
    picture_t *picture = picture_NewFromResource(fmt, &resource);
    if (!picture) {
        DirectXDestroyPictureResource(vd);
        free(sys->picsys);
        return VLC_ENOMEM;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t cfg;
    memset(&cfg, 0, sizeof(cfg));
    cfg.picture_count = 1;
    cfg.picture       = &picture;
    cfg.lock          = DirectXLock;
    cfg.unlock        = DirectXUnlock;

    sys->pool = picture_pool_NewExtended(&cfg);
    if (!sys->pool) {
        picture_Release(picture);
        DirectXDestroyPictureResource(vd);
        return VLC_ENOMEM;
    }
    return VLC_SUCCESS;
}
static void DirectXDestroyPool(vout_display_t *vd)
{
    vout_display_sys_t *sys = vd->sys;

    if (sys->pool) {
        DirectXDestroyPictureResource(vd);
        picture_pool_Release(sys->pool);
    }
    sys->pool = NULL;
}
Exemple #2
0
/**
 * Return a direct buffer
 */
static picture_t *Get(vout_display_t *vd)
{
    vout_display_sys_t *sys = vd->sys;

    if (!sys->pool) {
        picture_resource_t rsc;

        memset(&rsc, 0, sizeof(rsc));

        if (sys->overlay) {
            SDL_Overlay *ol = sys->overlay;

            for (int i = 0; i < ol->planes; i++) {
                rsc.p[i].p_pixels = ol->pixels[ i > 0 && sys->is_uv_swapped ? (3-i) : i];
                rsc.p[i].i_pitch  = ol->pitches[i > 0 && sys->is_uv_swapped ? (3-i) : i];
                rsc.p[i].i_lines  = ol->h;
                if (ol->format == SDL_YV12_OVERLAY ||
                    ol->format == SDL_IYUV_OVERLAY)
                    rsc.p[i].i_lines /= 2;

            }
        } else {
            const int x = sys->place.x;
            const int y = sys->place.y;

            SDL_Surface *sf = sys->display;
            SDL_FillRect(sf, NULL, 0);

            assert(x >= 0 && y >= 0);
            rsc.p[0].p_pixels = (uint8_t*)sf->pixels + y * sf->pitch + x * ((sf->format->BitsPerPixel + 7) / 8);
            rsc.p[0].i_pitch  = sf->pitch;
            rsc.p[0].i_lines  = vd->fmt.i_height;
        }

        picture_t *picture = picture_NewFromResource(&vd->fmt, &rsc);;
        if (!picture)
            return NULL;

        sys->pool = picture_pool_New(1, &picture);
        if (!sys->pool)
            return NULL;
    }

    return picture_pool_Get(sys->pool);
}
Exemple #3
0
static picture_t *DxAllocPicture(vlc_va_t *va, const video_format_t *fmt, unsigned index)
{
    video_format_t src_fmt = *fmt;
    src_fmt.i_chroma = VLC_CODEC_D3D9_OPAQUE;
    picture_sys_t *pic_sys = calloc(1, sizeof(*pic_sys));
    if (unlikely(pic_sys == NULL))
        return NULL;
    pic_sys->surface = (LPDIRECT3DSURFACE9) va->sys->dx_sys.hw_surface[index];

    picture_resource_t res = {
        .p_sys = pic_sys,
    };
    picture_t *pic = picture_NewFromResource(&src_fmt, &res);
    if (unlikely(pic == NULL))
    {
        free(pic_sys);
        return NULL;
    }
    return pic;
}
Exemple #4
0
static int DirectXCreatePool(vout_display_t *vd,
                             bool *use_overlay, video_format_t *fmt)
{
    vout_display_sys_t *sys = vd->sys;

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

    if (DirectXCreatePictureResource(vd, use_overlay, fmt))
        return VLC_EGENERIC;

    /* Create the associated picture */
    picture_resource_t *rsc = &sys->resource;
    for (int i = 0; i < PICTURE_PLANE_MAX; i++) {
        rsc->p[i].p_pixels = NULL;
        rsc->p[i].i_pitch  = 0;
        rsc->p[i].i_lines  = 0;
    }
    picture_t *picture = picture_NewFromResource(fmt, rsc);
    if (!picture) {
        DirectXDestroyPictureResource(vd);
        free(rsc->p_sys);
        return VLC_ENOMEM;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t cfg;
    memset(&cfg, 0, sizeof(cfg));
    cfg.picture_count = 1;
    cfg.picture       = &picture;
    cfg.lock          = DirectXLock;
    cfg.unlock        = DirectXUnlock;

    sys->pool = picture_pool_NewExtended(&cfg);
    if (!sys->pool) {
        picture_Release(picture);
        DirectXDestroyPictureResource(vd);
        return VLC_ENOMEM;
    }
    return VLC_SUCCESS;
}
Exemple #5
0
/**
 * Return a pool of direct buffers
 */
static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
{
    vout_display_sys_t *sys = vd->sys;
    VLC_UNUSED(count);

    if (!sys->pool) {
        picture_resource_t rsc;

        memset(&rsc, 0, sizeof(rsc));
        rsc.p[0].p_pixels = aa_image(sys->aa_context);
        rsc.p[0].i_pitch = aa_imgwidth(sys->aa_context);
        rsc.p[0].i_lines = aa_imgheight(sys->aa_context);

        picture_t *p_picture = picture_NewFromResource(&vd->fmt, &rsc);
        if (!p_picture)
            return NULL;

        sys->pool = picture_pool_New(1, &p_picture);
    }
    return sys->pool;
}
Exemple #6
0
static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt)
{
    picture_t *p_pic;
    picture_resource_t rsc;
    picture_sys_t *p_picsys = calloc(1, sizeof(*p_picsys));

    if (unlikely(p_picsys == NULL))
        return NULL;

    p_picsys->p_vd_sys = sys;

    memset(&rsc, 0, sizeof(picture_resource_t));
    rsc.p_sys = p_picsys,

    p_pic = picture_NewFromResource(fmt, &rsc);
    if (!p_pic)
    {
        free(p_picsys);
        return NULL;
    }
    return p_pic;
}
Exemple #7
0
static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt,
                               bool b_opaque)
{
    picture_t *p_pic;
    picture_resource_t rsc;
    picture_sys_t *p_picsys = calloc(1, sizeof(*p_picsys));

    if (unlikely(p_picsys == NULL))
        return NULL;


    memset(&rsc, 0, sizeof(picture_resource_t));
    rsc.p_sys = p_picsys;

    if (b_opaque)
    {
        p_picsys->hw.b_vd_ref = true;
        p_picsys->hw.p_surface = sys->p_window->p_surface;
        p_picsys->hw.p_jsurface =  sys->p_window->p_jsurface;
        p_picsys->hw.i_index = -1;
        vlc_mutex_init(&p_picsys->hw.lock);
        rsc.pf_destroy = AndroidOpaquePicture_DetachVout;
    }
    else
    {
        p_picsys->sw.p_vd_sys = sys;
        rsc.pf_destroy = AndroidPicture_Destroy;
    }

    p_pic = picture_NewFromResource(fmt, &rsc);
    if (!p_pic)
    {
        free(p_picsys);
        return NULL;
    }
    return p_pic;
}
Exemple #8
0
static picture_t *DxAllocPicture(vlc_va_t *va, const video_format_t *fmt, unsigned index)
{
    video_format_t src_fmt = *fmt;
    src_fmt.i_chroma = VLC_CODEC_D3D11_OPAQUE;
    picture_sys_t *pic_sys = calloc(1, sizeof(*pic_sys));
    if (unlikely(pic_sys == NULL))
        return NULL;

    pic_sys->decoder  = (ID3D11VideoDecoderOutputView*) va->sys->dx_sys.hw_surface[index];
    ID3D11VideoDecoderOutputView_GetResource(pic_sys->decoder, (ID3D11Resource**) &pic_sys->texture);
    pic_sys->context  = va->sys->d3dctx;

    picture_resource_t res = {
        .p_sys      = pic_sys,
        .pf_destroy = DestroyPicture,
    };
    picture_t *pic = picture_NewFromResource(&src_fmt, &res);
    if (unlikely(pic == NULL))
    {
        free(pic_sys);
        return NULL;
    }
    return pic;
}
Exemple #9
0
static int Open(vlc_object_t *p_this)
{
    vout_display_t *vd = (vout_display_t*)p_this;

    video_format_t fmt = vd->fmt;

    if (fmt.i_chroma != VLC_CODEC_ANDROID_OPAQUE)
        return VLC_EGENERIC;

    /* Allocate structure */
    vout_display_sys_t *sys = (struct vout_display_sys_t*)calloc(1, sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;

    sys->p_library = LoadNativeWindowAPI(&sys->native_window);
    if (!sys->p_library)
    {
        free(sys);
        msg_Err(vd, "Could not initialize NativeWindow API.");
        return VLC_EGENERIC;
    }
    sys->fmt = fmt;
    video_format_t subpicture_format = sys->fmt;
    subpicture_format.i_chroma = VLC_CODEC_RGBA;
    /* Create a RGBA picture for rendering subtitles. */
    sys->subtitles_picture = picture_NewFromFormat(&subpicture_format);

    /* Export the subpicture capability of this vout. */
    vd->info.subpicture_chromas = subpicture_chromas;

    int i_pictures = POOL_SIZE;
    picture_t** pictures = calloc(sizeof(*pictures), i_pictures);
    if (!pictures)
        goto error;
    for (int i = 0; i < i_pictures; i++)
    {
        picture_sys_t *p_picsys = calloc(1, sizeof(*p_picsys));
        if (unlikely(p_picsys == NULL))
            goto error;

        picture_resource_t resource = { .p_sys = p_picsys };
        picture_t *picture = picture_NewFromResource(&fmt, &resource);
        if (!picture)
        {
            free(p_picsys);
            goto error;
        }
        pictures[i] = picture;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = i_pictures;
    pool_cfg.picture       = pictures;
    pool_cfg.lock          = LockSurface;
    pool_cfg.unlock        = UnlockSurface;

    sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!sys->pool)
    {
        for (int i = 0; i < i_pictures; i++)
            picture_Release(pictures[i]);
        goto error;
    }

    /* Setup vout_display */
    vd->sys     = sys;
    vd->fmt     = fmt;
    vd->pool    = Pool;
    vd->display = Display;
    vd->control = Control;
    vd->prepare = NULL;
    vd->manage  = Manage;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, false);

    return VLC_SUCCESS;

error:
    free(pictures);
    Close(p_this);
    return VLC_ENOMEM;
}
Exemple #10
0
/**
 * It creates the pool of picture (only 1).
 *
 * Each picture has an associated offscreen surface in video memory
 * depending on hardware capabilities the picture chroma will be as close
 * as possible to the orginal render chroma to reduce CPU conversion overhead
 * and delegate this work to video card GPU
 */
static int Direct3DCreatePool(vout_display_t *vd, video_format_t *fmt)
{
    vout_display_sys_t *sys = vd->sys;
    LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;

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

    /* Find the appropriate D3DFORMAT for the render chroma, the format will be the closest to
     * the requested chroma which is usable by the hardware in an offscreen surface, as they
     * typically support more formats than textures */
    const d3d_format_t *d3dfmt = Direct3DFindFormat(vd, fmt->i_chroma, sys->d3dpp.BackBufferFormat);
    if (!d3dfmt) {
        msg_Err(vd, "surface pixel format is not supported.");
        return VLC_EGENERIC;
    }
    fmt->i_chroma = d3dfmt->fourcc;
    fmt->i_rmask  = d3dfmt->rmask;
    fmt->i_gmask  = d3dfmt->gmask;
    fmt->i_bmask  = d3dfmt->bmask;

    /* We create one picture.
     * It is useless to create more as we can't be used for direct rendering */

    /* Create a surface */
    LPDIRECT3DSURFACE9 surface;
    HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(d3ddev,
                                                              fmt->i_width,
                                                              fmt->i_height,
                                                              d3dfmt->format,
                                                              D3DPOOL_DEFAULT,
                                                              &surface,
                                                              NULL);
    if (FAILED(hr)) {
        msg_Err(vd, "Failed to create picture surface. (hr=0x%lx)", hr);
        return VLC_EGENERIC;
    }
    /* fill surface with black color */
    IDirect3DDevice9_ColorFill(d3ddev, surface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0));

    /* Create the associated picture */
    picture_resource_t *rsc = &sys->resource;
    rsc->p_sys = malloc(sizeof(*rsc->p_sys));
    if (!rsc->p_sys) {
        IDirect3DSurface9_Release(surface);
        return VLC_ENOMEM;
    }
    rsc->p_sys->surface = surface;
    rsc->p_sys->fallback = NULL;
    for (int i = 0; i < PICTURE_PLANE_MAX; i++) {
        rsc->p[i].p_pixels = NULL;
        rsc->p[i].i_pitch = 0;
        rsc->p[i].i_lines = fmt->i_height / (i > 0 ? 2 : 1);
    }
    picture_t *picture = picture_NewFromResource(fmt, rsc);
    if (!picture) {
        IDirect3DSurface9_Release(surface);
        free(rsc->p_sys);
        return VLC_ENOMEM;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = 1;
    pool_cfg.picture       = &picture;
    pool_cfg.lock          = Direct3DLockSurface;
    pool_cfg.unlock        = Direct3DUnlockSurface;

    sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!sys->pool) {
        picture_Release(picture);
        IDirect3DSurface9_Release(surface);
        return VLC_ENOMEM;
    }
    return VLC_SUCCESS;
}
Exemple #11
0
picture_t *picture_NewFromFormat( const video_format_t *p_fmt )
{
    return picture_NewFromResource( p_fmt, NULL );
}
Exemple #12
0
static picture_pool_t *vd_pool(vout_display_t *vd, unsigned count)
{
    vout_display_sys_t *sys = vd->sys;
    picture_resource_t picture_res;
    picture_pool_configuration_t picture_pool_cfg;
    video_format_t fmt = vd->fmt;
    MMAL_STATUS_T status;
    unsigned i;

    if (sys->picture_pool) {
        if (sys->num_buffers < count)
            msg_Warn(vd, "Picture pool with %u pictures requested, but we already have one with %u pictures",
                            count, sys->num_buffers);

        goto out;
    }

    if (sys->opaque) {
        if (count <= NUM_ACTUAL_OPAQUE_BUFFERS)
            count = NUM_ACTUAL_OPAQUE_BUFFERS;
    }

    if (count < sys->input->buffer_num_recommended)
        count = sys->input->buffer_num_recommended;

#ifndef NDEBUG
    msg_Dbg(vd, "Creating picture pool with %u pictures", count);
#endif

    sys->input->buffer_num = count;
    status = mmal_port_enable(sys->input, input_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to enable input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
        goto out;
    }

    status = mmal_component_enable(sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to enable component %s (status=%"PRIx32" %s)",
                        sys->component->name, status, mmal_status_to_string(status));
        goto out;
    }

    sys->num_buffers = count;
    sys->pool = mmal_pool_create(sys->num_buffers, sys->input->buffer_size);
    if (!sys->pool) {
        msg_Err(vd, "Failed to create MMAL pool for %u buffers of size %"PRIu32,
                        count, sys->input->buffer_size);
        goto out;
    }

    memset(&picture_res, 0, sizeof(picture_resource_t));
    sys->pictures = calloc(sys->num_buffers, sizeof(picture_t *));
    for (i = 0; i < sys->num_buffers; ++i) {
        picture_res.p_sys = calloc(1, sizeof(picture_sys_t));
        picture_res.p_sys->owner = (vlc_object_t *)vd;
        picture_res.p_sys->queue = sys->pool->queue;

        sys->pictures[i] = picture_NewFromResource(&fmt, &picture_res);
        if (!sys->pictures[i]) {
            msg_Err(vd, "Failed to create picture");
            free(picture_res.p_sys);
            goto out;
        }

        sys->pictures[i]->i_planes = sys->i_planes;
        memcpy(sys->pictures[i]->p, sys->planes, sys->i_planes * sizeof(plane_t));
    }

    memset(&picture_pool_cfg, 0, sizeof(picture_pool_configuration_t));
    picture_pool_cfg.picture_count = sys->num_buffers;
    picture_pool_cfg.picture = sys->pictures;
    picture_pool_cfg.lock = mmal_picture_lock;
    picture_pool_cfg.unlock = mmal_picture_unlock;

    sys->picture_pool = picture_pool_NewExtended(&picture_pool_cfg);
    if (!sys->picture_pool) {
        msg_Err(vd, "Failed to create picture pool");
        goto out;
    }

out:
    return sys->picture_pool;
}
Exemple #13
0
/*****************************************************************************
 * OpenDisplay: open and initialize KVA device
 *****************************************************************************
 * Open and initialize display according to preferences specified in the vout
 * thread fields.
 *****************************************************************************/
static int OpenDisplay( vout_display_t *vd, video_format_t *fmt )
{
    vout_display_sys_t * sys = vd->sys;
    const vlc_fourcc_t *fallback;
    bool b_hw_accel = 0;
    FOURCC i_kva_fourcc;
    int i_chroma_shift;
    char sz_title[ 256 ];
    RECTL rcl;
    int w, h;

    msg_Dbg( vd, "render chroma = %4.4s", ( const char * )&fmt->i_chroma );

    for( int pass = 0; pass < 2 && !b_hw_accel; pass++ )
    {
        fallback = ( pass == 0 ) ? vlc_fourcc_GetYUVFallback( fmt->i_chroma ) :
                   vlc_fourcc_GetRGBFallback( fmt->i_chroma );

        for( int i = 0; fallback[ i ]; i++ )
        {
            switch( fallback[ i ])
            {
            case VLC_CODEC_YV12:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_YV12;
                i_kva_fourcc = FOURCC_YV12;
                i_chroma_shift = 1;
                break;

            case VLC_CODEC_YUYV:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_YUY2;
                i_kva_fourcc = FOURCC_Y422;
                i_chroma_shift = 0;
                break;

            case VLC_CODEC_YV9:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_YVU9;
                i_kva_fourcc = FOURCC_YVU9;
                i_chroma_shift = 2;
                break;

            case VLC_CODEC_RGB32:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_BGR32;
                i_kva_fourcc = FOURCC_BGR4;
                i_chroma_shift = 0;
                break;

            case VLC_CODEC_RGB24:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_BGR24;
                i_kva_fourcc = FOURCC_BGR3;
                i_chroma_shift = 0;
                break;

            case VLC_CODEC_RGB16:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_BGR16;
                i_kva_fourcc = FOURCC_R565;
                i_chroma_shift = 0;
                break;

            case VLC_CODEC_RGB15:
                b_hw_accel = sys->kvac.ulInputFormatFlags & KVAF_BGR15;
                i_kva_fourcc = FOURCC_R555;
                i_chroma_shift = 0;
                break;
            }

            if( b_hw_accel )
            {
                fmt->i_chroma = fallback[ i ];
                break;
            }
        }
    }

    if( !b_hw_accel )
    {
        msg_Err( vd, "Ooops. There is no fourcc supported by KVA at all.");

        return VLC_EGENERIC;
    }

    /* Set the RGB masks */
    fmt->i_rmask = sys->kvac.ulRMask;
    fmt->i_gmask = sys->kvac.ulGMask;
    fmt->i_bmask = sys->kvac.ulBMask;

    msg_Dbg( vd, "output chroma = %4.4s", ( const char * )&fmt->i_chroma );
    msg_Dbg( vd, "KVA chroma = %4.4s", ( const char * )&i_kva_fourcc );

    w = vd->source.i_width;
    h = vd->source.i_height;

    sys->kvas.ulLength           = sizeof( KVASETUP );
    sys->kvas.szlSrcSize.cx      = w;
    sys->kvas.szlSrcSize.cy      = h;
    sys->kvas.rclSrcRect.xLeft   = 0;
    sys->kvas.rclSrcRect.yTop    = 0;
    sys->kvas.rclSrcRect.xRight  = w;
    sys->kvas.rclSrcRect.yBottom = h;
    sys->kvas.ulRatio            = KVAR_FORCEANY;
    sys->kvas.ulAspectWidth      = w;
    sys->kvas.ulAspectHeight     = h;
    sys->kvas.fccSrcColor        = i_kva_fourcc;
    sys->kvas.fDither            = TRUE;

    if( kvaSetup( &sys->kvas ))
    {
        msg_Err( vd, "cannot set up KVA");

        return VLC_EGENERIC;
    }

    /* Create the associated picture */
    picture_resource_t *rsc = &sys->resource;
    rsc->p_sys = malloc( sizeof( *rsc->p_sys ));
    if( !rsc->p_sys )
        return VLC_EGENERIC;

    rsc->p_sys->i_chroma_shift = i_chroma_shift;

    for( int i = 0; i < PICTURE_PLANE_MAX; i++ )
    {
        rsc->p[ i ].p_pixels = NULL;
        rsc->p[ i ].i_pitch  = 0;
        rsc->p[ i ].i_lines  = 0;
    }

    picture_t *picture = picture_NewFromResource( fmt, rsc );
    if( !picture )
        goto exit_picture;

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset( &pool_cfg, 0, sizeof( pool_cfg ));
    pool_cfg.picture_count = 1;
    pool_cfg.picture       = &picture;
    pool_cfg.lock          = KVALock;
    pool_cfg.unlock        = KVAUnlock;

    sys->pool = picture_pool_NewExtended( &pool_cfg );
    if( !sys->pool )
    {
        picture_Release( picture );

        goto exit_picture;
    }

    if (vd->cfg->display.title)
        snprintf( sz_title, sizeof( sz_title ), "%s", vd->cfg->display.title );
    else
        snprintf( sz_title, sizeof( sz_title ),
                  "%s (%4.4s to %4.4s - %s mode KVA output)",
                  VOUT_TITLE,
                  ( char * )&vd->fmt.i_chroma,
                  ( char * )&sys->kvas.fccSrcColor,
                  psz_video_mode[ sys->kvac.ulMode - 1 ]);
    WinSetWindowText( sys->frame, sz_title );

    sys->i_screen_width  = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
    sys->i_screen_height = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );

    if( sys->parent_window )
        WinQueryWindowRect( sys->parent, &sys->client_rect );
    else
    {
        sys->client_rect.xLeft   = ( sys->i_screen_width  - w ) / 2;
        sys->client_rect.yBottom = ( sys->i_screen_height - h ) / 2 ;
        sys->client_rect.xRight  = sys->client_rect.xLeft   + w;
        sys->client_rect.yTop    = sys->client_rect.yBottom + h;
    }

    rcl = sys->client_rect;

    WinCalcFrameRect( sys->frame, &rcl, FALSE);

    WinSetWindowPos( sys->frame, HWND_TOP,
                     rcl.xLeft, rcl.yBottom,
                     rcl.xRight - rcl.xLeft, rcl.yTop - rcl.yBottom,
                     SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW |
                     SWP_ACTIVATE );

    return VLC_SUCCESS;

exit_picture:
    free( rsc->p_sys );

    return VLC_EGENERIC;
}
Exemple #14
0
static int Open(vlc_object_t *p_this)
{
    vout_display_t *vd = (vout_display_t *)p_this;
    video_format_t fmt;
    video_format_ApplyRotation(&fmt, &vd->fmt);

    if (fmt.i_chroma == VLC_CODEC_ANDROID_OPAQUE)
        return VLC_EGENERIC;
    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;

    /* Allocate structure */
    vout_display_sys_t *sys = (struct vout_display_sys_t*) calloc(1, sizeof(*sys));
    if (!sys)
        goto error;

    /* */
    sys->p_library = InitLibrary(sys);
    if (!sys->p_library) {
        msg_Err(vd, "Could not initialize libandroid.so/libui.so/libgui.so/libsurfaceflinger_client.so!");
        goto error;
    }

    /* Setup chroma */
    char *psz_fcc = var_InheritString(vd, CFG_PREFIX "chroma");
    if( psz_fcc ) {
        fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_fcc);
        free(psz_fcc);
    } else
        fmt.i_chroma = VLC_CODEC_RGB32;

    switch(fmt.i_chroma) {
        case VLC_CODEC_RGB16:
            fmt.i_bmask = 0x0000001f;
            fmt.i_gmask = 0x000007e0;
            fmt.i_rmask = 0x0000f800;
            break;

        case VLC_CODEC_YV12:
        case VLC_CODEC_I420:
            fmt.i_chroma = VLC_CODEC_RGB32;
        case VLC_CODEC_RGB32:
            fmt.i_rmask  = 0x000000ff;
            fmt.i_gmask  = 0x0000ff00;
            fmt.i_bmask  = 0x00ff0000;
            break;

        default:
            return VLC_EGENERIC;
    }
    video_format_FixRgb(&fmt);

    msg_Dbg(vd, "Pixel format %4.4s", (char*)&fmt.i_chroma);
    sys->i_android_hal = ChromaToAndroidHal(fmt.i_chroma);
    if (sys->i_android_hal == -1)
        goto error;

    sys->fmt = fmt;
    UpdateLayout(sys);

    /* Create the associated picture */
    picture_sys_t *picsys = calloc(1, sizeof(picture_sys_t));
    if (unlikely(picsys == NULL))
        goto error;
    picsys->sys = sys;

    picture_resource_t resource = { .p_sys = picsys };
    picture_t *picture = picture_NewFromResource(&fmt, &resource);
    if (!picture) {
        free(picsys);
        goto error;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = 1;
    pool_cfg.picture       = &picture;
    pool_cfg.lock          = AndroidLockSurface;
    pool_cfg.unlock        = AndroidUnlockSurface;

    sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!sys->pool) {
        picture_Release(picture);
        goto error;
    }

    /* Setup vout_display */
    vd->sys     = sys;
    vd->fmt     = fmt;
    vd->pool    = Pool;
    vd->display = Display;
    vd->control = Control;
    vd->prepare = NULL;
    vd->manage  = Manage;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, false);

    return VLC_SUCCESS;

error:
    Close(p_this);
    return VLC_ENOMEM;
}
Exemple #15
0
static int Open(vlc_object_t *p_this)
{
    vout_display_t *vd = (vout_display_t *)p_this;
    vout_display_t *p_dec = vd;
    char ppsz_components[MAX_COMPONENTS_LIST_SIZE][OMX_MAX_STRINGNAME_SIZE];
    picture_t** pictures = NULL;
    OMX_PARAM_PORTDEFINITIONTYPE *def;

    static OMX_CALLBACKTYPE callbacks =
        { OmxEventHandler, OmxEmptyBufferDone, OmxFillBufferDone };

    if (InitOmxCore(p_this) != VLC_SUCCESS)
        return VLC_EGENERIC;

    int components = CreateComponentsList(p_this, "iv_renderer", ppsz_components);
    if (components <= 0) {
        DeinitOmxCore();
        return VLC_EGENERIC;
    }

    /* Allocate structure */
    vout_display_sys_t *p_sys = (struct vout_display_sys_t*) calloc(1, sizeof(*p_sys));
    if (!p_sys) {
        DeinitOmxCore();
        return VLC_ENOMEM;
    }

    vd->sys     = p_sys;
    strcpy(p_sys->psz_component, ppsz_components[0]);

    /* Load component */
    OMX_ERRORTYPE omx_error = pf_get_handle(&p_sys->omx_handle,
                                            p_sys->psz_component, vd, &callbacks);
    CHECK_ERROR(omx_error, "OMX_GetHandle(%s) failed (%x: %s)",
                p_sys->psz_component, omx_error, ErrorToString(omx_error));

    InitOmxEventQueue(&p_sys->event_queue);
    OMX_FIFO_INIT(&p_sys->port.fifo, pOutputPortPrivate);
    p_sys->port.b_direct = false;
    p_sys->port.b_flushed = true;

    OMX_PORT_PARAM_TYPE param;
    OMX_INIT_STRUCTURE(param);
    omx_error = OMX_GetParameter(p_sys->omx_handle, OMX_IndexParamVideoInit, &param);
    CHECK_ERROR(omx_error, "OMX_GetParameter(OMX_IndexParamVideoInit) failed (%x: %s)",
                omx_error, ErrorToString(omx_error));

    p_sys->port.i_port_index = param.nStartPortNumber;
    p_sys->port.b_valid = true;
    p_sys->port.omx_handle = p_sys->omx_handle;

    def = &p_sys->port.definition;
    OMX_INIT_STRUCTURE(*def);
    def->nPortIndex = p_sys->port.i_port_index;
    omx_error = OMX_GetParameter(p_sys->omx_handle, OMX_IndexParamPortDefinition, def);
    CHECK_ERROR(omx_error, "OMX_GetParameter(OMX_IndexParamPortDefinition) failed (%x: %s)",
                omx_error, ErrorToString(omx_error));

#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))

    def->format.video.nFrameWidth = vd->fmt.i_width;
    def->format.video.nFrameHeight = vd->fmt.i_height;
    def->format.video.nStride = 0;
    def->format.video.nSliceHeight = 0;
    p_sys->port.definition.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;

    if (!strcmp(p_sys->psz_component, "OMX.broadcom.video_render")) {
        def->format.video.nSliceHeight = ALIGN(def->format.video.nFrameHeight, 16);
    }

    omx_error = OMX_SetParameter(p_sys->omx_handle, OMX_IndexParamPortDefinition, &p_sys->port.definition);
    CHECK_ERROR(omx_error, "OMX_SetParameter(OMX_IndexParamPortDefinition) failed (%x: %s)",
                omx_error, ErrorToString(omx_error));
    OMX_GetParameter(p_sys->omx_handle, OMX_IndexParamPortDefinition, &p_sys->port.definition);

    if (def->format.video.nStride < (int) def->format.video.nFrameWidth)
        def->format.video.nStride = def->format.video.nFrameWidth;
    if (def->format.video.nSliceHeight < def->format.video.nFrameHeight)
        def->format.video.nSliceHeight = def->format.video.nFrameHeight;

    p_sys->port.pp_buffers =
            malloc(p_sys->port.definition.nBufferCountActual *
                   sizeof(OMX_BUFFERHEADERTYPE*));
    p_sys->port.i_buffers = p_sys->port.definition.nBufferCountActual;

    omx_error = OMX_SendCommand(p_sys->omx_handle, OMX_CommandStateSet, OMX_StateIdle, 0);
    CHECK_ERROR(omx_error, "OMX_CommandStateSet Idle failed (%x: %s)",
                omx_error, ErrorToString(omx_error));

    unsigned int i;
    for (i = 0; i < p_sys->port.i_buffers; i++) {
        omx_error = OMX_AllocateBuffer(p_sys->omx_handle, &p_sys->port.pp_buffers[i],
                                       p_sys->port.i_port_index, 0,
                                       p_sys->port.definition.nBufferSize);
        if (omx_error != OMX_ErrorNone)
            break;
        OMX_FIFO_PUT(&p_sys->port.fifo, p_sys->port.pp_buffers[i]);
    }
    if (omx_error != OMX_ErrorNone) {
        p_sys->port.i_buffers = i;
        for (i = 0; i < p_sys->port.i_buffers; i++)
            OMX_FreeBuffer(p_sys->omx_handle, p_sys->port.i_port_index, p_sys->port.pp_buffers[i]);
        msg_Err(vd, "OMX_AllocateBuffer failed (%x: %s)",
                omx_error, ErrorToString(omx_error));
        goto error;
    }

    omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
    CHECK_ERROR(omx_error, "Wait for Idle failed (%x: %s)",
                omx_error, ErrorToString(omx_error));

    omx_error = OMX_SendCommand(p_sys->omx_handle, OMX_CommandStateSet,
                                OMX_StateExecuting, 0);
    CHECK_ERROR(omx_error, "OMX_CommandStateSet Executing failed (%x: %s)",
                omx_error, ErrorToString(omx_error));
    omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
    CHECK_ERROR(omx_error, "Wait for Executing failed (%x: %s)",
                omx_error, ErrorToString(omx_error));

    if (!strcmp(p_sys->psz_component, "OMX.broadcom.video_render")) {
        OMX_CONFIG_DISPLAYREGIONTYPE config_display;
        OMX_INIT_STRUCTURE(config_display);
        config_display.nPortIndex = p_sys->port.i_port_index;

        config_display.set = OMX_DISPLAY_SET_SRC_RECT;
        config_display.src_rect.width = vd->cfg->display.width;
        config_display.src_rect.height = vd->cfg->display.height;
        OMX_SetConfig(p_sys->omx_handle, OMX_IndexConfigDisplayRegion, &config_display);
        config_display.set = OMX_DISPLAY_SET_FULLSCREEN;
        config_display.fullscreen = OMX_TRUE;
        OMX_SetConfig(p_sys->omx_handle, OMX_IndexConfigDisplayRegion, &config_display);

        UpdateDisplaySize(vd, vd->cfg);
    }


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

    fmt.i_chroma = VLC_CODEC_I420;
    video_format_FixRgb(&fmt);

    /* Setup vout_display */
    vd->fmt     = fmt;
    vd->pool    = Pool;
    vd->display = Display;
    vd->control = Control;
    vd->prepare = NULL;
    vd->manage  = NULL;

    /* Create the associated picture */
    pictures = calloc(p_sys->port.i_buffers, sizeof(*pictures));
    if (!pictures)
        goto error;
    for (unsigned int i = 0; i < p_sys->port.i_buffers; i++) {
        picture_sys_t *picsys = malloc(sizeof(*picsys));
        if (unlikely(picsys == NULL))
            goto error;
        picsys->sys = p_sys;

        picture_resource_t resource = { .p_sys = picsys };

        picture_t *picture = picture_NewFromResource(&fmt, &resource);
        if (unlikely(picture == NULL))
        {
            free(picsys);
            goto error;
        }
        pictures[i] = picture;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = p_sys->port.i_buffers;
    pool_cfg.picture       = pictures;
    pool_cfg.lock          = LockSurface;
    pool_cfg.unlock        = UnlockSurface;

    p_sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!p_sys->pool) {
        for (unsigned int i = 0; i < p_sys->port.i_buffers; i++)
            picture_Release(pictures[i]);
        goto error;
    }

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, true);

    free(pictures);
    return VLC_SUCCESS;

error:
    free(pictures);
    Close(p_this);
    return VLC_EGENERIC;
}
Exemple #16
0
Fichier : wingdi.c Projet : paa/vlc
static int Init(vout_display_t *vd,
                video_format_t *fmt, int width, int height)
{
    vout_display_sys_t *sys = vd->sys;

    /* */
    RECT *display = &sys->rect_display;
    display->left   = 0;
    display->top    = 0;
#ifdef MODULE_NAME_IS_wingapi
    display->right  = GXGetDisplayProperties().cxWidth;
    display->bottom = GXGetDisplayProperties().cyHeight;
#else
    display->right  = GetSystemMetrics(SM_CXSCREEN);;
    display->bottom = GetSystemMetrics(SM_CYSCREEN);;
#endif

    /* Initialize an offscreen bitmap for direct buffer operations. */

    /* */
    HDC window_dc = GetDC(sys->hvideownd);

    /* */
#ifdef MODULE_NAME_IS_wingapi
    GXDisplayProperties gx_displayprop = GXGetDisplayProperties();
    sys->i_depth = gx_displayprop.cBPP;
#else

    sys->i_depth = GetDeviceCaps(window_dc, PLANES) *
                   GetDeviceCaps(window_dc, BITSPIXEL);
#endif

    /* */
    msg_Dbg(vd, "GDI depth is %i", sys->i_depth);
    switch (sys->i_depth) {
    case 8:
        fmt->i_chroma = VLC_CODEC_RGB8;
        break;
    case 15:
        fmt->i_chroma = VLC_CODEC_RGB15;
        fmt->i_rmask  = 0x7c00;
        fmt->i_gmask  = 0x03e0;
        fmt->i_bmask  = 0x001f;
        break;
    case 16:
        fmt->i_chroma = VLC_CODEC_RGB16;
        fmt->i_rmask  = 0xf800;
        fmt->i_gmask  = 0x07e0;
        fmt->i_bmask  = 0x001f;
        break;
    case 24:
        fmt->i_chroma = VLC_CODEC_RGB24;
        fmt->i_rmask  = 0x00ff0000;
        fmt->i_gmask  = 0x0000ff00;
        fmt->i_bmask  = 0x000000ff;
        break;
    case 32:
        fmt->i_chroma = VLC_CODEC_RGB32;
        fmt->i_rmask  = 0x00ff0000;
        fmt->i_gmask  = 0x0000ff00;
        fmt->i_bmask  = 0x000000ff;
        break;
    default:
        msg_Err(vd, "screen depth %i not supported", sys->i_depth);
        return VLC_EGENERIC;
    }
    fmt->i_width  = width;
    fmt->i_height = height;

    uint8_t *p_pic_buffer;
    int     i_pic_pitch;
#ifdef MODULE_NAME_IS_wingapi
    GXOpenDisplay(sys->hvideownd, GX_FULLSCREEN);
    EventThreadUpdateTitle(sys->event, VOUT_TITLE " (WinGAPI output)");

    /* Filled by pool::lock() */
    p_pic_buffer = NULL;
    i_pic_pitch  = 0;
#else
    /* Initialize offscreen bitmap */
    BITMAPINFO *bi = &sys->bitmapinfo;
    memset(bi, 0, sizeof(BITMAPINFO) + 3 * sizeof(RGBQUAD));
    if (sys->i_depth > 8) {
        ((DWORD*)bi->bmiColors)[0] = fmt->i_rmask;
        ((DWORD*)bi->bmiColors)[1] = fmt->i_gmask;
        ((DWORD*)bi->bmiColors)[2] = fmt->i_bmask;;
    }

    BITMAPINFOHEADER *bih = &sys->bitmapinfo.bmiHeader;
    bih->biSize = sizeof(BITMAPINFOHEADER);
    bih->biSizeImage     = 0;
    bih->biPlanes        = 1;
    bih->biCompression   = (sys->i_depth == 15 ||
                            sys->i_depth == 16) ? BI_BITFIELDS : BI_RGB;
    bih->biBitCount      = sys->i_depth;
    bih->biWidth         = fmt->i_width;
    bih->biHeight        = -fmt->i_height;
    bih->biClrImportant  = 0;
    bih->biClrUsed       = 0;
    bih->biXPelsPerMeter = 0;
    bih->biYPelsPerMeter = 0;

    i_pic_pitch = bih->biBitCount * bih->biWidth / 8;
    sys->off_bitmap = CreateDIBSection(window_dc,
                                       (BITMAPINFO *)bih,
                                       DIB_RGB_COLORS,
                                       &p_pic_buffer, NULL, 0);

    sys->off_dc = CreateCompatibleDC(window_dc);

    SelectObject(sys->off_dc, sys->off_bitmap);
    ReleaseDC(sys->hvideownd, window_dc);

    EventThreadUpdateTitle(sys->event, VOUT_TITLE " (WinGDI output)");
#endif

    /* */
    picture_resource_t rsc;
    memset(&rsc, 0, sizeof(rsc));
#ifdef MODULE_NAME_IS_wingapi
    rsc.p_sys = malloc(sizeof(*rsc.p_sys));
    if (!rsc.p_sys)
        return VLC_EGENERIC;
    rsc.p_sys->vd = vd;
#endif
    rsc.p[0].p_pixels = p_pic_buffer;
    rsc.p[0].i_lines  = fmt->i_height;
    rsc.p[0].i_pitch  = i_pic_pitch;;

    picture_t *picture = picture_NewFromResource(fmt, &rsc);
    if (picture) {
        picture_pool_configuration_t cfg;
        memset(&cfg, 0, sizeof(cfg));
        cfg.picture_count = 1;
        cfg.picture = &picture;
#ifdef MODULE_NAME_IS_wingapi
        cfg.lock    = Lock;
        cfg.unlock  = Unlock;
#endif
        sys->pool = picture_pool_NewExtended(&cfg);
    } else {
        free(rsc.p_sys);
        sys->pool = NULL;
    }

    UpdateRects(vd, NULL, NULL, true);

    return VLC_SUCCESS;
}
Exemple #17
0
static int Init(vout_display_t *vd, video_format_t *fmt)
{
    vout_display_sys_t *sys = vd->sys;

    /* */
    RECT *display = &sys->sys.rect_display;
    display->left   = 0;
    display->top    = 0;
    display->right  = GetSystemMetrics(SM_CXSCREEN);;
    display->bottom = GetSystemMetrics(SM_CYSCREEN);;

    /* Initialize an offscreen bitmap for direct buffer operations. */

    /* */
    HDC window_dc = GetDC(sys->sys.hvideownd);

    /* */
    sys->i_depth = GetDeviceCaps(window_dc, PLANES) *
                   GetDeviceCaps(window_dc, BITSPIXEL);

    /* */
    msg_Dbg(vd, "GDI depth is %i", sys->i_depth);
    switch (sys->i_depth) {
    case 8:
        fmt->i_chroma = VLC_CODEC_RGB8;
        break;
    case 15:
        fmt->i_chroma = VLC_CODEC_RGB15;
        fmt->i_rmask  = 0x7c00;
        fmt->i_gmask  = 0x03e0;
        fmt->i_bmask  = 0x001f;
        break;
    case 16:
        fmt->i_chroma = VLC_CODEC_RGB16;
        fmt->i_rmask  = 0xf800;
        fmt->i_gmask  = 0x07e0;
        fmt->i_bmask  = 0x001f;
        break;
    case 24:
        fmt->i_chroma = VLC_CODEC_RGB24;
        fmt->i_rmask  = 0x00ff0000;
        fmt->i_gmask  = 0x0000ff00;
        fmt->i_bmask  = 0x000000ff;
        break;
    case 32:
        fmt->i_chroma = VLC_CODEC_RGB32;
        fmt->i_rmask  = 0x00ff0000;
        fmt->i_gmask  = 0x0000ff00;
        fmt->i_bmask  = 0x000000ff;
        break;
    default:
        msg_Err(vd, "screen depth %i not supported", sys->i_depth);
        return VLC_EGENERIC;
    }

    void *p_pic_buffer;
    int     i_pic_pitch;
    /* Initialize offscreen bitmap */
    BITMAPINFO *bi = &sys->bitmapinfo;
    memset(bi, 0, sizeof(BITMAPINFO) + 3 * sizeof(RGBQUAD));
    if (sys->i_depth > 8) {
        ((DWORD*)bi->bmiColors)[0] = fmt->i_rmask;
        ((DWORD*)bi->bmiColors)[1] = fmt->i_gmask;
        ((DWORD*)bi->bmiColors)[2] = fmt->i_bmask;;
    }

    BITMAPINFOHEADER *bih = &sys->bitmapinfo.bmiHeader;
    bih->biSize = sizeof(BITMAPINFOHEADER);
    bih->biSizeImage     = 0;
    bih->biPlanes        = 1;
    bih->biCompression   = (sys->i_depth == 15 ||
                            sys->i_depth == 16) ? BI_BITFIELDS : BI_RGB;
    bih->biBitCount      = sys->i_depth;
    bih->biWidth         = fmt->i_width;
    bih->biHeight        = -fmt->i_height;
    bih->biClrImportant  = 0;
    bih->biClrUsed       = 0;
    bih->biXPelsPerMeter = 0;
    bih->biYPelsPerMeter = 0;

    i_pic_pitch = bih->biBitCount * bih->biWidth / 8;
    sys->off_bitmap = CreateDIBSection(window_dc,
                                       (BITMAPINFO *)bih,
                                       DIB_RGB_COLORS,
                                       &p_pic_buffer, NULL, 0);

    sys->off_dc = CreateCompatibleDC(window_dc);

    SelectObject(sys->off_dc, sys->off_bitmap);
    ReleaseDC(sys->sys.hvideownd, window_dc);

    if (!sys->sys.b_windowless)
        EventThreadUpdateTitle(sys->sys.event, VOUT_TITLE " (WinGDI output)");

    /* */
    picture_resource_t rsc;
    memset(&rsc, 0, sizeof(rsc));
    rsc.p[0].p_pixels = p_pic_buffer;
    rsc.p[0].i_lines  = fmt->i_height;
    rsc.p[0].i_pitch  = i_pic_pitch;;

    picture_t *picture = picture_NewFromResource(fmt, &rsc);
    if (picture != NULL)
        sys->sys.pool = picture_pool_New(1, &picture);
    else
        sys->sys.pool = NULL;

    UpdateRects(vd, true);

    return VLC_SUCCESS;
}
Exemple #18
0
static int Open(vlc_object_t *p_this) {
    vout_display_t *vd = (vout_display_t *)p_this;
    vout_display_sys_t *sys;
    void *p_library;

    /* */
    if (vlc_mutex_trylock(&single_instance) != 0) {
        msg_Err(vd, "Can't start more than one instance at a time");
        return VLC_EGENERIC;
    }

    /* Allocate structure */
    sys = (struct vout_display_sys_t*) calloc(1, sizeof(*sys));
    if (!sys) {
        vlc_mutex_unlock(&single_instance);
        return VLC_ENOMEM;
    }

    /* */
    sys->p_library = p_library = InitLibrary(sys);
    if (!p_library) {
        free(sys);
        msg_Err(vd, "Could not initialize libui.so/libgui.so/libsurfaceflinger_client.so!");
        vlc_mutex_unlock(&single_instance);
        return VLC_EGENERIC;
    }

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

    char *psz_fcc = var_InheritString(vd, CFG_PREFIX "chroma");
    if( psz_fcc ) {
        fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_fcc);
        free(psz_fcc);
    } else
        fmt.i_chroma = VLC_CODEC_RGB32;

    switch(fmt.i_chroma) {
        case VLC_CODEC_YV12:
            /* avoid swscale usage by asking for I420 instead since the
             * vout already has code to swap the buffers */
            fmt.i_chroma = VLC_CODEC_I420;
        case VLC_CODEC_I420:
            break;

        case VLC_CODEC_RGB16:
            fmt.i_bmask = 0x0000001f;
            fmt.i_gmask = 0x000007e0;
            fmt.i_rmask = 0x0000f800;
            break;

        case VLC_CODEC_RGB32:
            fmt.i_rmask  = 0x000000ff;
            fmt.i_gmask  = 0x0000ff00;
            fmt.i_bmask  = 0x00ff0000;
            break;

        default:
            return VLC_EGENERIC;
    }
    video_format_FixRgb(&fmt);

    msg_Dbg(vd, "Pixel format %4.4s", (char*)&fmt.i_chroma);

    /* Create the associated picture */
    picture_resource_t *rsc = &sys->resource;
    rsc->p_sys = malloc(sizeof(*rsc->p_sys));
    if (!rsc->p_sys)
        goto enomem;
    rsc->p_sys->sys = sys;

    for (int i = 0; i < PICTURE_PLANE_MAX; i++) {
        rsc->p[i].p_pixels = NULL;
        rsc->p[i].i_pitch = 0;
        rsc->p[i].i_lines = 0;
    }
    picture_t *picture = picture_NewFromResource(&fmt, rsc);
    if (!picture)
        goto enomem;

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = 1;
    pool_cfg.picture       = &picture;
    pool_cfg.lock          = AndroidLockSurface;
    pool_cfg.unlock        = AndroidUnlockSurface;

    sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!sys->pool) {
        picture_Release(picture);
        goto enomem;
    }

    /* Setup vout_display */
    vd->sys     = sys;
    vd->fmt     = fmt;
    vd->pool    = Pool;
    vd->display = Display;
    vd->control = Control;
    vd->prepare = NULL;
    vd->manage  = NULL;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, false);

    sys->i_sar_num = vd->source.i_sar_num;
    sys->i_sar_den = vd->source.i_sar_den;

    return VLC_SUCCESS;

enomem:
    free(rsc->p_sys);
    free(sys);
    dlclose(p_library);
    vlc_mutex_unlock(&single_instance);
    return VLC_ENOMEM;
}
Exemple #19
0
static int Open(vlc_object_t *p_this) {
    vout_display_t *vd = (vout_display_t *)p_this;
    vout_display_sys_t *sys;
    void *p_library;

    /* */
    if (vlc_mutex_trylock(&single_instance) != 0) {
        msg_Err(vd, "Can't start more than one instance at a time");
        return VLC_EGENERIC;
    }

    /* Allocate structure */
    sys = (struct vout_display_sys_t*) calloc(1, sizeof(*sys));
    if (!sys) {
        vlc_mutex_unlock(&single_instance);
        return VLC_ENOMEM;
    }

    /* */
    sys->p_library = p_library = InitLibrary(sys);
    if (!p_library) {
        free(sys);
        msg_Err(vd, "Could not initialize libui.so/libgui.so/libsurfaceflinger_client.so!");
        vlc_mutex_unlock(&single_instance);
        return VLC_EGENERIC;
    }

    /* Setup chroma */
    video_format_t fmt = vd->fmt;
    fmt.i_chroma = VLC_CODEC_RGB32;
    fmt.i_rmask  = 0x000000ff;
    fmt.i_gmask  = 0x0000ff00;
    fmt.i_bmask  = 0x00ff0000;
    video_format_FixRgb(&fmt);

    /* Create the associated picture */
    picture_resource_t *rsc = &sys->resource;
    rsc->p_sys = malloc(sizeof(*rsc->p_sys));
    if (!rsc->p_sys)
        goto enomem;
    rsc->p_sys->sys = sys;

    for (int i = 0; i < PICTURE_PLANE_MAX; i++) {
        rsc->p[i].p_pixels = NULL;
        rsc->p[i].i_pitch = 0;
        rsc->p[i].i_lines = 0;
    }
    picture_t *picture = picture_NewFromResource(&fmt, rsc);
    if (!picture)
        goto enomem;

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = 1;
    pool_cfg.picture       = &picture;
    pool_cfg.lock          = AndroidLockSurface;
    pool_cfg.unlock        = AndroidUnlockSurface;

    sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!sys->pool) {
        picture_Release(picture);
        goto enomem;
    }

    /* Setup vout_display */
    vd->sys     = sys;
    vd->fmt     = fmt;
    vd->pool    = Pool;
    vd->display = Display;
    vd->control = Control;
    vd->prepare = NULL;
    vd->manage  = NULL;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, false);

    sys->i_sar_num = vd->source.i_sar_num;
    sys->i_sar_den = vd->source.i_sar_den;

    return VLC_SUCCESS;

enomem:
    free(rsc->p_sys);
    free(sys);
    dlclose(p_library);
    vlc_mutex_unlock(&single_instance);
    return VLC_ENOMEM;
}
Exemple #20
0
static int
EvasImageBuffersAlloc( vout_display_t *vd, video_format_t *p_fmt )
{
    vout_display_sys_t *sys = vd->sys;
    picture_t *p_pic = NULL;
    picture_resource_t rsc;
    size_t i_bytes = 0;

    memset(&rsc, 0, sizeof(picture_resource_t));
    if( !( p_pic = picture_NewFromResource( p_fmt, &rsc ) ) )
        return -1;

    if( picture_Setup( p_pic, p_fmt ) )
    {
        picture_Release( p_pic );
        return -1;
    }

    for( int i = 0; i < p_pic->i_planes; ++i )
        memcpy( &sys->p_planes[i], &p_pic->p[i], sizeof(plane_t));
    sys->i_nb_planes = p_pic->i_planes;
    picture_Release( p_pic );

    if( !( sys->p_buffers = calloc( sys->i_nb_buffers, sizeof(struct buffer) ) ) )
        goto error;

    /* Calculate how big the new image should be */
    for( unsigned int i = 0; i < sys->i_nb_planes; i++ )
    {
        const plane_t *p = &sys->p_planes[i];

        if( p->i_pitch < 0 || p->i_lines <= 0 ||
            (size_t)p->i_pitch > (SIZE_MAX - i_bytes)/p->i_lines )
            goto error;
        i_bytes += p->i_pitch * p->i_lines;
    }

    if( !i_bytes )
        goto error;

    for( unsigned int i = 0; i < sys->i_nb_buffers; ++i )
    {
        struct buffer *p_buffer = &sys->p_buffers[i];

        p_buffer->p[0] = aligned_alloc( 16, i_bytes );

        if( !p_buffer->p[0] )
        {
            sys->i_nb_buffers = i;
            break;
        }

        for( unsigned int j = 1; j < sys->i_nb_planes; j++ )
            p_buffer->p[j] = &p_buffer->p[j-1][ sys->p_planes[j-1].i_lines *
                                                sys->p_planes[j-1].i_pitch ];
    }

    return 0;

error:
    if( sys->p_buffers )
        EvasImageBuffersFree( vd );
    return -1;
}