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
1f3043f6
Commit
1f3043f6
authored
Jun 03, 2015
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
videoio: VideoWriter H264/.mp4 support via ffmpeg/libav
parent
8ad6ba82
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
128 additions
and
30 deletions
+128
-30
cap_ffmpeg_impl.hpp
modules/videoio/src/cap_ffmpeg_impl.hpp
+63
-0
test_ffmpeg.cpp
modules/videoio/test/test_ffmpeg.cpp
+65
-30
No files found.
modules/videoio/src/cap_ffmpeg_impl.hpp
View file @
1f3043f6
...
...
@@ -1540,6 +1540,30 @@ void CvVideoWriter_FFMPEG::close()
init
();
}
#define CV_PRINTABLE_CHAR(ch) ((ch) < 32 ? '?' : (ch))
#define CV_TAG_TO_PRINTABLE_CHAR4(tag) CV_PRINTABLE_CHAR((tag) & 255), CV_PRINTABLE_CHAR(((tag) >> 8) & 255), CV_PRINTABLE_CHAR(((tag) >> 16) & 255), CV_PRINTABLE_CHAR(((tag) >> 24) & 255)
static
inline
bool
cv_ff_codec_tag_match
(
const
AVCodecTag
*
tags
,
enum
AVCodecID
id
,
unsigned
int
tag
)
{
while
(
tags
->
id
!=
AV_CODEC_ID_NONE
)
{
if
(
tags
->
id
==
id
&&
tags
->
tag
==
tag
)
return
true
;
tags
++
;
}
return
false
;
}
static
inline
bool
cv_ff_codec_tag_list_match
(
const
AVCodecTag
*
const
*
tags
,
enum
AVCodecID
id
,
unsigned
int
tag
)
{
int
i
;
for
(
i
=
0
;
tags
&&
tags
[
i
];
i
++
)
{
bool
res
=
cv_ff_codec_tag_match
(
tags
[
i
],
id
,
tag
);
if
(
res
)
return
res
;
}
return
false
;
}
/// Create a video writer object that uses FFMPEG
bool
CvVideoWriter_FFMPEG
::
open
(
const
char
*
filename
,
int
fourcc
,
double
fps
,
int
width
,
int
height
,
bool
is_color
)
...
...
@@ -1587,6 +1611,45 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
if
(
(
codec_id
=
codec_get_bmp_id
(
fourcc
))
==
CV_CODEC
(
CODEC_ID_NONE
)
)
return
false
;
#elif LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
// APIchnages:
// 2012-01-31 - dd6d3b0 - lavf 54.01.0
// Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags().
if
(
(
codec_id
=
av_codec_get_id
(
fmt
->
codec_tag
,
fourcc
))
==
CV_CODEC
(
CODEC_ID_NONE
)
)
{
const
struct
AVCodecTag
*
fallback_tags
[]
=
{
avformat_get_riff_video_tags
(),
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 25, 100)
// APIchanges: ffmpeg only
// 2014-01-19 - 1a193c4 - lavf 55.25.100 - avformat.h
// Add avformat_get_mov_video_tags() and avformat_get_mov_audio_tags().
// TODO ffmpeg only, need to skip libav: avformat_get_mov_video_tags(),
#endif
codec_bmp_tags
,
NULL
};
if
(
(
codec_id
=
av_codec_get_id
(
fallback_tags
,
fourcc
))
==
CV_CODEC
(
CODEC_ID_NONE
)
)
{
fflush
(
stdout
);
fprintf
(
stderr
,
"OpenCV: FFMPEG: tag 0x%08x/'%c%c%c%c' is not found (format '%s / %s')'
\n
"
,
fourcc
,
CV_TAG_TO_PRINTABLE_CHAR4
(
fourcc
),
fmt
->
name
,
fmt
->
long_name
);
return
false
;
}
}
// validate tag
if
(
cv_ff_codec_tag_list_match
(
fmt
->
codec_tag
,
codec_id
,
fourcc
)
==
false
)
{
fflush
(
stdout
);
fprintf
(
stderr
,
"OpenCV: FFMPEG: tag 0x%08x/'%c%c%c%c' is not supported with codec id %d and format '%s / %s'
\n
"
,
fourcc
,
CV_TAG_TO_PRINTABLE_CHAR4
(
fourcc
),
codec_id
,
fmt
->
name
,
fmt
->
long_name
);
int
supported_tag
;
if
(
(
supported_tag
=
av_codec_get_tag
(
fmt
->
codec_tag
,
codec_id
))
!=
0
)
{
fprintf
(
stderr
,
"OpenCV: FFMPEG: fallback to use tag 0x%08x/'%c%c%c%c'
\n
"
,
supported_tag
,
CV_TAG_TO_PRINTABLE_CHAR4
(
supported_tag
));
fourcc
=
supported_tag
;
}
}
#else
const
struct
AVCodecTag
*
tags
[]
=
{
codec_bmp_tags
,
NULL
};
if
(
(
codec_id
=
av_codec_get_id
(
tags
,
fourcc
))
==
CV_CODEC
(
CODEC_ID_NONE
)
)
...
...
modules/videoio/test/test_ffmpeg.cpp
View file @
1f3043f6
...
...
@@ -49,8 +49,28 @@ using namespace cv;
using
namespace
std
;
static
const
char
*
AVI_EXT
=
".avi"
;
static
const
char
*
MP4_EXT
=
".mp4"
;
class
CV_FFmpegWriteBigVideoTest
:
public
cvtest
::
BaseTest
{
struct
TestFormatEntry
{
int
tag
;
const
char
*
ext
;
bool
required
;
};
static
long
int
getFileSize
(
string
filename
)
{
FILE
*
p_file
=
NULL
;
p_file
=
fopen
(
filename
.
c_str
(),
"rb"
);
if
(
p_file
==
NULL
)
return
-
1
;
fseek
(
p_file
,
0
,
SEEK_END
);
long
int
size
=
ftell
(
p_file
);
fclose
(
p_file
);
return
size
;
}
public
:
void
run
(
int
)
{
...
...
@@ -59,36 +79,35 @@ public:
const
double
fps0
=
15
;
const
double
time_sec
=
1
;
const
int
tags
[]
=
{
0
,
//VideoWriter::fourcc('D', 'I', 'V', '3'),
//VideoWriter::fourcc('D', 'I', 'V', 'X'),
VideoWriter
::
fourcc
(
'D'
,
'X'
,
'5'
,
'0'
),
VideoWriter
::
fourcc
(
'F'
,
'L'
,
'V'
,
'1'
),
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'1'
),
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'3'
),
VideoWriter
::
fourcc
(
'I'
,
'4'
,
'2'
,
'0'
),
//VideoWriter::fourcc('j', 'p', 'e', 'g'),
VideoWriter
::
fourcc
(
'M'
,
'J'
,
'P'
,
'G'
),
VideoWriter
::
fourcc
(
'm'
,
'p'
,
'4'
,
'v'
),
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
),
//VideoWriter::fourcc('W', 'M', 'V', '1'),
//VideoWriter::fourcc('W', 'M', 'V', '2'),
VideoWriter
::
fourcc
(
'X'
,
'V'
,
'I'
,
'D'
),
//VideoWriter::fourcc('Y', 'U', 'Y', '2'),
const
TestFormatEntry
entries
[]
=
{
{
0
,
AVI_EXT
,
true
},
//{VideoWriter::fourcc('D', 'I', 'V', '3'), AVI_EXT, true},
//{VideoWriter::fourcc('D', 'I', 'V', 'X'), AVI_EXT, true},
{
VideoWriter
::
fourcc
(
'D'
,
'X'
,
'5'
,
'0'
),
AVI_EXT
,
true
},
{
VideoWriter
::
fourcc
(
'F'
,
'L'
,
'V'
,
'1'
),
AVI_EXT
,
true
},
{
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'1'
),
AVI_EXT
,
true
},
{
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'3'
),
AVI_EXT
,
true
},
{
VideoWriter
::
fourcc
(
'I'
,
'4'
,
'2'
,
'0'
),
AVI_EXT
,
true
},
//{VideoWriter::fourcc('j', 'p', 'e', 'g'), AVI_EXT, true},
{
VideoWriter
::
fourcc
(
'M'
,
'J'
,
'P'
,
'G'
),
AVI_EXT
,
true
},
{
VideoWriter
::
fourcc
(
'm'
,
'p'
,
'4'
,
'v'
),
AVI_EXT
,
true
},
{
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
),
AVI_EXT
,
true
},
//{VideoWriter::fourcc('W', 'M', 'V', '1'), AVI_EXT, true},
//{VideoWriter::fourcc('W', 'M', 'V', '2'), AVI_EXT, true},
{
VideoWriter
::
fourcc
(
'X'
,
'V'
,
'I'
,
'D'
),
AVI_EXT
,
true
},
//{VideoWriter::fourcc('Y', 'U', 'Y', '2'), AVI_EXT, true},
{
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
),
MP4_EXT
,
false
}
};
const
size_t
n
=
sizeof
(
tags
)
/
sizeof
(
tags
[
0
]);
bool
created
=
false
;
const
size_t
n
=
sizeof
(
entries
)
/
sizeof
(
entries
[
0
]);
for
(
size_t
j
=
0
;
j
<
n
;
++
j
)
{
int
tag
=
tags
[
j
]
;
stringstream
s
;
s
<<
tag
;
int
tag
=
entries
[
j
].
tag
;
const
char
*
ext
=
entries
[
j
].
ext
;
s
tring
s
=
cv
::
format
(
"%08x%s"
,
tag
,
ext
)
;
const
string
filename
=
tempfile
(
(
s
.
str
()
+
".avi"
)
.
c_str
());
const
string
filename
=
tempfile
(
s
.
c_str
());
try
{
...
...
@@ -113,11 +132,12 @@ public:
if
(
writer
.
isOpened
()
==
false
)
{
ts
->
printf
(
ts
->
LOG
,
"
\n\n
File name: %s
\n
"
,
filename
.
c_str
());
ts
->
printf
(
ts
->
LOG
,
"Codec id: %d Codec tag: %c%c%c%c
\n
"
,
j
,
fprintf
(
stderr
,
"
\n\n
File name: %s
\n
"
,
filename
.
c_str
());
fprintf
(
stderr
,
"Codec id: %d Codec tag: %c%c%c%c
\n
"
,
(
int
)
j
,
tag
&
255
,
(
tag
>>
8
)
&
255
,
(
tag
>>
16
)
&
255
,
(
tag
>>
24
)
&
255
);
ts
->
printf
(
ts
->
LOG
,
"Error: cannot create video file."
);
ts
->
set_failed_test_info
(
ts
->
FAIL_INVALID_OUTPUT
);
fprintf
(
stderr
,
"Error: cannot create video file."
);
if
(
entries
[
j
].
required
)
ts
->
set_failed_test_info
(
ts
->
FAIL_INVALID_OUTPUT
);
}
else
{
...
...
@@ -133,8 +153,23 @@ public:
}
writer
.
release
();
if
(
!
created
)
created
=
true
;
else
remove
(
filename
.
c_str
());
long
int
sz
=
getFileSize
(
filename
);
if
(
sz
<
0
)
{
fprintf
(
stderr
,
"ERROR: File name: %s was not created
\n
"
,
filename
.
c_str
());
if
(
entries
[
j
].
required
)
ts
->
set_failed_test_info
(
ts
->
FAIL_INVALID_OUTPUT
);
}
else
{
if
(
sz
<
8192
)
{
fprintf
(
stderr
,
"ERROR: File name: %s is very small (data write problems?)
\n
"
,
filename
.
c_str
());
if
(
entries
[
j
].
required
)
ts
->
set_failed_test_info
(
ts
->
FAIL_INVALID_OUTPUT
);
}
remove
(
filename
.
c_str
());
}
}
}
catch
(...)
...
...
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