@ -399,10 +399,23 @@ static void dummy_release_buffer(AVPacket *pkt)
}
}
# endif
# endif
static int enqueue_buffer ( struct video_data * s , struct v4l2_buffer * buf )
{
int res = 0 ;
if ( v4l2_ioctl ( s - > fd , VIDIOC_QBUF , buf ) < 0 ) {
res = AVERROR ( errno ) ;
av_log ( NULL , AV_LOG_ERROR , " ioctl(VIDIOC_QBUF): %s \n " , av_err2str ( res ) ) ;
} else {
avpriv_atomic_int_add_and_fetch ( & s - > buffers_queued , 1 ) ;
}
return res ;
}
static void mmap_release_buffer ( void * opaque , uint8_t * data )
static void mmap_release_buffer ( void * opaque , uint8_t * data )
{
{
struct v4l2_buffer buf = { 0 } ;
struct v4l2_buffer buf = { 0 } ;
int res ;
struct buff_data * buf_descriptor = opaque ;
struct buff_data * buf_descriptor = opaque ;
struct video_data * s = buf_descriptor - > s ;
struct video_data * s = buf_descriptor - > s ;
@ -411,13 +424,7 @@ static void mmap_release_buffer(void *opaque, uint8_t *data)
buf . index = buf_descriptor - > index ;
buf . index = buf_descriptor - > index ;
av_free ( buf_descriptor ) ;
av_free ( buf_descriptor ) ;
if ( v4l2_ioctl ( s - > fd , VIDIOC_QBUF , & buf ) < 0 ) {
enqueue_buffer ( s , & buf ) ;
res = AVERROR ( errno ) ;
av_log ( NULL , AV_LOG_ERROR , " ioctl(VIDIOC_QBUF): %s \n " ,
av_err2str ( res ) ) ;
}
avpriv_atomic_int_add_and_fetch ( & s - > buffers_queued , 1 ) ;
}
}
# if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
# if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
@ -520,6 +527,7 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
av_log ( ctx , AV_LOG_ERROR ,
av_log ( ctx , AV_LOG_ERROR ,
" The v4l2 frame is %d bytes, but %d bytes are expected \n " ,
" The v4l2 frame is %d bytes, but %d bytes are expected \n " ,
buf . bytesused , s - > frame_size ) ;
buf . bytesused , s - > frame_size ) ;
enqueue_buffer ( s , & buf ) ;
return AVERROR_INVALIDDATA ;
return AVERROR_INVALIDDATA ;
}
}
@ -529,19 +537,16 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
res = av_new_packet ( pkt , buf . bytesused ) ;
res = av_new_packet ( pkt , buf . bytesused ) ;
if ( res < 0 ) {
if ( res < 0 ) {
av_log ( ctx , AV_LOG_ERROR , " Error allocating a packet. \n " ) ;
av_log ( ctx , AV_LOG_ERROR , " Error allocating a packet. \n " ) ;
if ( v4l2_ioctl ( s - > fd , VIDIOC_QBUF , & buf ) = = 0 )
enqueue_buffer ( s , & buf ) ;
avpriv_atomic_int_add_and_fetch ( & s - > buffers_queued , 1 ) ;
return res ;
return res ;
}
}
memcpy ( pkt - > data , s - > buf_start [ buf . index ] , buf . bytesused ) ;
memcpy ( pkt - > data , s - > buf_start [ buf . index ] , buf . bytesused ) ;
if ( v4l2_ioctl ( s - > fd , VIDIOC_QBUF , & buf ) < 0 ) {
res = enqueue_buffer ( s , & buf ) ;
res = AVERROR ( errno ) ;
if ( res ) {
av_log ( ctx , AV_LOG_ERROR , " ioctl(VIDIOC_QBUF): %s \n " , av_err2str ( res ) ) ;
av_free_packet ( pkt ) ;
av_free_packet ( pkt ) ;
return res ;
return res ;
}
}
avpriv_atomic_int_add_and_fetch ( & s - > buffers_queued , 1 ) ;
} else {
} else {
struct buff_data * buf_descriptor ;
struct buff_data * buf_descriptor ;
@ -559,8 +564,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
* allocate a buffer for memcpying into it
* allocate a buffer for memcpying into it
*/
*/
av_log ( ctx , AV_LOG_ERROR , " Failed to allocate a buffer descriptor \n " ) ;
av_log ( ctx , AV_LOG_ERROR , " Failed to allocate a buffer descriptor \n " ) ;
if ( v4l2_ioctl ( s - > fd , VIDIOC_QBUF , & buf ) = = 0 )
enqueue_buffer ( s , & buf ) ;
avpriv_atomic_int_add_and_fetch ( & s - > buffers_queued , 1 ) ;
return AVERROR ( ENOMEM ) ;
return AVERROR ( ENOMEM ) ;
}
}
@ -571,8 +575,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
buf_descriptor , 0 ) ;
buf_descriptor , 0 ) ;
if ( ! pkt - > buf ) {
if ( ! pkt - > buf ) {
av_log ( ctx , AV_LOG_ERROR , " Failed to create a buffer \n " ) ;
av_log ( ctx , AV_LOG_ERROR , " Failed to create a buffer \n " ) ;
if ( v4l2_ioctl ( s - > fd , VIDIOC_QBUF , & buf ) = = 0 )
enqueue_buffer ( s , & buf ) ;
avpriv_atomic_int_add_and_fetch ( & s - > buffers_queued , 1 ) ;
av_freep ( & buf_descriptor ) ;
av_freep ( & buf_descriptor ) ;
return AVERROR ( ENOMEM ) ;
return AVERROR ( ENOMEM ) ;
}
}