Beispiel #1
0
Datei: vda.c Projekt: AsamQi/vlc
/*****************************************************************************
 * vda_Copy420YpCbCr8Planar: copy y420 CVPixelBuffer to picture_t
 *****************************************************************************/
static void vda_Copy420YpCbCr8Planar( picture_t *p_pic,
                                      CVPixelBufferRef buffer,
                                      unsigned i_width,
                                      unsigned i_height,
                                      copy_cache_t *cache )
{
    uint8_t *pp_plane[3];
    size_t  pi_pitch[3];

    if (!buffer)
        return;

    CVPixelBufferLockBaseAddress( buffer, 0 );

    for( int i = 0; i < 3; i++ )
    {
        pp_plane[i] = CVPixelBufferGetBaseAddressOfPlane( buffer, i );
        pi_pitch[i] = CVPixelBufferGetBytesPerRowOfPlane( buffer, i );
    }

    CopyFromYv12( p_pic, pp_plane, pi_pitch,
                  i_width, i_height, cache );

    CVPixelBufferUnlockBaseAddress( buffer, 0 );
}
Beispiel #2
0
static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
{
    vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);

    VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];

#if VA_CHECK_VERSION(0,31,0)
    if( vaSyncSurface( p_va->p_display, i_surface_id ) )
#else
    if( vaSyncSurface( p_va->p_display, p_va->i_context_id, i_surface_id ) )
#endif
        return VLC_EGENERIC;

    if(p_va->b_supports_derive)
    {
        if(vaDeriveImage(p_va->p_display, i_surface_id, &(p_va->image)) != VA_STATUS_SUCCESS)
            return VLC_EGENERIC;
    }
    else
    {
        if( vaGetImage( p_va->p_display, i_surface_id,
                        0, 0, p_va->i_surface_width, p_va->i_surface_height,
                        p_va->image.image_id) )
            return VLC_EGENERIC;
    }

    void *p_base;
    if( vaMapBuffer( p_va->p_display, p_va->image.buf, &p_base ) )
        return VLC_EGENERIC;

    const uint32_t i_fourcc = p_va->image.format.fourcc;
    if( i_fourcc == VA_FOURCC('Y','V','1','2') ||
        i_fourcc == VA_FOURCC('I','4','2','0') )
    {
        bool b_swap_uv = i_fourcc == VA_FOURCC('I','4','2','0');
        uint8_t *pp_plane[3];
        size_t  pi_pitch[3];

        for( int i = 0; i < 3; i++ )
        {
            const int i_src_plane = (b_swap_uv && i != 0) ?  (3 - i) : i;
            pp_plane[i] = (uint8_t*)p_base + p_va->image.offsets[i_src_plane];
            pi_pitch[i] = p_va->image.pitches[i_src_plane];
        }
        CopyFromYv12( p_picture, pp_plane, pi_pitch,
                      p_va->i_surface_width,
                      p_va->i_surface_height,
                      &p_va->image_cache );
    }
    else
    {
        assert( i_fourcc == VA_FOURCC('N','V','1','2') );
        uint8_t *pp_plane[2];
        size_t  pi_pitch[2];

        for( int i = 0; i < 2; i++ )
        {
            pp_plane[i] = (uint8_t*)p_base + p_va->image.offsets[i];
            pi_pitch[i] = p_va->image.pitches[i];
        }
        CopyFromNv12( p_picture, pp_plane, pi_pitch,
                      p_va->i_surface_width,
                      p_va->i_surface_height,
                      &p_va->image_cache );
    }

    if( vaUnmapBuffer( p_va->p_display, p_va->image.buf ) )
        return VLC_EGENERIC;

    if(p_va->b_supports_derive)
    {
        vaDestroyImage( p_va->p_display, p_va->image.image_id );
        p_va->image.image_id = VA_INVALID_ID;
    }

    return VLC_SUCCESS;
}
Beispiel #3
0
static int Extract( vlc_va_t *va, picture_t *p_picture, uint8_t *data )
{
    vlc_va_sys_t *sys = va->sys;
    VASurfaceID surface = (VASurfaceID)(uintptr_t)data;
    VAImage image;
    int ret = VLC_EGENERIC;

#if VA_CHECK_VERSION(0,31,0)
    if (vaSyncSurface(sys->hw_ctx.display, surface))
#else
    if (vaSyncSurface(sys->hw_ctx.display, sys->hw_ctx.context_id, surface))
#endif
        return VLC_EGENERIC;

    if (!sys->do_derive || vaDeriveImage(sys->hw_ctx.display, surface, &image))
    {   /* Fallback if image derivation is not supported */
        if (vaCreateImage(sys->hw_ctx.display, &sys->format, sys->width,
                          sys->height, &image))
            return VLC_EGENERIC;
        if (vaGetImage(sys->hw_ctx.display, surface, 0, 0, sys->width,
                       sys->height, image.image_id))
            goto error;
    }

    void *p_base;
    if (vaMapBuffer(sys->hw_ctx.display, image.buf, &p_base))
        goto error;

    const unsigned i_fourcc = sys->format.fourcc;
    if( i_fourcc == VA_FOURCC_YV12 ||
        i_fourcc == VA_FOURCC_IYUV )
    {
        bool b_swap_uv = i_fourcc == VA_FOURCC_IYUV;
        uint8_t *pp_plane[3];
        size_t  pi_pitch[3];

        for( int i = 0; i < 3; i++ )
        {
            const int i_src_plane = (b_swap_uv && i != 0) ?  (3 - i) : i;
            pp_plane[i] = (uint8_t*)p_base + image.offsets[i_src_plane];
            pi_pitch[i] = image.pitches[i_src_plane];
        }
        CopyFromYv12( p_picture, pp_plane, pi_pitch, sys->width, sys->height,
                      &sys->image_cache );
    }
    else
    {
        assert( i_fourcc == VA_FOURCC_NV12 );
        uint8_t *pp_plane[2];
        size_t  pi_pitch[2];

        for( int i = 0; i < 2; i++ )
        {
            pp_plane[i] = (uint8_t*)p_base + image.offsets[i];
            pi_pitch[i] = image.pitches[i];
        }
        CopyFromNv12( p_picture, pp_plane, pi_pitch, sys->width, sys->height,
                      &sys->image_cache );
    }

    vaUnmapBuffer(sys->hw_ctx.display, image.buf);
    ret = VLC_SUCCESS;
error:
    vaDestroyImage(sys->hw_ctx.display, image.image_id);
    return ret;
}
Beispiel #4
0
static int Extract(vlc_va_t *external, picture_t *picture, AVFrame *ff)
{
    vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
    LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)ff->data[3];

    if (!va->surface_cache.buffer)
        return VLC_EGENERIC;

    /* */
    assert(va->output == MAKEFOURCC('Y','V','1','2'));

    /* */
    D3DLOCKED_RECT lock;
    if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) {
        msg_Err(va->log, "Failed to lock surface");
        return VLC_EGENERIC;
    }

    if (va->render == MAKEFOURCC('Y','V','1','2') ||
        va->render == MAKEFOURCC('I','M','C','3')) {
        bool imc3 = va->render == MAKEFOURCC('I','M','C','3');
        size_t chroma_pitch = imc3 ? lock.Pitch : (lock.Pitch / 2);

        size_t pitch[3] = {
            lock.Pitch,
            chroma_pitch,
            chroma_pitch,
        };

        uint8_t *plane[3] = {
            (uint8_t*)lock.pBits,
            (uint8_t*)lock.pBits + pitch[0] * va->surface_height,
            (uint8_t*)lock.pBits + pitch[0] * va->surface_height
                                 + pitch[1] * va->surface_height / 2,
        };

        if (imc3) {
            uint8_t *V = plane[1];
            plane[1] = plane[2];
            plane[2] = V;
        }
        CopyFromYv12(picture, plane, pitch,
                     va->width, va->height,
                     &va->surface_cache);
    } else {
        assert(va->render == MAKEFOURCC('N','V','1','2'));
        uint8_t *plane[2] = {
            lock.pBits,
            (uint8_t*)lock.pBits + lock.Pitch * va->surface_height
        };
        size_t  pitch[2] = {
            lock.Pitch,
            lock.Pitch,
        };
        CopyFromNv12(picture, plane, pitch,
                     va->width, va->height,
                     &va->surface_cache);
    }

    /* */
    IDirect3DSurface9_UnlockRect(d3d);
    return VLC_SUCCESS;
}
Beispiel #5
0
static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
                   uint8_t *data)
{
    vlc_va_sys_t *sys = va->sys;
    LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)data;

    if (!sys->surface_cache.buffer)
        return VLC_EGENERIC;

    /* */
    assert(sys->output == MAKEFOURCC('Y','V','1','2'));

    /* */
    D3DLOCKED_RECT lock;
    if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) {
        msg_Err(va, "Failed to lock surface");
        return VLC_EGENERIC;
    }

    if (sys->render == MAKEFOURCC('Y','V','1','2') ||
        sys->render == MAKEFOURCC('I','M','C','3')) {
        bool imc3 = sys->render == MAKEFOURCC('I','M','C','3');
        size_t chroma_pitch = imc3 ? lock.Pitch : (lock.Pitch / 2);

        size_t pitch[3] = {
            lock.Pitch,
            chroma_pitch,
            chroma_pitch,
        };

        uint8_t *plane[3] = {
            (uint8_t*)lock.pBits,
            (uint8_t*)lock.pBits + pitch[0] * sys->surface_height,
            (uint8_t*)lock.pBits + pitch[0] * sys->surface_height
                                 + pitch[1] * sys->surface_height / 2,
        };

        if (imc3) {
            uint8_t *V = plane[1];
            plane[1] = plane[2];
            plane[2] = V;
        }
        CopyFromYv12(picture, plane, pitch, sys->width, sys->height,
                     &sys->surface_cache);
    } else {
        assert(sys->render == MAKEFOURCC('N','V','1','2'));
        uint8_t *plane[2] = {
            lock.pBits,
            (uint8_t*)lock.pBits + lock.Pitch * sys->surface_height
        };
        size_t  pitch[2] = {
            lock.Pitch,
            lock.Pitch,
        };
        CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
                     &sys->surface_cache);
    }

    /* */
    IDirect3DSurface9_UnlockRect(d3d);
    (void) opaque;
    return VLC_SUCCESS;
}