Пример #1
0
/**
 * Allocate a new picture in the heap.
 *
 * This function allocates a fake direct buffer in memory, which can be
 * used exactly like a video buffer. The video output thread then manages
 * how it gets displayed.
 */
static int AllocatePicture( picture_t *p_pic )
{
    /* Calculate how big the new image should be */
    size_t i_bytes = 0;
    for( int i = 0; i < p_pic->i_planes; i++ )
    {
        const plane_t *p = &p_pic->p[i];

        if( p->i_pitch < 0 || p->i_lines <= 0 ||
            (size_t)p->i_pitch > (SIZE_MAX - i_bytes)/p->i_lines )
        {
            p_pic->i_planes = 0;
            return VLC_ENOMEM;
        }
        i_bytes += p->i_pitch * p->i_lines;
    }

    uint8_t *p_data = vlc_memalign( 16, i_bytes );
    if( i_bytes > 0 && p_data == NULL )
    {
        p_pic->i_planes = 0;
        return VLC_EGENERIC;
    }
    p_pic->gc.p_sys = (void *)p_data;

    /* Fill the p_pixels field for each plane */
    p_pic->p[0].p_pixels = p_data;
    for( int i = 1; i < p_pic->i_planes; i++ )
    {
        p_pic->p[i].p_pixels = &p_pic->p[i-1].p_pixels[ p_pic->p[i-1].i_lines *
                                                        p_pic->p[i-1].i_pitch ];
    }

    return VLC_SUCCESS;
}
Пример #2
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);
}
Пример #3
0
static picture_t *Filter(filter_t *filter, picture_t *src)
{
    filter_sys_t *sys = filter->p_sys;

    picture_t *dst = filter_NewPicture(filter);
    if (!dst) {
        picture_Release(src);
        return NULL;
    }

    vlc_mutex_lock(&sys->lock);
    float strength = VLC_CLIP(sys->strength, STRENGTH_MIN, STRENGTH_MAX);
    int   radius   = VLC_CLIP((sys->radius + 1) & ~1, RADIUS_MIN, RADIUS_MAX);
    vlc_mutex_unlock(&sys->lock);

    const video_format_t *fmt = &filter->fmt_in.video;
    struct vf_priv_s *cfg = &sys->cfg;

    cfg->thresh = (1 << 15) / strength;
    if (cfg->radius != radius) {
        cfg->radius = radius;
        cfg->buf    = (uint16_t *)vlc_memalign(16,
                                   (((fmt->i_width + 15) & ~15) * (cfg->radius + 1) / 2 + 32) * sizeof(*cfg->buf));			// sunqueen modify
    }

    for (int i = 0; i < dst->i_planes; i++) {
        const plane_t *srcp = &src->p[i];
        plane_t       *dstp = &dst->p[i];

        const vlc_chroma_description_t *chroma = sys->chroma;
        int w = fmt->i_width  * chroma->p[i].w.num / chroma->p[i].w.den;
        int h = fmt->i_height * chroma->p[i].h.num / chroma->p[i].h.den;
        int r = (cfg->radius  * chroma->p[i].w.num / chroma->p[i].w.den +
                 cfg->radius  * chroma->p[i].h.num / chroma->p[i].h.den) / 2;
        r = VLC_CLIP((r + 1) & ~1, RADIUS_MIN, RADIUS_MAX);
        if (__MIN(w, h) > 2 * r && cfg->buf) {
            filter_plane(cfg, dstp->p_pixels, srcp->p_pixels,
                         w, h, dstp->i_pitch, srcp->i_pitch, r);
        } else {
            plane_CopyPixels(dstp, srcp);
        }
    }

    picture_CopyProperties(dst, src);
    picture_Release(src);
    return dst;
}
Пример #4
0
/**
 * Allocate a new picture in the heap.
 *
 * This function allocates a fake direct buffer in memory, which can be
 * used exactly like a video buffer. The video output thread then manages
 * how it gets displayed.
 */
static int vout_AllocatePicture( picture_t *p_pic,
                                 vlc_fourcc_t i_chroma,
                                 int i_width, int i_height,
                                 int i_sar_num, int i_sar_den )
{
    /* Make sure the real dimensions are a multiple of 16 */
    if( picture_Setup( p_pic, i_chroma, i_width, i_height,
                       i_sar_num, i_sar_den ) != VLC_SUCCESS )
        return VLC_EGENERIC;

    /* Calculate how big the new image should be */
    size_t i_bytes = 0;
    for( int i = 0; i < p_pic->i_planes; i++ )
    {
        const plane_t *p = &p_pic->p[i];

        if( p->i_pitch <= 0 || p->i_lines <= 0 ||
            p->i_pitch > (SIZE_MAX - i_bytes)/p->i_lines )
        {
            p_pic->i_planes = 0;
            return VLC_ENOMEM;
        }
        i_bytes += p->i_pitch * p->i_lines;
    }

    uint8_t *p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_bytes );
    if( !p_data )
    {
        p_pic->i_planes = 0;
        return VLC_EGENERIC;
    }

    /* Fill the p_pixels field for each plane */
    p_pic->p[0].p_pixels = p_data;
    for( int i = 1; i < p_pic->i_planes; i++ )
    {
        p_pic->p[i].p_pixels = &p_pic->p[i-1].p_pixels[ p_pic->p[i-1].i_lines *
                                                        p_pic->p[i-1].i_pitch ];
    }

    return VLC_SUCCESS;
}