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
9615f8c9
Commit
9615f8c9
authored
Apr 23, 2018
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #11358 from mshabunin:enable-xine
parents
b8a6bfb5
a9bdf75c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
246 additions
and
725 deletions
+246
-725
videoio.hpp
modules/videoio/include/opencv2/videoio.hpp
+2
-1
cap.cpp
modules/videoio/src/cap.cpp
+10
-6
cap_xine.cpp
modules/videoio/src/cap_xine.cpp
+223
-714
precomp.hpp
modules/videoio/src/precomp.hpp
+2
-2
test_video_io.cpp
modules/videoio/test/test_video_io.cpp
+9
-2
No files found.
modules/videoio/include/opencv2/videoio.hpp
View file @
9615f8c9
...
...
@@ -116,7 +116,8 @@ enum VideoCaptureAPIs {
CAP_IMAGES
=
2000
,
//!< OpenCV Image Sequence (e.g. img_%02d.jpg)
CAP_ARAVIS
=
2100
,
//!< Aravis SDK
CAP_OPENCV_MJPEG
=
2200
,
//!< Built-in OpenCV MotionJPEG codec
CAP_INTEL_MFX
=
2300
//!< Intel MediaSDK
CAP_INTEL_MFX
=
2300
,
//!< Intel MediaSDK
CAP_XINE
=
2400
,
//!< XINE engine (Linux)
};
/** @brief %VideoCapture generic properties identifier.
...
...
modules/videoio/src/cap.cpp
View file @
9615f8c9
...
...
@@ -318,15 +318,11 @@ CV_IMPL CvCapture * cvCreateFileCaptureWithPreference (const char * filename, in
if
(
apiPreference
)
break
;
#endif
case
CAP_MSMF
:
#ifdef HAVE_MSMF
case
CAP_MSMF
:
TRY_OPEN
(
result
,
cvCreateFileCapture_MSMF
(
filename
))
#endif
#ifdef HAVE_XINE
TRY_OPEN
(
result
,
cvCreateFileCapture_XINE
(
filename
))
#endif
if
(
apiPreference
)
break
;
#endif
#ifdef HAVE_VFW
case
CAP_VFW
:
...
...
@@ -540,6 +536,14 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename, int apiPr
{
bool
useAny
=
(
apiPreference
==
CAP_ANY
);
Ptr
<
IVideoCapture
>
capture
;
#ifdef HAVE_XINE
if
(
useAny
||
apiPreference
==
CAP_XINE
)
{
capture
=
createXINECapture
(
filename
.
c_str
());
if
(
capture
&&
capture
->
isOpened
())
return
capture
;
}
#endif
#ifdef HAVE_GPHOTO2
if
(
useAny
||
apiPreference
==
CAP_GPHOTO2
)
{
...
...
modules/videoio/src/cap_xine.cpp
View file @
9615f8c9
/*M//////////////////////////////////////////////////////////
/////////////////////////////
/*M//////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
...
...
@@ -45,802 +45,311 @@
// Institute of Communications Engineering
// RWTH Aachen University
#include "precomp.hpp"
// required to enable some functions used here...
#define XINE_ENABLE_EXPERIMENTAL_FEATURES
#include <cassert>
extern
"C"
{
#include <xine.h>
//
#include <xine/xineutils.h>
#include <xine/xineutils.h>
// forward declaration from <xine/xineutils.h>
const
char
*
xine_get_homedir
(
void
);
}
using
namespace
cv
;
typedef
struct
CvCaptureAVI_XINE
class
XINECapture
:
public
IVideoCapture
{
/// method call table
xine_t
*
xine
;
xine_stream_t
*
stream
;
xine_video_port_t
*
vo_port
;
/// frame returned by xine_get_next_video_frame()
// method call table
xine_t
*
xine
;
xine_stream_t
*
stream
;
xine_video_port_t
*
vo_port
;
xine_video_frame_t
xine_frame
;
IplImage
*
yuv_frame
;
IplImage
*
bgr_frame
;
/// image dimansions of the input stream.
CvSize
size
;
/// framenumber of the last frame received from xine_get_next_video_frame().
/// note: always keep this value updated !!!!
int
frame_number
;
/// framerate of the opened stream
double
frame_rate
;
/// duration of a frame in stream
double
frame_duration
;
/// indicated if input is seekable
bool
seekable
;
}
CvCaptureAVI_XINE
;
// 4:2:2 interleaved -> BGR
static
void
icvYUY2toBGR
(
CvCaptureAVI_XINE
*
capture
)
{
uint8_t
*
v
=
capture
->
xine_frame
.
data
;
int
offset
;
for
(
int
y
=
0
;
y
<
capture
->
yuv_frame
->
height
;
y
++
)
Size
size
;
int
frame_number
;
double
frame_rate
;
// fps
double
frame_duration
;
// ms
bool
seekable
;
public
:
XINECapture
()
:
xine
(
0
),
stream
(
0
),
vo_port
(
0
),
frame_number
(
-
1
),
frame_rate
(
0.
),
frame_duration
(
0.
),
seekable
(
false
)
{
offset
=
y
*
capture
->
yuv_frame
->
widthStep
;
for
(
int
x
=
0
;
x
<
capture
->
yuv_frame
->
width
;
x
++
,
offset
+=
3
)
{
capture
->
yuv_frame
->
imageData
[
offset
+
1
]
=
v
[
3
];
capture
->
yuv_frame
->
imageData
[
offset
+
2
]
=
v
[
1
];
if
(
x
&
1
)
{
capture
->
yuv_frame
->
imageData
[
offset
]
=
v
[
2
];
v
+=
4
;
}
else
{
capture
->
yuv_frame
->
imageData
[
offset
]
=
v
[
0
];
}
}
xine_video_frame_t
z
=
{};
xine_frame
=
z
;
}
// convert to BGR
cvCvtColor
(
capture
->
yuv_frame
,
capture
->
bgr_frame
,
CV_YCrCb2BGR
);
}
~
XINECapture
()
{
close
();
}
// 4:2:0 planary -> BGR
static
void
icvYV12toBGR
(
CvCaptureAVI_XINE
*
capture
)
{
IplImage
*
yuv
=
capture
->
yuv_frame
;
int
w_Y
=
capture
->
size
.
width
;
int
h_Y
=
capture
->
size
.
height
;
bool
isOpened
()
const
CV_OVERRIDE
{
return
xine
&&
stream
;
}
int
w_UV
=
w_Y
>>
1
;
int
getCaptureDomain
()
CV_OVERRIDE
{
return
CAP_XINE
;
}
int
size_Y
=
w_Y
*
h_Y
;
int
size_UV
=
size_Y
/
4
;
int
line
=
yuv
->
widthStep
;
uint8_t
*
addr_Y
=
capture
->
xine_frame
.
data
;
uint8_t
*
addr_U
=
addr_Y
+
size_Y
;
uint8_t
*
addr_V
=
addr_U
+
size_UV
;
// YYYY..UU.VV. -> BGRBGRBGR...
for
(
int
y
=
0
;
y
<
h_Y
;
y
++
)
void
close
()
{
int
offset
=
y
*
line
;
for
(
int
x
=
0
;
x
<
w_Y
;
x
++
,
offset
+=
3
)
if
(
vo_port
&&
xine_frame
.
data
)
{
/*
if ( x&1 )
{
addr_U++; addr_V++;
}
*/
int
one_zero
=
x
&
1
;
addr_U
+=
one_zero
;
addr_V
+=
one_zero
;
yuv
->
imageData
[
offset
]
=
*
(
addr_Y
++
);
yuv
->
imageData
[
offset
+
1
]
=
*
addr_U
;
yuv
->
imageData
[
offset
+
2
]
=
*
addr_V
;
xine_free_video_frame
(
vo_port
,
&
xine_frame
);
}
if
(
y
&
1
)
if
(
stream
)
{
addr_U
-=
w_UV
;
addr_V
-=
w_UV
;
xine_close
(
stream
);
stream
=
0
;
}
if
(
vo_port
)
{
xine_close_video_driver
(
xine
,
vo_port
);
vo_port
=
0
;
}
if
(
xine
)
{
xine_exit
(
xine
);
xine
=
0
;
}
}
/* convert to BGR */
cvCvtColor
(
capture
->
yuv_frame
,
capture
->
bgr_frame
,
CV_YCrCb2BGR
);
}
static
void
icvCloseAVI_XINE
(
CvCaptureAVI_XINE
*
capture
)
{
xine_free_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
);
if
(
capture
->
yuv_frame
)
cvReleaseImage
(
&
capture
->
yuv_frame
);
if
(
capture
->
bgr_frame
)
cvReleaseImage
(
&
capture
->
bgr_frame
);
bool
open
(
const
char
*
filename
)
{
CV_Assert
(
!
xine
,
!
stream
,
!
vo_port
);
char
configfile
[
2048
]
=
{
0
};
xine_close
(
capture
->
stream
);
// xine_dispose( capture->stream );
xine
=
xine_new
();
sprintf
(
configfile
,
"%s%s"
,
xine_get_homedir
(),
"/.xine/config"
);
xine_config_load
(
xine
,
configfile
);
xine_init
(
xine
);
xine_engine_set_param
(
xine
,
0
,
0
);
if
(
capture
->
vo_port
)
xine_close_video_driver
(
capture
->
xine
,
capture
->
vo_port
);
vo_port
=
xine_new_framegrab_video_port
(
xine
);
if
(
!
vo_port
)
return
false
;
xine_exit
(
capture
->
xine
);
}
stream
=
xine_stream_new
(
xine
,
NULL
,
vo_port
);
if
(
!
xine_open
(
stream
,
filename
))
return
false
;
// reset stream...
if
(
!
xine_play
(
stream
,
0
,
0
))
return
false
;
/**
* CHECKS IF THE STREAM IN * capture IS SEEKABLE.
**/
static
void
icvCheckSeekAVI_XINE
(
CvCaptureAVI_XINE
*
capture
)
{
OPENCV_ASSERT
(
capture
,
"icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )"
,
"illegal capture->vo_port"
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvCheckSeekAVI_XINE ... start
\n
"
);
#endif
// temp. frame for testing.
xine_video_frame_t
tmp
;
// try to seek to a future frame...
xine_play
(
capture
->
stream
,
0
,
300
);
/* 300msec */
// try to receive the frame...
xine_get_next_video_frame
(
capture
->
vo_port
,
&
tmp
);
// if the framenumber is still 0, we can't use the xine seek functionality
capture
->
seekable
=
(
tmp
.
frame_number
!=
0
);
// reset stream
xine_play
(
capture
->
stream
,
0
,
0
);
// release xine_frame
xine_free_video_frame
(
capture
->
vo_port
,
&
tmp
);
#ifndef NDEBUG
if
(
capture
->
seekable
)
fprintf
(
stderr
,
"(DEBUG) icvCheckSeekAVI_XINE: Input is seekable, using XINE seek implementation.
\n
"
);
else
fprintf
(
stderr
,
"(DEBUG) icvCheckSeekAVI_XINE: Input is NOT seekable, using fallback function.
\n
"
);
fprintf
(
stderr
,
"(DEBUG) icvCheckSeekAVI_XINE ... end
\n
"
);
#endif
}
// initialize some internals...
frame_number
=
0
;
static
int
icvOpenAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
const
char
*
filename
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvOpenAVI_XINE ... start
\n
"
);
#endif
if
(
!
xine_get_next_video_frame
(
vo_port
,
&
xine_frame
)
)
return
false
;
char
configfile
[
2048
]
;
size
=
Size
(
xine_frame
.
width
,
xine_frame
.
height
)
;
capture
->
xine
=
xine_new
(
);
sprintf
(
configfile
,
"%s%s"
,
xine_get_homedir
(),
"/.xine/config"
)
;
xine_free_video_frame
(
vo_port
,
&
xine_frame
);
xine_frame
.
data
=
0
;
xine_config_load
(
capture
->
xine
,
configfile
);
xine_init
(
capture
->
xine
);
{
xine_video_frame_t
tmp
;
if
(
!
xine_play
(
stream
,
0
,
300
))
/* 300msec */
return
false
;
if
(
!
xine_get_next_video_frame
(
vo_port
,
&
tmp
))
return
false
;
seekable
=
(
tmp
.
frame_number
!=
0
);
xine_free_video_frame
(
vo_port
,
&
tmp
);
if
(
!
xine_play
(
stream
,
0
,
0
))
return
false
;
}
xine_engine_set_param
(
capture
->
xine
,
0
,
0
);
capture
->
vo_port
=
xine_new_framegrab_video_port
(
capture
->
xine
);
if
(
capture
->
vo_port
==
NULL
)
{
printf
(
"(ERROR)icvOpenAVI_XINE(): Unable to initialize video driver.
\n
"
);
return
0
;
frame_duration
=
xine_get_stream_info
(
stream
,
XINE_STREAM_INFO_FRAME_DURATION
)
/
90.
;
frame_rate
=
frame_duration
>
0
?
1000
/
frame_duration
:
0.
;
return
true
;
}
capture
->
stream
=
xine_stream_new
(
capture
->
xine
,
NULL
,
capture
->
vo_port
);
if
(
!
xine_open
(
capture
->
stream
,
filename
)
)
bool
grabFrame
()
CV_OVERRIDE
{
printf
(
"(ERROR)icvOpenAVI_XINE(): Unable to open source '%s'
\n
"
,
filename
);
return
0
;
CV_Assert
(
vo_port
);
bool
res
=
xine_get_next_video_frame
(
vo_port
,
&
xine_frame
);
if
(
res
)
frame_number
++
;
return
res
;
}
// reset stream...
xine_play
(
capture
->
stream
,
0
,
0
);
// initialize some internals...
capture
->
frame_number
=
0
;
if
(
!
xine_get_next_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
)
)
bool
retrieveFrame
(
int
,
OutputArray
out
)
CV_OVERRIDE
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvOpenAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
}
capture
->
size
=
cvSize
(
capture
->
xine_frame
.
width
,
capture
->
xine_frame
.
height
);
capture
->
yuv_frame
=
cvCreateImage
(
capture
->
size
,
IPL_DEPTH_8U
,
3
);
capture
->
bgr_frame
=
cvCreateImage
(
capture
->
size
,
IPL_DEPTH_8U
,
3
);
xine_free_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
);
capture
->
xine_frame
.
data
[
0
]
=
0
;
icvCheckSeekAVI_XINE
(
capture
);
capture
->
frame_duration
=
xine_get_stream_info
(
capture
->
stream
,
XINE_STREAM_INFO_FRAME_DURATION
)
/
90.
;
capture
->
frame_rate
=
1000
/
capture
->
frame_duration
;
CV_Assert
(
stream
);
CV_Assert
(
vo_port
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) frame_duration = %f, framerate = %f
\n
"
,
capture
->
frame_duration
,
capture
->
frame_rate
);
#endif
OPENCV_ASSERT
(
capture
->
yuv_frame
,
"icvOpenAVI_XINE( CvCaptureAVI_XINE *, const char *)"
,
"couldn't create yuv frame"
);
OPENCV_ASSERT
(
capture
->
bgr_frame
,
"icvOpenAVI_XINE( CvCaptureAVI_XINE *, const char *)"
,
"couldn't create bgr frame"
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvOpenAVI_XINE ... end
\n
"
);
#endif
return
1
;
}
static
int
icvGrabFrameAVI_XINE
(
CvCaptureAVI_XINE
*
capture
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvGrabFrameAVI_XINE ... start
\n
"
);
#endif
if
(
xine_frame
.
data
==
0
)
return
false
;
OPENCV_ASSERT
(
capture
,
"icvGrabFrameAVI_XINE( CvCaptureAVI_XINE * )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvGrabFrameAVI_XINE( CvCaptureAVI_XINE * )"
,
"illegal capture->vo_port"
);
bool
res
=
false
;
Mat
frame_bgr
;
int
res
=
xine_get_next_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
);
/* always keep internal framenumber updated !!! */
if
(
res
)
capture
->
frame_number
++
;
switch
(
xine_frame
.
colorspace
)
{
case
XINE_IMGFMT_YV12
:
// actual format seems to be I420 (or IYUV)
{
Mat
frame
(
Size
(
xine_frame
.
width
,
xine_frame
.
height
*
3
/
2
),
CV_8UC1
,
xine_frame
.
data
);
cv
::
cvtColor
(
frame
,
out
,
cv
::
COLOR_YUV2BGR_I420
);
res
=
true
;
}
break
;
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvGrabFrameAVI_XINE ... end
\n
"
);
#endif
return
res
;
}
case
XINE_IMGFMT_YUY2
:
{
Mat
frame
(
Size
(
xine_frame
.
width
,
xine_frame
.
height
),
CV_8UC2
,
xine_frame
.
data
);
cv
::
cvtColor
(
frame
,
out
,
cv
::
COLOR_YUV2BGR_YUY2
);
res
=
true
;
}
break
;
default
:
break
;
}
static
const
IplImage
*
icvRetrieveFrameAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
int
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvRetrieveFrameAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )"
,
"illegal capture->vo_port"
);
/* no frame grabbed yet? so let's do it now! */
int
res
=
0
;
if
(
capture
->
xine_frame
.
data
==
0
)
{
res
=
icvGrabFrameAVI_XINE
(
capture
);
}
else
{
res
=
1
;
// always release last xine_frame, not needed anymore
xine_free_video_frame
(
vo_port
,
&
xine_frame
);
xine_frame
.
data
=
0
;
return
res
;
}
if
(
res
)
double
getProperty
(
int
property_id
)
const
CV_OVERRIDE
{
switch
(
capture
->
xine_frame
.
colorspace
)
CV_Assert
(
xine
,
vo_port
,
stream
);
int
pos_t
,
pos_l
,
length
;
bool
res
=
(
bool
)
xine_get_pos_length
(
stream
,
&
pos_l
,
&
pos_t
,
&
length
);
switch
(
property_id
)
{
case
XINE_IMGFMT_YV12
:
icvYV12toBGR
(
capture
);
#ifndef NDEBUG
printf
(
"(DEBUG)icvRetrieveFrameAVI_XINE: converted YV12 to BGR.
\n
"
);
#endif
break
;
case
XINE_IMGFMT_YUY2
:
icvYUY2toBGR
(
capture
);
#ifndef NDEBUG
printf
(
"(DEBUG)icvRetrieveFrameAVI_XINE: converted YUY2 to BGR.
\n
"
);
#endif
break
;
case
XINE_IMGFMT_XVMC
:
printf
(
"(ERROR)icvRetrieveFrameAVI_XINE: XVMC format not supported!
\n
"
);
break
;
case
XINE_IMGFMT_XXMC
:
printf
(
"(ERROR)icvRetrieveFrameAVI_XINE: XXMC format not supported!
\n
"
);
break
;
default:
printf
(
"(ERROR)icvRetrieveFrameAVI_XINE: unknown color/pixel format!
\n
"
);
case
CV_CAP_PROP_POS_MSEC
:
return
res
?
pos_t
:
0
;
case
CV_CAP_PROP_POS_FRAMES
:
return
frame_number
;
case
CV_CAP_PROP_POS_AVI_RATIO
:
return
length
&&
res
?
pos_l
/
65535.0
:
0.0
;
case
CV_CAP_PROP_FRAME_WIDTH
:
return
size
.
width
;
case
CV_CAP_PROP_FRAME_HEIGHT
:
return
size
.
height
;
case
CV_CAP_PROP_FPS
:
return
frame_rate
;
case
CV_CAP_PROP_FOURCC
:
return
(
double
)
xine_get_stream_info
(
stream
,
XINE_STREAM_INFO_VIDEO_FOURCC
);
}
/* always release last xine_frame, not needed anymore, but store its frame_number in *capture ! */
xine_free_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
);
capture
->
xine_frame
.
data
=
0
;
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvRetrieveFrameAVI_XINE ... end
\n
"
);
#endif
return
capture
->
bgr_frame
;
return
0
;
}
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvRetrieveFrameAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
}
/**
* THIS FUNCTION IS A FALLBACK FUNCTION FOR THE CASE THAT THE XINE SEEK IMPLEMENTATION
* DOESN'T WORK WITH THE ACTUAL INPUT. THIS FUNCTION IS ONLY USED IN THE CASE OF AN EMERGENCY,
* BECAUSE IT IS VERY SLOW !
**/
static
int
icvOldSeekFrameAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
int
f
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvOldSeekFrameAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvRetricvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->vo_port"
);
// not needed tnx to asserts...
// we need a valid capture context and it's stream to seek through
// if ( !capture || !capture->stream ) return 0;
// no need to seek if we are already there...
if
(
f
==
capture
->
frame_number
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvOldSeekFrameAVI_XINE ... end
\n
"
);
#endif
return
1
;
}
// if the requested position is behind out actual position,
// we just need to read the remaining amount of frames until we are there.
else
if
(
f
>
capture
->
frame_number
)
{
for
(
;
capture
->
frame_number
<
f
;
capture
->
frame_number
++
)
/// un-increment framenumber grabbing failed
if
(
!
xine_get_next_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
)
)
{
capture
->
frame_number
--
;
break
;
}
else
{
xine_free_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
);
}
}
// otherwise we need to reset the stream and
// start reading frames from the beginning.
else
// f < capture->frame_number
bool
setProperty
(
int
property_id
,
double
value
)
CV_OVERRIDE
{
/// reset stream, should also work with non-seekable input
xine_play
(
capture
->
stream
,
0
,
0
);
/// read frames until we are at the requested frame
for
(
capture
->
frame_number
=
0
;
capture
->
frame_number
<
f
;
capture
->
frame_number
++
)
/// un-increment last framenumber if grabbing failed
if
(
!
xine_get_next_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
)
)
{
capture
->
frame_number
--
;
break
;
}
else
{
xine_free_video_frame
(
capture
->
vo_port
,
&
capture
->
xine_frame
);
}
CV_Assert
(
stream
);
CV_Assert
(
vo_port
);
switch
(
property_id
)
{
case
CV_CAP_PROP_POS_MSEC
:
return
seekTime
((
int
)
value
);
case
CV_CAP_PROP_POS_FRAMES
:
return
seekFrame
((
int
)
value
);
case
CV_CAP_PROP_POS_AVI_RATIO
:
return
seekRatio
(
value
);
default
:
return
false
;
}
}
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvOldSeekFrameAVI_XINE ... end
\n
"
);
#endif
return
(
f
==
capture
->
frame_number
)
?
1
:
0
;
}
static
int
icvSeekFrameAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
int
f
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->vo_port"
);
// not needed tnx to asserts...
// we need a valid capture context and it's stream to seek through
// if ( !capture || !capture->stream ) return 0;
if
(
capture
->
seekable
)
protected
:
bool
oldSeekFrame
(
int
f
)
{
/// use xinelib's seek functionality
int
new_time
=
(
int
)
(
(
f
+
1
)
*
(
float
)
capture
->
frame_duration
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) calling xine_play()"
);
#endif
if
(
xine_play
(
capture
->
stream
,
0
,
new_time
)
)
CV_Assert
(
xine
,
vo_port
,
stream
);
// no need to seek if we are already there...
if
(
f
==
frame_number
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"ok
\n
"
);
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ... end
\n
"
);
#endif
capture
->
frame_number
=
f
;
return
1
;
return
true
;
}
else
else
if
(
f
>
frame_number
)
{
// if the requested position is behind out actual position,
// we just need to read the remaining amount of frames until we are there.
for
(;
frame_number
<
f
;
frame_number
++
)
{
// un-increment framenumber grabbing failed
if
(
!
xine_get_next_video_frame
(
vo_port
,
&
xine_frame
))
{
frame_number
--
;
break
;
}
else
{
xine_free_video_frame
(
vo_port
,
&
xine_frame
);
}
}
}
else
// f < frame_number
{
#ifndef NDEBUG
fprintf
(
stderr
,
"failed
\n
"
);
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ... failed
\n
"
);
#endif
return
0
;
// otherwise we need to reset the stream and
// start reading frames from the beginning.
// reset stream, should also work with non-seekable input
xine_play
(
stream
,
0
,
0
);
// read frames until we are at the requested frame
for
(
frame_number
=
0
;
frame_number
<
f
;
frame_number
++
)
{
// un-increment last framenumber if grabbing failed
if
(
!
xine_get_next_video_frame
(
vo_port
,
&
xine_frame
))
{
frame_number
--
;
break
;
}
else
{
xine_free_video_frame
(
vo_port
,
&
xine_frame
);
}
}
}
return
f
==
frame_number
;
}
else
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ... end
\n
"
);
#endif
return
icvOldSeekFrameAVI_XINE
(
capture
,
f
);
}
}
static
int
icvSeekTimeAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
int
t
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekTimeAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->vo_port"
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekTimeAVI_XINE ... start
\n
"
);
#endif
// not needed tnx to asserts...
// we need a valid capture context and it's stream to seek through
// if ( !capture || !capture->stream ) return 0;
if
(
capture
->
seekable
)
bool
seekFrame
(
int
f
)
{
/// use xinelib's seek functionality
if
(
xine_play
(
capture
->
stream
,
0
,
t
)
)
CV_Assert
(
xine
,
vo_port
,
stream
);
if
(
seekable
)
{
capture
->
frame_number
=
(
int
)
(
(
float
)
t
*
capture
->
frame_rate
/
1000
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ... end
\n
"
);
#endif
return
1
;
int
new_time
=
(
int
)((
f
+
1
)
*
(
float
)
frame_duration
);
if
(
xine_play
(
stream
,
0
,
new_time
))
{
frame_number
=
f
;
return
true
;
}
}
else
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
return
oldSeekFrame
(
f
);
}
return
false
;
}
else
{
int
new_frame
=
(
int
)
(
(
float
)
t
*
capture
->
frame_rate
/
1000
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekFrameAVI_XINE ....end
\n
"
);
#endif
return
icvOldSeekFrameAVI_XINE
(
capture
,
new_frame
);
}
}
static
int
icvSeekRatioAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
double
ratio
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekRatioAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )"
,
"illegal capture->vo_port"
);
// not needed tnx to asserts...
// we need a valid capture context and it's stream to seek through
// if ( !capture || !capture->stream ) return 0;
/// ratio must be [0..1]
if
(
ratio
>
1
||
ratio
<
0
)
return
0
;
if
(
capture
->
seekable
)
bool
seekTime
(
int
t
)
{
// TODO: FIX IT, DOESN'T WORK PROPERLY, YET...!
int
pos_t
,
pos_l
,
length
;
xine_get_pos_length
(
capture
->
stream
,
&
pos_l
,
&
pos_t
,
&
length
);
fprintf
(
stderr
,
"ratio on GetProperty(): %d
\n
"
,
pos_l
);
/// use xinelib's seek functionality
if
(
xine_play
(
capture
->
stream
,
(
int
)(
ratio
*
(
float
)
length
),
0
)
)
CV_Assert
(
xine
,
vo_port
,
stream
);
if
(
seekable
)
{
capture
->
frame_number
=
(
int
)
(
ratio
*
length
/
capture
->
frame_duration
);
if
(
xine_play
(
stream
,
0
,
t
))
{
frame_number
=
(
int
)((
double
)
t
*
frame_rate
/
1000
);
return
true
;
}
}
else
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekRatioAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
int
new_frame
=
(
int
)((
double
)
t
*
frame_rate
/
1000
);
return
oldSeekFrame
(
new_frame
);
}
}
else
{
/// TODO: fill it !
fprintf
(
stderr
,
"icvSeekRatioAVI_XINE(): Seek not supported by stream !
\n
"
);
fprintf
(
stderr
,
"icvSeekRatioAVI_XINE(): (seek in stream with NO seek support NOT implemented...yet!)
\n
"
);
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekRatioAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
return
false
;
}
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSeekRatioAVI_XINE ... end!
\n
"
);
#endif
return
1
;
}
static
double
icvGetPropertyAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
int
property_id
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvGetPropertyAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->vo_port"
);
OPENCV_ASSERT
(
capture
->
xine
,
"icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->xine"
);
OPENCV_ASSERT
(
capture
->
bgr_frame
,
"icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->bgr_frame"
);
// not needed tnx to asserts...
// we need a valid capture context and it's stream to seek through
// if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0
int
pos_t
,
pos_l
,
length
;
xine_get_pos_length
(
capture
->
stream
,
&
pos_l
,
&
pos_t
,
&
length
);
fprintf
(
stderr
,
"ratio on GetProperty(): %i
\n
"
,
pos_l
);
switch
(
property_id
)
bool
seekRatio
(
double
ratio
)
{
/// return actual position in msec
case
CV_CAP_PROP_POS_MSEC
:
if
(
!
capture
->
seekable
)
{
fprintf
(
stderr
,
"(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_MSEC:
\n
"
);
fprintf
(
stderr
,
" Stream is NOT seekable, so position info may NOT be valid !!
\n
"
);
}
return
pos_t
;
/// return actual frame number
case
CV_CAP_PROP_POS_FRAMES
:
/// we insist the capture->frame_number to be remain updated !!!!
return
capture
->
frame_number
;
/// return actual position ratio in the range [0..1] depending on
/// the total length of the stream and the actual position
case
CV_CAP_PROP_POS_AVI_RATIO
:
if
(
!
capture
->
seekable
)
{
fprintf
(
stderr
,
"(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_AVI_RATIO:
\n
"
);
fprintf
(
stderr
,
" Stream is NOT seekable, so ratio info may NOT be valid !!
\n
"
);
}
if
(
length
==
0
)
break
;
else
return
pos_l
/
65535
;
/// return width of image source
case
CV_CAP_PROP_FRAME_WIDTH
:
return
capture
->
size
.
width
;
/// return height of image source
case
CV_CAP_PROP_FRAME_HEIGHT
:
return
capture
->
size
.
height
;
/// return framerate of stream
case
CV_CAP_PROP_FPS
:
if
(
!
capture
->
seekable
)
CV_Assert
(
xine
,
vo_port
,
stream
);
if
(
ratio
>
1
||
ratio
<
0
)
return
false
;
if
(
seekable
)
{
// TODO: FIX IT, DOESN'T WORK PROPERLY, YET...!
int
pos_t
,
pos_l
,
length
;
bool
res
=
(
bool
)
xine_get_pos_length
(
stream
,
&
pos_l
,
&
pos_t
,
&
length
);
if
(
res
&&
xine_play
(
stream
,
(
int
)(
ratio
*
(
double
)
length
),
0
))
{
f
printf
(
stderr
,
"(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_FPS:
\n
"
);
fprintf
(
stderr
,
" Stream is NOT seekable, so FPS info may NOT be valid !!
\n
"
)
;
f
rame_number
=
(
int
)(
ratio
*
length
/
frame_duration
);
return
true
;
}
return
capture
->
frame_rate
;
/// return four-character-code (FOURCC) of source's codec
case
CV_CAP_PROP_FOURCC
:
return
(
double
)
xine_get_stream_info
(
capture
->
stream
,
XINE_STREAM_INFO_VIDEO_FOURCC
);
}
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvGetPropertyAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
}
static
int
icvSetPropertyAVI_XINE
(
CvCaptureAVI_XINE
*
capture
,
int
property_id
,
double
value
)
{
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSetPropertyAVI_XINE ... start
\n
"
);
#endif
OPENCV_ASSERT
(
capture
,
"icvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int, double )"
,
"illegal capture"
);
OPENCV_ASSERT
(
capture
->
stream
,
"icvGetPropericvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )"
,
"illegal capture->stream"
);
OPENCV_ASSERT
(
capture
->
vo_port
,
"icvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int, double )"
,
"illegal capture->vo_port"
);
// not needed tnx to asserts...
// we need a valid capture context and it's stream to seek through
// if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSetPropertyAVI_XINE: seeking to value %f ... "
,
value
);
#endif
switch
(
property_id
)
{
/// set (seek to) position in msec
case
CV_CAP_PROP_POS_MSEC
:
return
icvSeekTimeAVI_XINE
(
capture
,
(
int
)
value
);
/// set (seek to) frame number
case
CV_CAP_PROP_POS_FRAMES
:
return
icvSeekFrameAVI_XINE
(
capture
,
(
int
)
value
);
/// set (seek to) position ratio in the range [0..1] depending on
/// the total length of the stream and the actual position
case
CV_CAP_PROP_POS_AVI_RATIO
:
return
icvSeekRatioAVI_XINE
(
capture
,
value
);
default:
#ifndef NDEBUG
fprintf
(
stderr
,
"(DEBUG) icvSetPropertyAVI_XINE ... failed!
\n
"
);
#endif
return
0
;
}
return
false
;
}
}
static
CvCaptureAVI_XINE
*
icvCaptureFromFile_XINE
(
const
char
*
filename
)
{
// construct capture struct
CvCaptureAVI_XINE
*
capture
=
(
CvCaptureAVI_XINE
*
)
cvAlloc
(
sizeof
(
CvCaptureAVI_XINE
)
);
memset
(
capture
,
0
,
sizeof
(
CvCaptureAVI_XINE
)
);
// initialize XINE
if
(
!
icvOpenAVI_XINE
(
capture
,
filename
)
)
return
0
;
OPENCV_ASSERT
(
capture
,
"cvCaptureFromFile_XINE( const char * )"
,
"couldn't create capture"
);
return
capture
;
}
class
CvCaptureAVI_XINE_CPP
:
public
CvCapture
{
public
:
CvCaptureAVI_XINE_CPP
()
{
captureXINE
=
0
;
}
virtual
~
CvCaptureAVI_XINE_CPP
()
{
close
();
}
virtual
bool
open
(
const
char
*
filename
);
virtual
void
close
();
virtual
double
getProperty
(
int
)
const
CV_OVERRIDE
;
virtual
bool
setProperty
(
int
,
double
)
CV_OVERRIDE
;
virtual
bool
grabFrame
()
CV_OVERRIDE
;
virtual
IplImage
*
retrieveFrame
(
int
)
CV_OVERRIDE
;
protected
:
CvCaptureAVI_XINE
*
captureXINE
;
};
bool
CvCaptureAVI_XINE_CPP
::
open
(
const
char
*
filename
)
{
close
();
captureXINE
=
icvCaptureFromFile_XINE
(
filename
);
return
captureXINE
!=
0
;
}
void
CvCaptureAVI_XINE_CPP
::
close
()
{
if
(
captureXINE
)
{
icvCloseAVI_XINE
(
captureXINE
);
cvFree
(
&
captureXINE
);
}
}
bool
CvCaptureAVI_XINE_CPP
::
grabFrame
()
{
return
captureXINE
?
icvGrabFrameAVI_XINE
(
captureXINE
)
!=
0
:
false
;
}
IplImage
*
CvCaptureAVI_XINE_CPP
::
retrieveFrame
(
int
)
Ptr
<
IVideoCapture
>
cv
::
createXINECapture
(
const
char
*
filename
)
{
return
captureXINE
?
(
IplImage
*
)
icvRetrieveFrameAVI_XINE
(
captureXINE
,
0
)
:
0
;
Ptr
<
XINECapture
>
res
=
makePtr
<
XINECapture
>
();
if
(
res
&&
res
->
open
(
filename
))
return
res
;
return
Ptr
<
IVideoCapture
>
();
}
double
CvCaptureAVI_XINE_CPP
::
getProperty
(
int
propId
)
const
{
return
captureXINE
?
icvGetPropertyAVI_XINE
(
captureXINE
,
propId
)
:
0
;
}
bool
CvCaptureAVI_XINE_CPP
::
setProperty
(
int
propId
,
double
value
)
{
return
captureXINE
?
icvSetPropertyAVI_XINE
(
captureXINE
,
propId
,
value
)
!=
0
:
false
;
}
CvCapture
*
cvCreateFileCapture_XINE
(
const
char
*
filename
)
{
CvCaptureAVI_XINE_CPP
*
capture
=
new
CvCaptureAVI_XINE_CPP
;
if
(
capture
->
open
(
filename
))
return
capture
;
delete
capture
;
return
0
;
}
#undef NDEBUG
modules/videoio/src/precomp.hpp
View file @
9615f8c9
...
...
@@ -133,8 +133,6 @@ CvCapture* cvCreateCameraCapture_Aravis( int index );
CvCapture
*
cvCreateFileCapture_Images
(
const
char
*
filename
);
CvVideoWriter
*
cvCreateVideoWriter_Images
(
const
char
*
filename
);
CvCapture
*
cvCreateFileCapture_XINE
(
const
char
*
filename
);
#define CV_CAP_GSTREAMER_1394 0
#define CV_CAP_GSTREAMER_V4L 1
...
...
@@ -195,6 +193,8 @@ namespace cv
Ptr
<
IVideoCapture
>
createGPhoto2Capture
(
int
index
);
Ptr
<
IVideoCapture
>
createGPhoto2Capture
(
const
String
&
deviceName
);
Ptr
<
IVideoCapture
>
createXINECapture
(
const
char
*
filename
);
}
#endif
/* __VIDEOIO_H_ */
modules/videoio/test/test_video_io.cpp
View file @
9615f8c9
...
...
@@ -131,7 +131,7 @@ public:
return
;
}
if
(
ext
!=
"wmv"
)
if
(
ext
!=
"wmv"
&&
ext
!=
"h264"
&&
ext
!=
"h265"
)
{
SCOPED_TRACE
(
"progressive seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
...
...
@@ -141,7 +141,7 @@ public:
}
}
if
(
ext
!=
"mpg"
&&
ext
!=
"wmv"
)
if
(
ext
!=
"mpg"
&&
ext
!=
"wmv"
&&
ext
!=
"h264"
&&
ext
!=
"h265"
)
{
SCOPED_TRACE
(
"random seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
...
...
@@ -334,6 +334,11 @@ int backend_params[] = {
#ifdef HAVE_FFMPEG
CAP_FFMPEG
,
#endif
#ifdef HAVE_XINE
CAP_XINE
,
#endif
CAP_OPENCV_MJPEG
// CAP_INTEL_MFX
};
...
...
@@ -345,6 +350,8 @@ string bunny_params[] = {
string
(
"mp4"
),
string
(
"mpg"
),
string
(
"avi"
),
string
(
"h264"
),
string
(
"h265"
),
#endif
string
(
"mjpg.avi"
)
};
...
...
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