/***************************************************************************** * 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 ); }
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; }
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; }
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; }
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; }