void CopyOmxPicture( int i_color_format, picture_t *p_pic, int i_slice_height, int i_src_stride, uint8_t *p_src, int i_chroma_div, ArchitectureSpecificCopyData *p_architecture_specific ) { uint8_t *p_dst; int i_dst_stride; int i_plane, i_width, i_line; if( i_color_format == QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka ) { qcom_convert(p_src, p_pic); return; } #ifdef CAN_COMPILE_SSE2 if( i_color_format == OMX_COLOR_FormatYUV420SemiPlanar && vlc_CPU_SSE2() && p_architecture_specific->data ) { copy_cache_t *p_surface_cache = (copy_cache_t*)p_architecture_specific->data; uint8_t *ppi_src_pointers[2] = { p_src, p_src + i_src_stride * i_slice_height }; size_t pi_src_strides[2] = { i_src_stride, i_src_stride }; CopyFromNv12( p_pic, ppi_src_pointers, pi_src_strides, i_src_stride, i_slice_height, p_surface_cache ); return; } #endif for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) { if(i_plane == 1) i_src_stride /= i_chroma_div; p_dst = p_pic->p[i_plane].p_pixels; i_dst_stride = p_pic->p[i_plane].i_pitch; i_width = p_pic->p[i_plane].i_visible_pitch; for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ ) { memcpy( p_dst, p_src, i_width ); p_src += i_src_stride; p_dst += i_dst_stride; } /* Handle plane height, which may be indicated via nSliceHeight in OMX. * The handling for chroma planes currently assumes vertically * subsampled chroma, e.g. 422 planar wouldn't work right. */ if( i_plane == 0 && i_slice_height > p_pic->p[i_plane].i_visible_lines ) p_src += i_src_stride * (i_slice_height - p_pic->p[i_plane].i_visible_lines); else if ( i_plane > 0 && i_slice_height/2 > p_pic->p[i_plane].i_visible_lines ) p_src += i_src_stride * (i_slice_height/2 - p_pic->p[i_plane].i_visible_lines); } }
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 *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 *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 *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; }