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
df8f6187
Commit
df8f6187
authored
Feb 14, 2018
by
Alexander Nesterov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added avi-container with tests
parent
cff79609
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
302 additions
and
16 deletions
+302
-16
CMakeLists.txt
modules/videoio/CMakeLists.txt
+1
-1
container_avi.private.hpp
...videoio/include/opencv2/videoio/container_avi.private.hpp
+191
-0
cap_mjpeg_decoder.cpp
modules/videoio/src/cap_mjpeg_decoder.cpp
+0
-0
cap_mjpeg_encoder.cpp
modules/videoio/src/cap_mjpeg_encoder.cpp
+0
-0
container_avi.cpp
modules/videoio/src/container_avi.cpp
+0
-0
test_container_avi.cpp
modules/videoio/test/test_container_avi.cpp
+87
-0
test_precomp.hpp
modules/videoio/test/test_precomp.hpp
+14
-0
test_video_io.cpp
modules/videoio/test/test_video_io.cpp
+9
-15
No files found.
modules/videoio/CMakeLists.txt
View file @
df8f6187
...
...
@@ -19,12 +19,12 @@ endif()
set
(
videoio_hdrs
${
CMAKE_CURRENT_LIST_DIR
}
/src/precomp.hpp
)
set
(
videoio_srcs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap.cpp
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_images.cpp
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mjpeg_encoder.cpp
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mjpeg_decoder.cpp
${
CMAKE_CURRENT_LIST_DIR
}
/src/container_avi.cpp
)
file
(
GLOB videoio_ext_hdrs
...
...
modules/videoio/include/opencv2/videoio/container_avi.private.hpp
0 → 100644
View file @
df8f6187
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef CONTAINER_AVI_HPP
#define CONTAINER_AVI_HPP
#ifndef __OPENCV_BUILD
# error this is a private header which should not be used from outside of the OpenCV library
#endif
#include "opencv2/core/cvdef.h"
#include "opencv2/videoio/videoio_c.h"
#include <deque>
namespace
cv
{
/*
AVI struct:
RIFF ('AVI '
LIST ('hdrl'
'avih'(<Main AVI Header>)
LIST ('strl'
'strh'(<Stream header>)
'strf'(<Stream format>)
[ 'strd'(<Additional header data>) ]
[ 'strn'(<Stream name>) ]
[ 'indx'(<Odml index data>) ]
...
)
[LIST ('strl' ...)]
[LIST ('strl' ...)]
...
[LIST ('odml'
'dmlh'(<ODML header data>)
...
)
]
...
)
[LIST ('INFO' ...)]
[JUNK]
LIST ('movi'
{{xxdb|xxdc|xxpc|xxwb}(<Data>) | LIST ('rec '
{xxdb|xxdc|xxpc|xxwb}(<Data>)
{xxdb|xxdc|xxpc|xxwb}(<Data>)
...
)
...
}
...
)
['idx1' (<AVI Index>) ]
)
{xxdb|xxdc|xxpc|xxwb}
xx - stream number: 00, 01, 02, ...
db - uncompressed video frame
dc - commpressed video frame
pc - palette change
wb - audio frame
JUNK section may pad any data section and must be ignored
*/
typedef
std
::
deque
<
std
::
pair
<
uint64_t
,
uint32_t
>
>
frame_list
;
typedef
frame_list
::
iterator
frame_iterator
;
struct
RiffChunk
;
struct
RiffList
;
class
VideoInputStream
;
enum
Codecs
{
MJPEG
};
//Represents single MJPEG video stream within single AVI/AVIX entry
//Multiple video streams within single AVI/AVIX entry are not supported
//ODML index is not supported
class
CV_EXPORTS
AVIReadContainer
{
public
:
AVIReadContainer
();
void
initStream
(
const
String
&
filename
);
void
initStream
(
Ptr
<
VideoInputStream
>
m_file_stream_
);
void
close
();
//stores founded frames in m_frame_list which can be accessed via getFrames
bool
parseAvi
(
Codecs
codec_
)
{
return
parseAviWithFrameList
(
m_frame_list
,
codec_
);
}
//stores founded frames in in_frame_list. getFrames() would return empty list
bool
parseAvi
(
frame_list
&
in_frame_list
,
Codecs
codec_
)
{
return
parseAviWithFrameList
(
in_frame_list
,
codec_
);
}
size_t
getFramesCount
()
{
return
m_frame_list
.
size
();
}
frame_list
&
getFrames
()
{
return
m_frame_list
;
}
unsigned
int
getWidth
()
{
return
m_width
;
}
unsigned
int
getHeight
()
{
return
m_height
;
}
double
getFps
()
{
return
m_fps
;
}
std
::
vector
<
char
>
readFrame
(
frame_iterator
it
);
bool
parseRiff
(
frame_list
&
m_mjpeg_frames
);
protected
:
bool
parseAviWithFrameList
(
frame_list
&
in_frame_list
,
Codecs
codec_
);
void
skipJunk
(
RiffChunk
&
chunk
);
void
skipJunk
(
RiffList
&
list
);
bool
parseHdrlList
(
Codecs
codec_
);
bool
parseIndex
(
unsigned
int
index_size
,
frame_list
&
in_frame_list
);
bool
parseMovi
(
frame_list
&
in_frame_list
)
{
//not implemented
in_frame_list
.
empty
();
return
true
;
}
bool
parseStrl
(
char
stream_id
,
Codecs
codec_
);
bool
parseInfo
()
{
//not implemented
return
true
;
}
void
printError
(
RiffList
&
list
,
unsigned
int
expected_fourcc
);
void
printError
(
RiffChunk
&
chunk
,
unsigned
int
expected_fourcc
);
Ptr
<
VideoInputStream
>
m_file_stream
;
unsigned
int
m_stream_id
;
unsigned
long
long
int
m_movi_start
;
unsigned
long
long
int
m_movi_end
;
frame_list
m_frame_list
;
unsigned
int
m_width
;
unsigned
int
m_height
;
double
m_fps
;
bool
m_is_indx_present
;
};
enum
{
COLORSPACE_GRAY
=
0
,
COLORSPACE_RGBA
=
1
,
COLORSPACE_BGR
=
2
,
COLORSPACE_YUV444P
=
3
};
enum
StreamType
{
db
,
dc
,
pc
,
wb
};
class
BitStream
;
// {xxdb|xxdc|xxpc|xxwb}
// xx - stream number: 00, 01, 02, ...
// db - uncompressed video frame
// dc - commpressed video frame
// pc - palette change
// wb - audio frame
class
CV_EXPORTS
AVIWriteContainer
{
public
:
AVIWriteContainer
();
~
AVIWriteContainer
();
bool
initContainer
(
const
String
&
filename
,
double
fps
,
Size
size
,
bool
iscolor
);
void
startWriteAVI
(
int
stream_count
);
void
writeStreamHeader
(
Codecs
codec_
);
void
startWriteChunk
(
int
fourcc
);
void
endWriteChunk
();
int
getAVIIndex
(
int
stream_number
,
StreamType
strm_type
);
void
writeIndex
(
int
stream_number
,
StreamType
strm_type
);
void
finishWriteAVI
();
bool
isOpenedStream
()
const
;
bool
isEmptyFrameOffset
()
const
{
return
frameOffset
.
empty
();
}
int
getWidth
()
const
{
return
width
;
}
int
getHeight
()
const
{
return
height
;
}
int
getChannels
()
const
{
return
channels
;
}
size_t
getMoviPointer
()
const
{
return
moviPointer
;
}
size_t
getStreamPos
()
const
;
void
pushFrameOffset
(
size_t
elem
)
{
frameOffset
.
push_back
(
elem
);
}
void
pushFrameSize
(
size_t
elem
)
{
frameSize
.
push_back
(
elem
);
}
bool
isEmptyFrameSize
()
const
{
return
frameSize
.
empty
();
}
size_t
atFrameSize
(
size_t
i
)
const
{
return
frameSize
[
i
];
}
size_t
countFrameSize
()
const
{
return
frameSize
.
size
();
}
void
jputStreamShort
(
int
val
);
void
putStreamBytes
(
const
uchar
*
buf
,
int
count
);
void
putStreamByte
(
int
val
);
void
jputStream
(
unsigned
currval
);
void
jflushStream
(
unsigned
currval
,
int
bitIdx
);
private
:
Ptr
<
BitStream
>
strm
;
int
outfps
;
int
width
,
height
,
channels
;
size_t
moviPointer
;
std
::
vector
<
size_t
>
frameOffset
,
frameSize
,
AVIChunkSizeIndex
,
frameNumIndexes
;
};
}
#endif //CONTAINER_AVI_HPP
modules/videoio/src/cap_mjpeg_decoder.cpp
View file @
df8f6187
This diff is collapsed.
Click to expand it.
modules/videoio/src/cap_mjpeg_encoder.cpp
View file @
df8f6187
This diff is collapsed.
Click to expand it.
modules/videoio/src/container_avi.cpp
0 → 100644
View file @
df8f6187
This diff is collapsed.
Click to expand it.
modules/videoio/test/test_container_avi.cpp
0 → 100644
View file @
df8f6187
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "opencv2/videoio/container_avi.private.hpp"
#include <cstdio>
using
namespace
cv
;
namespace
opencv_test
{
TEST
(
videoio_avi
,
good_MJPG
)
{
String
filename
=
BunnyParameters
::
getFilename
(
".mjpg.avi"
);
AVIReadContainer
in
;
in
.
initStream
(
filename
);
frame_list
frames
;
ASSERT_TRUE
(
in
.
parseRiff
(
frames
));
EXPECT_EQ
(
frames
.
size
(),
static_cast
<
unsigned
>
(
BunnyParameters
::
getCount
()));
EXPECT_EQ
(
in
.
getWidth
(),
static_cast
<
unsigned
>
(
BunnyParameters
::
getWidth
()));
EXPECT_EQ
(
in
.
getHeight
(),
static_cast
<
unsigned
>
(
BunnyParameters
::
getHeight
()));
EXPECT_EQ
(
in
.
getFps
(),
static_cast
<
unsigned
>
(
BunnyParameters
::
getFps
()));
}
TEST
(
videoio_avi
,
bad_MJPG
)
{
String
filename
=
BunnyParameters
::
getFilename
(
".avi"
);
AVIReadContainer
in
;
in
.
initStream
(
filename
);
frame_list
frames
;
EXPECT_FALSE
(
in
.
parseRiff
(
frames
));
EXPECT_EQ
(
frames
.
size
(),
static_cast
<
unsigned
>
(
0
));
}
TEST
(
videoio_avi
,
basic
)
{
const
String
filename
=
cv
::
tempfile
(
"test.avi"
);
const
double
fps
=
100
;
const
Size
sz
(
800
,
600
);
const
size_t
count
=
10
;
const
uchar
data
[
count
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
0xA
};
const
Codecs
codec
=
MJPEG
;
{
AVIWriteContainer
out
;
ASSERT_TRUE
(
out
.
initContainer
(
filename
,
fps
,
sz
,
true
));
ASSERT_TRUE
(
out
.
isOpenedStream
());
EXPECT_EQ
(
out
.
getWidth
(),
sz
.
width
);
EXPECT_EQ
(
out
.
getHeight
(),
sz
.
height
);
EXPECT_EQ
(
out
.
getChannels
(),
3
);
out
.
startWriteAVI
(
1
);
{
out
.
writeStreamHeader
(
codec
);
// starts LIST chunk
size_t
chunkPointer
=
out
.
getStreamPos
();
int
avi_index
=
out
.
getAVIIndex
(
0
,
dc
);
{
out
.
startWriteChunk
(
avi_index
);
out
.
putStreamBytes
(
data
,
count
);
size_t
tempChunkPointer
=
out
.
getStreamPos
();
size_t
moviPointer
=
out
.
getMoviPointer
();
out
.
pushFrameOffset
(
chunkPointer
-
moviPointer
);
out
.
pushFrameSize
(
tempChunkPointer
-
chunkPointer
-
8
);
out
.
endWriteChunk
();
}
out
.
endWriteChunk
();
// ends LIST chunk
}
out
.
writeIndex
(
0
,
dc
);
out
.
finishWriteAVI
();
}
{
AVIReadContainer
in
;
in
.
initStream
(
filename
);
frame_list
frames
;
ASSERT_TRUE
(
in
.
parseRiff
(
frames
));
EXPECT_EQ
(
in
.
getFps
(),
fps
);
EXPECT_EQ
(
in
.
getWidth
(),
static_cast
<
unsigned
>
(
sz
.
width
));
EXPECT_EQ
(
in
.
getHeight
(),
static_cast
<
unsigned
>
(
sz
.
height
));
ASSERT_EQ
(
frames
.
size
(),
static_cast
<
unsigned
>
(
1
));
std
::
vector
<
char
>
actual
=
in
.
readFrame
(
frames
.
begin
());
ASSERT_EQ
(
actual
.
size
(),
count
);
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
EXPECT_EQ
(
actual
.
at
(
i
),
data
[
i
])
<<
"at index "
<<
i
;
}
remove
(
filename
.
c_str
());
}
}
modules/videoio/test/test_precomp.hpp
View file @
df8f6187
...
...
@@ -41,4 +41,18 @@ inline void generateFrame(int i, int FRAME_COUNT, cv::Mat & frame)
#endif
}
class
BunnyParameters
{
public
:
inline
static
int
getWidth
()
{
return
672
;
};
inline
static
int
getHeight
()
{
return
384
;
};
inline
static
int
getFps
()
{
return
24
;
};
inline
static
double
getTime
()
{
return
5.21
;
};
inline
static
int
getCount
()
{
return
cvRound
(
getFps
()
*
getTime
());
};
inline
static
std
::
string
getFilename
(
const
std
::
string
&
ext
)
{
return
cvtest
::
TS
::
ptr
()
->
get_data_path
()
+
"video/big_buck_bunny"
+
ext
;
}
};
#endif
modules/videoio/test/test_video_io.cpp
View file @
df8f6187
...
...
@@ -151,13 +151,13 @@ typedef tuple<string, int> Backend_Type_Params;
class
Videoio_Bunny
:
public
Videoio_Test_Base
,
public
testing
::
TestWithParam
<
Backend_Type_Params
>
{
BunnyParameters
bunny_param
;
public
:
Videoio_Bunny
()
{
ext
=
get
<
0
>
(
GetParam
());
apiPref
=
get
<
1
>
(
GetParam
());
video_file
=
cvtest
::
TS
::
ptr
()
->
get_data_path
()
+
"video/big_buck_bunny."
+
ext
;
video_file
=
BunnyParameters
::
getFilename
(
String
(
"."
)
+
ext
);
}
void
doFrameCountTest
()
{
...
...
@@ -181,18 +181,12 @@ public:
return
;
}
const
int
width_gt
=
672
;
const
int
height_gt
=
384
;
const
int
fps_gt
=
24
;
const
double
time_gt
=
5.21
;
const
int
count_gt
=
cvRound
(
fps_gt
*
time_gt
);
// 5.21 sec * 24 fps
EXPECT_EQ
(
width_gt
,
cap
.
get
(
CAP_PROP_FRAME_WIDTH
));
EXPECT_EQ
(
height_gt
,
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
));
EXPECT_EQ
(
bunny_param
.
getWidth
()
,
cap
.
get
(
CAP_PROP_FRAME_WIDTH
));
EXPECT_EQ
(
bunny_param
.
getHeight
(),
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
));
double
fps_prop
=
cap
.
get
(
CAP_PROP_FPS
);
if
(
fps_prop
>
0
)
EXPECT_NEAR
(
fps_prop
,
fps_gt
,
1
);
EXPECT_NEAR
(
fps_prop
,
bunny_param
.
getFps
()
,
1
);
else
std
::
cout
<<
"FPS is not available. SKIP check."
<<
std
::
endl
;
...
...
@@ -204,7 +198,7 @@ public:
{
if
(
count_prop
>
0
)
{
EXPECT_EQ
(
count_gt
,
count_prop
);
EXPECT_EQ
(
bunny_param
.
getCount
()
,
count_prop
);
}
}
...
...
@@ -215,13 +209,13 @@ public:
cap
>>
frame
;
if
(
frame
.
empty
())
break
;
EXPECT_EQ
(
width_gt
,
frame
.
cols
);
EXPECT_EQ
(
height_gt
,
frame
.
rows
);
EXPECT_EQ
(
bunny_param
.
getWidth
()
,
frame
.
cols
);
EXPECT_EQ
(
bunny_param
.
getHeight
()
,
frame
.
rows
);
count_actual
+=
1
;
}
if
(
count_prop
>
0
)
{
EXPECT_NEAR
(
count_gt
,
count_actual
,
1
);
EXPECT_NEAR
(
bunny_param
.
getCount
()
,
count_actual
,
1
);
}
else
std
::
cout
<<
"Frames counter is not available. Actual frames: "
<<
count_actual
<<
". SKIP check."
<<
std
::
endl
;
...
...
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