static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
{
    vout_display_sys_t *sys = vd->sys;

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

    if (count > sys->count)
        count = sys->count;

	// sunqueen modify start
//    picture_t *pictures[count];
	picture_t **pictures;

	pictures = (picture_t **)malloc(sizeof(picture_t *) * count);
	// sunqueen modify end

    for (unsigned i = 0; i < count; i++) {
        picture_sys_t *picsys = (picture_sys_t *)malloc(sizeof (*picsys));			// sunqueen modify
        if (unlikely(picsys == NULL))
        {
            count = i;
            break;
        }
        picsys->sys = sys;
        picsys->id = NULL;

        picture_resource_t rsc = { /*.p_sys =*/ picsys };			// sunqueen modify

        for (unsigned i = 0; i < PICTURE_PLANE_MAX; i++) {
            /* vmem-lock is responsible for the allocation */
            rsc.p[i].p_pixels = NULL;
            rsc.p[i].i_lines  = sys->lines[i];
            rsc.p[i].i_pitch  = sys->pitches[i];
        }

        pictures[i] = picture_NewFromResource(&vd->fmt, &rsc);
        if (!pictures[i]) {
            free(rsc.p_sys);
            count = i;
            break;
        }
    }

    /* */
    picture_pool_configuration_t pool;
    memset(&pool, 0, sizeof(pool));
    pool.picture_count = count;
    pool.picture       = pictures;
    pool.lock          = Lock;
    pool.unlock        = Unlock;
    sys->pool = picture_pool_NewExtended(&pool);
    if (!sys->pool) {
        for (unsigned i = 0; i < count; i++)
            picture_Release(pictures[i]);
    }

	free(pictures);			// sunqueen add
    return sys->pool;
}
Пример #2
0
static picture_pool_t *
tc_anop_get_pool(const opengl_tex_converter_t *tc, const video_format_t *fmt,
                 unsigned requested_count, const GLuint *textures)
{
    struct priv *priv = tc->priv;
    priv->stex = SurfaceTexture_create(tc->parent, textures[0]);
    if (priv->stex == NULL)
    {
        msg_Err(tc->parent, "tc_anop_get_pool: SurfaceTexture_create failed");
        return NULL;
    }

#define FORCED_COUNT 31
    requested_count = FORCED_COUNT;
    picture_t *picture[FORCED_COUNT] = {NULL, };
    unsigned count;

    for (count = 0; count < requested_count; count++)
    {
        picture_sys_t *p_picsys = calloc(1, sizeof(*p_picsys));
        if (unlikely(p_picsys == NULL))
            break;
        picture_resource_t rsc = {
            .p_sys = p_picsys,
            .pf_destroy = AndroidOpaquePicture_DetachVout,
        };

        p_picsys->hw.b_vd_ref = true;
        p_picsys->hw.p_surface = SurfaceTexture_getANativeWindow(priv->stex);
        p_picsys->hw.p_jsurface = SurfaceTexture_getSurface(priv->stex);
        p_picsys->hw.i_index = -1;
        vlc_mutex_init(&p_picsys->hw.lock);

        picture[count] = picture_NewFromResource(fmt, &rsc);
        if (!picture[count])
        {
            free(p_picsys);
            break;
        }
    }
    if (count <= 0)
        goto error;

    /* Wrap the pictures into a pool */
    picture_pool_configuration_t pool_cfg = {
        .picture_count = requested_count,
        .picture       = picture,
        .lock          = pool_lock_pic,
        .unlock        = pool_unlock_pic,
    };
    picture_pool_t *pool = picture_pool_NewExtended(&pool_cfg);
    if (!pool)
        goto error;

    return pool;
error:
    SurfaceTexture_release(priv->stex);
    return NULL;
}
Пример #3
0
static picture_pool_t *
PoolAlloc( vout_display_t *vd, unsigned i_requested_count )
{
    picture_t **pp_pics = NULL;
    picture_pool_t *p_pool;
    picture_pool_configuration_t pool_cfg;

    msg_Dbg(vd, "PoolAlloc, requested_count: %d", i_requested_count);

    i_requested_count++; /* picture owned by evas */

    if( BuffersSetup( vd, &vd->fmt, &i_requested_count) )
    {
        msg_Err( vd, "BuffersSetup failed" );
        return NULL;
    }
    if( i_requested_count <= 1 )
    {
        msg_Err( vd, "not enough buffers allocated" );
        goto error;
    }
    i_requested_count--;

    msg_Dbg( vd, "PoolAlloc, got: %d", i_requested_count );

    if( !( pp_pics = calloc( i_requested_count, sizeof(picture_t) ) ) )
        goto error;

    for( unsigned int i = 0; i < i_requested_count; ++i )
    {
        if( !( pp_pics[i] = PictureAlloc( vd ) ) )
        {
            i_requested_count = i;
            msg_Err( vd, "PictureAlloc failed" );
            goto error;
        }
    }

    memset( &pool_cfg, 0, sizeof(pool_cfg) );
    pool_cfg.picture_count = i_requested_count;
    pool_cfg.picture       = pp_pics;
    pool_cfg.lock          = PoolLockPicture;
    pool_cfg.unlock        = PoolUnlockPicture;

    p_pool = picture_pool_NewExtended( &pool_cfg );
    if( p_pool )
        return p_pool;

error:
    if( pp_pics )
    {
        for( unsigned int i = 0; i < i_requested_count; ++i )
            picture_Release( pp_pics[i] );
        free( pp_pics );
    }
    BuffersClean( vd );
    return NULL;
}
Пример #4
0
static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
{
    unsigned i;
    vout_display_sys_t *sys = vd->sys;

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

            memset(&rsc, 0, sizeof(rsc));
            rsc.p[0].i_pitch = PIXEL_ALIGN(vd->fmt.i_width);
            rsc.p[0].i_lines = PIXEL_ALIGN(vd->fmt.i_height);
            rsc.p[1].i_pitch = PIXEL_ALIGN(vd->fmt.i_width);
            switch (vd->fmt.i_chroma) {
                case VLC_CODEC_MV12:
                    rsc.p[1].i_lines = PIXEL_ALIGN(vd->fmt.i_height / 2);
                    break;
                case VLC_CODEC_MV16:
                    rsc.p[1].i_lines = PIXEL_ALIGN(vd->fmt.i_height);
                    break;
                default:
                    return NULL;
            }

            sys->picture = malloc(count * sizeof(picture_t *));
            if (!sys->picture)
                return NULL;

            for (i = 0; i < count; i ++) {
                sys->picture[i] = picture_NewFromResource(&vd->fmt, &rsc);
                if (!sys->picture[i]) {
                    sys->picture_count = i;
                    break;
                }
            }
            sys->picture_count = i;
        }

        /* */
        picture_pool_configuration_t pool;
        memset(&pool, 0, sizeof(pool));
        pool.picture_count = sys->picture_count;
        pool.picture       = sys->picture;
        pool.lock          = Lock;
        sys->pool = picture_pool_NewExtended(&pool);
        if (!sys->pool) {
            for (i = 0; i < sys->picture_count; i++) {
                picture_Release(sys->picture[i]);
            }
            free(sys->picture);
            sys->picture = NULL;
            sys->picture_count = 0;
        }
    }

    return sys->pool;
}
Пример #5
0
static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
                                            unsigned offset)
{
    picture_t *picture = pool->picture[offset];
    uintptr_t sys = ((uintptr_t)pool) + offset;
    picture_resource_t res = {
        .p_sys = picture->p_sys,
        .pf_destroy = picture_pool_ReleasePicture,
    };

    for (int i = 0; i < picture->i_planes; i++) {
        res.p[i].p_pixels = picture->p[i].p_pixels;
        res.p[i].i_lines = picture->p[i].i_lines;
        res.p[i].i_pitch = picture->p[i].i_pitch;
    }

    picture_t *clone = picture_NewFromResource(&picture->format, &res);
    if (likely(clone != NULL)) {
        ((picture_priv_t *)clone)->gc.opaque = (void *)sys;
        picture_Hold(picture);
    }
    return clone;
}

picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg)
{
    if (unlikely(cfg->picture_count > pool_max))
        return NULL;

    picture_pool_t *pool = vlc_memalign(pool_max,
        sizeof (*pool) + cfg->picture_count * sizeof (picture_t *));
    if (unlikely(pool == NULL))
        return NULL;

    pool->pic_lock   = cfg->lock;
    pool->pic_unlock = cfg->unlock;
    vlc_mutex_init(&pool->lock);
    vlc_cond_init(&pool->wait);
    pool->available = (1ULL << cfg->picture_count) - 1;
    atomic_init(&pool->refs,  1);
    pool->picture_count = cfg->picture_count;
    memcpy(pool->picture, cfg->picture,
           cfg->picture_count * sizeof (picture_t *));
    pool->canceled = false;
    return pool;
}

picture_pool_t *picture_pool_New(unsigned count, picture_t *const *tab)
{
    picture_pool_configuration_t cfg = {
        .picture_count = count,
        .picture = tab,
    };

    return picture_pool_NewExtended(&cfg);
}
Пример #6
0
picture_pool_t *picture_pool_New(int picture_count, picture_t *picture[])
{
    picture_pool_configuration_t cfg;

    memset(&cfg, 0, sizeof(cfg));
    cfg.picture_count = picture_count;
    cfg.picture       = picture;

    return picture_pool_NewExtended(&cfg);
}
Пример #7
0
static picture_pool_t *PoolAlloc(vout_display_t *vd, unsigned requested_count)
{
    vout_display_sys_t *sys = vd->sys;
    picture_pool_t *pool = NULL;
    picture_t **pp_pics = NULL;
    unsigned int i = 0;

    msg_Dbg(vd, "PoolAlloc: request %d frames", requested_count);
    if (AndroidWindow_Setup(sys, sys->p_window, requested_count) != 0)
        goto error;

    requested_count = sys->p_window->i_pic_count;
    msg_Dbg(vd, "PoolAlloc: got %d frames", requested_count);

    UpdateVideoSize(sys, &sys->p_window->fmt);

    pp_pics = calloc(requested_count, sizeof(picture_t));

    for (i = 0; i < requested_count; i++)
    {
        picture_t *p_pic = PictureAlloc(sys, &sys->p_window->fmt,
                                        sys->p_window->b_opaque);
        if (!p_pic)
            goto error;

        pp_pics[i] = p_pic;
    }

    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = requested_count;
    pool_cfg.picture       = pp_pics;
    if (sys->p_window->b_opaque)
    {
        pool_cfg.lock      = PoolLockOpaquePicture;
        pool_cfg.unlock    = PoolUnlockOpaquePicture;
    }
    else
    {
        pool_cfg.lock      = PoolLockPicture;
        pool_cfg.unlock    = PoolUnlockPicture;
    }
    pool = picture_pool_NewExtended(&pool_cfg);

error:
    if (!pool && pp_pics) {
        for (unsigned j = 0; j < i; j++)
            picture_Release(pp_pics[j]);
    }
    free(pp_pics);
    return pool;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
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;
}
Пример #13
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;
}
Пример #14
0
Файл: vout.c Проект: Kubink/vlc
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;
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
Файл: wingdi.c Проект: 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;
}
Пример #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;
}