@ -16,11 +16,19 @@
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
# include "config.h"
# include <fcntl.h>
# include <sys/mman.h>
# include <unistd.h>
/* This was introduced in version 4.6. And may not exist all without an
* optional package . So to prevent a hard dependency on needing the Linux
* kernel headers to compile , make this optional . */
# if HAVE_LINUX_DMA_BUF_H
# include <linux/dma-buf.h>
# include <sys/ioctl.h>
# endif
# include <drm.h>
# include <xf86drm.h>
@ -97,14 +105,12 @@ static void drm_unmap_frame(AVHWFramesContext *hwfc,
HWMapDescriptor * hwmap )
{
DRMMapping * map = hwmap - > priv ;
struct dma_buf_sync sync = { . flags = DMA_BUF_SYNC_END | map - > sync_flags } ;
int i , ret ;
for ( i = 0 ; i < map - > nb_regions ; i + + ) {
ret = ioctl ( map - > object [ i ] , DMA_BUF_IOCTL_SYNC , & sync ) ;
if ( ret )
av_log ( hwfc , AV_LOG_ERROR , " Failed to issue ioctl sync to DRM object "
" %d: %d. \n " , map - > object [ i ] , errno ) ;
for ( int i = 0 ; i < map - > nb_regions ; i + + ) {
# if HAVE_LINUX_DMA_BUF_H
struct dma_buf_sync sync = { . flags = DMA_BUF_SYNC_END | map - > sync_flags } ;
ioctl ( map - > object [ i ] , DMA_BUF_IOCTL_SYNC , & sync ) ;
# endif
munmap ( map - > address [ i ] , map - > length [ i ] ) ;
}
@ -115,7 +121,9 @@ static int drm_map_frame(AVHWFramesContext *hwfc,
AVFrame * dst , const AVFrame * src , int flags )
{
const AVDRMFrameDescriptor * desc = ( AVDRMFrameDescriptor * ) src - > data [ 0 ] ;
# if HAVE_LINUX_DMA_BUF_H
struct dma_buf_sync sync_start = { 0 } ;
# endif
DRMMapping * map ;
int err , i , p , plane ;
int mmap_prot ;
@ -126,16 +134,18 @@ static int drm_map_frame(AVHWFramesContext *hwfc,
return AVERROR ( ENOMEM ) ;
mmap_prot = 0 ;
if ( flags & AV_HWFRAME_MAP_READ ) {
if ( flags & AV_HWFRAME_MAP_READ )
mmap_prot | = PROT_READ ;
map - > sync_flags | = DMA_BUF_SYNC_READ ;
}
if ( flags & AV_HWFRAME_MAP_WRITE ) {
if ( flags & AV_HWFRAME_MAP_WRITE )
mmap_prot | = PROT_WRITE ;
map - > sync_flags | = DMA_BUF_SYNC_WRITE ;
}
# if HAVE_LINUX_DMA_BUF_H
if ( flags & AV_HWFRAME_MAP_READ )
map - > sync_flags | = DMA_BUF_SYNC_READ ;
if ( flags & AV_HWFRAME_MAP_WRITE )
map - > sync_flags | = DMA_BUF_SYNC_WRITE ;
sync_start . flags = DMA_BUF_SYNC_START | map - > sync_flags ;
# endif
av_assert0 ( desc - > nb_objects < = AV_DRM_MAX_PLANES ) ;
for ( i = 0 ; i < desc - > nb_objects ; i + + ) {
@ -152,13 +162,11 @@ static int drm_map_frame(AVHWFramesContext *hwfc,
map - > length [ i ] = desc - > objects [ i ] . size ;
map - > object [ i ] = desc - > objects [ i ] . fd ;
err = ioctl ( desc - > objects [ i ] . fd , DMA_BUF_IOCTL_SYNC , & sync_start ) ;
if ( err ) {
err = AVERROR ( errno ) ;
av_log ( hwfc , AV_LOG_ERROR , " Failed to issue ioctl sync to DRM object "
" %d: %d. \n " , desc - > objects [ i ] . fd , errno ) ;
goto fail ;
}
# if HAVE_LINUX_DMA_BUF_H
/* We're not checking for errors here because the kernel may not
* support the ioctl , in which case its okay to carry on */
ioctl ( desc - > objects [ i ] . fd , DMA_BUF_IOCTL_SYNC , & sync_start ) ;
# endif
}
map - > nb_regions = i ;