Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
1f3043f6
O
Opencv
项目概览
Greenplum
/
Opencv
10 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
1f3043f6
编写于
6月 03, 2015
作者:
A
Alexander Alekhin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
videoio: VideoWriter H264/.mp4 support via ffmpeg/libav
上级
8ad6ba82
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
128 addition
and
30 deletion
+128
-30
modules/videoio/src/cap_ffmpeg_impl.hpp
modules/videoio/src/cap_ffmpeg_impl.hpp
+63
-0
modules/videoio/test/test_ffmpeg.cpp
modules/videoio/test/test_ffmpeg.cpp
+65
-30
未找到文件。
modules/videoio/src/cap_ffmpeg_impl.hpp
浏览文件 @
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
浏览文件 @
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
(...)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录