Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
b148ef2b
Commit
b148ef2b
authored
Feb 04, 2016
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6053 from peters:master
parents
b2d44663
da480619
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
180 additions
and
0 deletions
+180
-0
cap_ffmpeg_impl.hpp
modules/videoio/src/cap_ffmpeg_impl.hpp
+180
-0
No files found.
modules/videoio/src/cap_ffmpeg_impl.hpp
View file @
b148ef2b
...
...
@@ -129,12 +129,22 @@ extern "C" {
#if defined WIN32 || defined _WIN32
#include <windows.h>
#if defined _MSC_VER && _MSC_VER < 1900
struct
timespec
{
time_t
tv_sec
;
long
tv_nsec
;
};
#endif
#elif defined __linux__ || defined __APPLE__
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#if defined __APPLE__
#include <sys/sysctl.h>
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#endif
...
...
@@ -184,6 +194,116 @@ extern "C" {
#endif
#endif
#define LIBAVFORMAT_INTERRUPT_TIMEOUT_MS 30000
#ifdef WIN32
// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
inline
LARGE_INTEGER
get_filetime_offset
()
{
SYSTEMTIME
s
;
FILETIME
f
;
LARGE_INTEGER
t
;
s
.
wYear
=
1970
;
s
.
wMonth
=
1
;
s
.
wDay
=
1
;
s
.
wHour
=
0
;
s
.
wMinute
=
0
;
s
.
wSecond
=
0
;
s
.
wMilliseconds
=
0
;
SystemTimeToFileTime
(
&
s
,
&
f
);
t
.
QuadPart
=
f
.
dwHighDateTime
;
t
.
QuadPart
<<=
32
;
t
.
QuadPart
|=
f
.
dwLowDateTime
;
return
t
;
}
inline
void
get_monotonic_time
(
timespec
*
tv
)
{
LARGE_INTEGER
t
;
FILETIME
f
;
double
microseconds
;
static
LARGE_INTEGER
offset
;
static
double
frequencyToMicroseconds
;
static
int
initialized
=
0
;
static
BOOL
usePerformanceCounter
=
0
;
if
(
!
initialized
)
{
LARGE_INTEGER
performanceFrequency
;
initialized
=
1
;
usePerformanceCounter
=
QueryPerformanceFrequency
(
&
performanceFrequency
);
if
(
usePerformanceCounter
)
{
QueryPerformanceCounter
(
&
offset
);
frequencyToMicroseconds
=
(
double
)
performanceFrequency
.
QuadPart
/
1000000.
;
}
else
{
offset
=
get_filetime_offset
();
frequencyToMicroseconds
=
10.
;
}
}
if
(
usePerformanceCounter
)
{
QueryPerformanceCounter
(
&
t
);
}
else
{
GetSystemTimeAsFileTime
(
&
f
);
t
.
QuadPart
=
f
.
dwHighDateTime
;
t
.
QuadPart
<<=
32
;
t
.
QuadPart
|=
f
.
dwLowDateTime
;
}
t
.
QuadPart
-=
offset
.
QuadPart
;
microseconds
=
(
double
)
t
.
QuadPart
/
frequencyToMicroseconds
;
t
.
QuadPart
=
microseconds
;
tv
->
tv_sec
=
t
.
QuadPart
/
1000000
;
tv
->
tv_nsec
=
(
t
.
QuadPart
%
1000000
)
*
1000
;
}
#else
inline
void
get_monotonic_time
(
timespec
*
time
)
{
#if defined(__APPLE__) && defined(__MACH__)
clock_serv_t
cclock
;
mach_timespec_t
mts
;
host_get_clock_service
(
mach_host_self
(),
CALENDAR_CLOCK
,
&
cclock
);
clock_get_time
(
cclock
,
&
mts
);
mach_port_deallocate
(
mach_task_self
(),
cclock
);
time
->
tv_sec
=
mts
.
tv_sec
;
time
->
tv_nsec
=
mts
.
tv_nsec
;
#else
clock_gettime
(
CLOCK_MONOTONIC
,
time
);
#endif
}
#endif
inline
timespec
get_monotonic_time_diff
(
timespec
start
,
timespec
end
)
{
timespec
temp
;
if
(
end
.
tv_nsec
-
start
.
tv_nsec
<
0
)
{
temp
.
tv_sec
=
end
.
tv_sec
-
start
.
tv_sec
-
1
;
temp
.
tv_nsec
=
1000000000
+
end
.
tv_nsec
-
start
.
tv_nsec
;
}
else
{
temp
.
tv_sec
=
end
.
tv_sec
-
start
.
tv_sec
;
temp
.
tv_nsec
=
end
.
tv_nsec
-
start
.
tv_nsec
;
}
return
temp
;
}
inline
double
get_monotonic_time_diff_ms
(
timespec
time1
,
timespec
time2
)
{
timespec
delta
=
get_monotonic_time_diff
(
time1
,
time2
);
double
milliseconds
=
delta
.
tv_sec
*
1000
+
(
double
)
delta
.
tv_nsec
/
1000000.0
;
return
milliseconds
;
}
static
int
get_number_of_cpus
(
void
)
{
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0)
...
...
@@ -233,6 +353,14 @@ struct Image_FFMPEG
};
struct
AVInterruptCallbackMetadata
{
timespec
value
;
unsigned
int
timeout_after_ms
;
int
timeout
;
};
inline
void
_opencv_ffmpeg_free
(
void
**
ptr
)
{
if
(
*
ptr
)
free
(
*
ptr
);
...
...
@@ -240,6 +368,20 @@ inline void _opencv_ffmpeg_free(void** ptr)
}
inline
int
_opencv_ffmpeg_interrupt_callback
(
void
*
ptr
)
{
AVInterruptCallbackMetadata
*
metadata
=
(
AVInterruptCallbackMetadata
*
)
ptr
;
assert
(
metadata
);
timespec
now
;
get_monotonic_time
(
&
now
);
metadata
->
timeout
=
get_monotonic_time_diff_ms
(
metadata
->
value
,
now
)
>
metadata
->
timeout_after_ms
;
return
metadata
->
timeout
?
-
1
:
0
;
}
struct
CvCapture_FFMPEG
{
bool
open
(
const
char
*
filename
);
...
...
@@ -293,6 +435,8 @@ struct CvCapture_FFMPEG
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
AVDictionary
*
dict
;
#endif
AVInterruptCallbackMetadata
interrupt_metadata
;
};
void
CvCapture_FFMPEG
::
init
()
...
...
@@ -591,6 +735,14 @@ bool CvCapture_FFMPEG::open( const char* _filename )
close
();
/* 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
;
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
av_dict_set
(
&
dict
,
"rtsp_transport"
,
"tcp"
,
0
);
int
err
=
avformat_open_input
(
&
ic
,
_filename
,
NULL
,
&
dict
);
...
...
@@ -703,6 +855,13 @@ bool CvCapture_FFMPEG::grabFrame()
{
av_free_packet
(
&
packet
);
if
(
interrupt_metadata
.
timeout
)
{
valid
=
false
;
break
;
}
int
ret
=
av_read_frame
(
ic
,
&
packet
);
if
(
ret
==
AVERROR
(
EAGAIN
))
continue
;
...
...
@@ -738,6 +897,9 @@ bool CvCapture_FFMPEG::grabFrame()
picture_pts
=
packet
.
pts
!=
AV_NOPTS_VALUE_
&&
packet
.
pts
!=
0
?
packet
.
pts
:
packet
.
dts
;
frame_number
++
;
valid
=
true
;
// update interrupt value
get_monotonic_time
(
&
interrupt_metadata
.
value
);
}
else
{
...
...
@@ -2323,6 +2485,8 @@ private:
AVFormatContext
*
ctx_
;
int
video_stream_id_
;
AVPacket
pkt_
;
AVInterruptCallbackMetadata
interrupt_metadata
;
};
bool
InputMediaStream_FFMPEG
::
open
(
const
char
*
fileName
,
int
*
codec
,
int
*
chroma_format
,
int
*
width
,
int
*
height
)
...
...
@@ -2333,6 +2497,14 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
video_stream_id_
=
-
1
;
memset
(
&
pkt_
,
0
,
sizeof
(
AVPacket
));
/* 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
;
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
avformat_network_init
();
#endif
...
...
@@ -2449,11 +2621,19 @@ bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFi
// get the next frame
for
(;;)
{
if
(
interrupt_metadata
.
timeout
)
{
break
;
}
int
ret
=
av_read_frame
(
ctx_
,
&
pkt_
);
if
(
ret
==
AVERROR
(
EAGAIN
))
continue
;
// update interrupt value
get_monotonic_time
(
&
interrupt_metadata
.
value
);
if
(
ret
<
0
)
{
if
(
ret
==
(
int
)
AVERROR_EOF
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment