#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
#ifdef WIN32
// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
+static
inline LARGE_INTEGER get_filetime_offset()
{
SYSTEMTIME s;
return t;
}
+static
inline void get_monotonic_time(timespec *tv)
{
LARGE_INTEGER t;
tv->tv_nsec = (t.QuadPart % 1000000) * 1000;
}
#else
+static
inline void get_monotonic_time(timespec *time)
{
#if defined(__APPLE__) && defined(__MACH__)
}
#endif
+static
inline timespec get_monotonic_time_diff(timespec start, timespec end)
{
timespec temp;
return temp;
}
+static
inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
{
timespec delta = get_monotonic_time_diff(time1, time2);
return milliseconds;
}
+#endif // USE_AV_INTERRUPT_CALLBACK
static int get_number_of_cpus(void)
{
};
+#if USE_AV_INTERRUPT_CALLBACK
struct AVInterruptCallbackMetadata
{
timespec value;
int timeout;
};
-
+static
inline void _opencv_ffmpeg_free(void** ptr)
{
if(*ptr) free(*ptr);
*ptr = 0;
}
-
+static
inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
{
AVInterruptCallbackMetadata* metadata = (AVInterruptCallbackMetadata*)ptr;
return metadata->timeout ? -1 : 0;
}
+#endif
struct CvCapture_FFMPEG
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
AVDictionary *dict;
#endif
-
+#if USE_AV_INTERRUPT_CALLBACK
AVInterruptCallbackMetadata interrupt_metadata;
+#endif
};
void CvCapture_FFMPEG::init()
close();
+#if USE_AV_INTERRUPT_CALLBACK
/* interrupt callback */
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
get_monotonic_time(&interrupt_metadata.value);
ic = avformat_alloc_context();
ic->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
ic->interrupt_callback.opaque = &interrupt_metadata;
+#endif
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
av_dict_set(&dict, "rtsp_transport", "tcp", 0);
av_free_packet (&packet);
+#if USE_AV_INTERRUPT_CALLBACK
if (interrupt_metadata.timeout)
{
valid = false;
break;
}
+#endif
int ret = av_read_frame(ic, &packet);
if (ret == AVERROR(EAGAIN)) continue;
frame_number++;
valid = true;
+#if USE_AV_INTERRUPT_CALLBACK
// update interrupt value
get_monotonic_time(&interrupt_metadata.value);
+#endif
}
else
{
int video_stream_id_;
AVPacket pkt_;
+#if USE_AV_INTERRUPT_CALLBACK
AVInterruptCallbackMetadata interrupt_metadata;
+#endif
};
bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
video_stream_id_ = -1;
memset(&pkt_, 0, sizeof(AVPacket));
+#if USE_AV_INTERRUPT_CALLBACK
/* interrupt callback */
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_TIMEOUT_MS;
get_monotonic_time(&interrupt_metadata.value);
ctx_ = avformat_alloc_context();
ctx_->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
ctx_->interrupt_callback.opaque = &interrupt_metadata;
+#endif
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
avformat_network_init();
// get the next frame
for (;;)
{
+#if USE_AV_INTERRUPT_CALLBACK
if(interrupt_metadata.timeout)
{
break;
}
+#endif
int ret = av_read_frame(ctx_, &pkt_);
if (ret == AVERROR(EAGAIN))
continue;
+#if USE_AV_INTERRUPT_CALLBACK
// update interrupt value
get_monotonic_time(&interrupt_metadata.value);
+#endif
if (ret < 0)
{