Merge pull request #6074 from alalek:ffmpeg_interrupt_callback_compatibility
This commit is contained in:
commit
80102b76f9
@ -195,11 +195,21 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef USE_AV_INTERRUPT_CALLBACK
|
||||||
|
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 21, 0)
|
||||||
|
#define USE_AV_INTERRUPT_CALLBACK 1
|
||||||
|
#else
|
||||||
|
#define USE_AV_INTERRUPT_CALLBACK 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
#define LIBAVFORMAT_INTERRUPT_TIMEOUT_MS 30000
|
#define LIBAVFORMAT_INTERRUPT_TIMEOUT_MS 30000
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
|
// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
|
||||||
|
|
||||||
|
static
|
||||||
inline LARGE_INTEGER get_filetime_offset()
|
inline LARGE_INTEGER get_filetime_offset()
|
||||||
{
|
{
|
||||||
SYSTEMTIME s;
|
SYSTEMTIME s;
|
||||||
@ -220,6 +230,7 @@ inline LARGE_INTEGER get_filetime_offset()
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
inline void get_monotonic_time(timespec *tv)
|
inline void get_monotonic_time(timespec *tv)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER t;
|
LARGE_INTEGER t;
|
||||||
@ -264,6 +275,7 @@ inline void get_monotonic_time(timespec *tv)
|
|||||||
tv->tv_nsec = (t.QuadPart % 1000000) * 1000;
|
tv->tv_nsec = (t.QuadPart % 1000000) * 1000;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
static
|
||||||
inline void get_monotonic_time(timespec *time)
|
inline void get_monotonic_time(timespec *time)
|
||||||
{
|
{
|
||||||
#if defined(__APPLE__) && defined(__MACH__)
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
@ -280,6 +292,7 @@ inline void get_monotonic_time(timespec *time)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static
|
||||||
inline timespec get_monotonic_time_diff(timespec start, timespec end)
|
inline timespec get_monotonic_time_diff(timespec start, timespec end)
|
||||||
{
|
{
|
||||||
timespec temp;
|
timespec temp;
|
||||||
@ -296,6 +309,7 @@ inline timespec get_monotonic_time_diff(timespec start, timespec end)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
|
inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
|
||||||
{
|
{
|
||||||
timespec delta = get_monotonic_time_diff(time1, time2);
|
timespec delta = get_monotonic_time_diff(time1, time2);
|
||||||
@ -303,6 +317,7 @@ inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
|
|||||||
|
|
||||||
return milliseconds;
|
return milliseconds;
|
||||||
}
|
}
|
||||||
|
#endif // USE_AV_INTERRUPT_CALLBACK
|
||||||
|
|
||||||
static int get_number_of_cpus(void)
|
static int get_number_of_cpus(void)
|
||||||
{
|
{
|
||||||
@ -353,6 +368,7 @@ struct Image_FFMPEG
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
struct AVInterruptCallbackMetadata
|
struct AVInterruptCallbackMetadata
|
||||||
{
|
{
|
||||||
timespec value;
|
timespec value;
|
||||||
@ -360,14 +376,14 @@ struct AVInterruptCallbackMetadata
|
|||||||
int timeout;
|
int timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static
|
||||||
inline void _opencv_ffmpeg_free(void** ptr)
|
inline void _opencv_ffmpeg_free(void** ptr)
|
||||||
{
|
{
|
||||||
if(*ptr) free(*ptr);
|
if(*ptr) free(*ptr);
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
|
inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
|
||||||
{
|
{
|
||||||
AVInterruptCallbackMetadata* metadata = (AVInterruptCallbackMetadata*)ptr;
|
AVInterruptCallbackMetadata* metadata = (AVInterruptCallbackMetadata*)ptr;
|
||||||
@ -380,6 +396,7 @@ inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
|
|||||||
|
|
||||||
return metadata->timeout ? -1 : 0;
|
return metadata->timeout ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct CvCapture_FFMPEG
|
struct CvCapture_FFMPEG
|
||||||
@ -435,8 +452,9 @@ struct CvCapture_FFMPEG
|
|||||||
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
|
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
|
||||||
AVDictionary *dict;
|
AVDictionary *dict;
|
||||||
#endif
|
#endif
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
AVInterruptCallbackMetadata interrupt_metadata;
|
AVInterruptCallbackMetadata interrupt_metadata;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void CvCapture_FFMPEG::init()
|
void CvCapture_FFMPEG::init()
|
||||||
@ -735,6 +753,7 @@ bool CvCapture_FFMPEG::open( const char* _filename )
|
|||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
/* interrupt callback */
|
/* interrupt callback */
|
||||||
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
|
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
|
||||||
get_monotonic_time(&interrupt_metadata.value);
|
get_monotonic_time(&interrupt_metadata.value);
|
||||||
@ -742,6 +761,7 @@ bool CvCapture_FFMPEG::open( const char* _filename )
|
|||||||
ic = avformat_alloc_context();
|
ic = avformat_alloc_context();
|
||||||
ic->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
|
ic->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
|
||||||
ic->interrupt_callback.opaque = &interrupt_metadata;
|
ic->interrupt_callback.opaque = &interrupt_metadata;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
|
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
|
||||||
av_dict_set(&dict, "rtsp_transport", "tcp", 0);
|
av_dict_set(&dict, "rtsp_transport", "tcp", 0);
|
||||||
@ -856,11 +876,13 @@ bool CvCapture_FFMPEG::grabFrame()
|
|||||||
|
|
||||||
av_free_packet (&packet);
|
av_free_packet (&packet);
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
if (interrupt_metadata.timeout)
|
if (interrupt_metadata.timeout)
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int ret = av_read_frame(ic, &packet);
|
int ret = av_read_frame(ic, &packet);
|
||||||
if (ret == AVERROR(EAGAIN)) continue;
|
if (ret == AVERROR(EAGAIN)) continue;
|
||||||
@ -898,8 +920,10 @@ bool CvCapture_FFMPEG::grabFrame()
|
|||||||
frame_number++;
|
frame_number++;
|
||||||
valid = true;
|
valid = true;
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
// update interrupt value
|
// update interrupt value
|
||||||
get_monotonic_time(&interrupt_metadata.value);
|
get_monotonic_time(&interrupt_metadata.value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2486,7 +2510,9 @@ private:
|
|||||||
int video_stream_id_;
|
int video_stream_id_;
|
||||||
AVPacket pkt_;
|
AVPacket pkt_;
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
AVInterruptCallbackMetadata interrupt_metadata;
|
AVInterruptCallbackMetadata interrupt_metadata;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
|
bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
|
||||||
@ -2497,6 +2523,7 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
|
|||||||
video_stream_id_ = -1;
|
video_stream_id_ = -1;
|
||||||
memset(&pkt_, 0, sizeof(AVPacket));
|
memset(&pkt_, 0, sizeof(AVPacket));
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
/* interrupt callback */
|
/* interrupt callback */
|
||||||
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
|
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
|
||||||
get_monotonic_time(&interrupt_metadata.value);
|
get_monotonic_time(&interrupt_metadata.value);
|
||||||
@ -2504,6 +2531,7 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
|
|||||||
ctx_ = avformat_alloc_context();
|
ctx_ = avformat_alloc_context();
|
||||||
ctx_->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
|
ctx_->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
|
||||||
ctx_->interrupt_callback.opaque = &interrupt_metadata;
|
ctx_->interrupt_callback.opaque = &interrupt_metadata;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
|
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
|
||||||
avformat_network_init();
|
avformat_network_init();
|
||||||
@ -2621,18 +2649,22 @@ bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFi
|
|||||||
// get the next frame
|
// get the next frame
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
if(interrupt_metadata.timeout)
|
if(interrupt_metadata.timeout)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int ret = av_read_frame(ctx_, &pkt_);
|
int ret = av_read_frame(ctx_, &pkt_);
|
||||||
|
|
||||||
if (ret == AVERROR(EAGAIN))
|
if (ret == AVERROR(EAGAIN))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#if USE_AV_INTERRUPT_CALLBACK
|
||||||
// update interrupt value
|
// update interrupt value
|
||||||
get_monotonic_time(&interrupt_metadata.value);
|
get_monotonic_time(&interrupt_metadata.value);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user