Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Obs Studio
提交
ca5a19cf
O
Obs Studio
项目概览
小白菜888
/
Obs Studio
通知
4
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Obs Studio
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ca5a19cf
编写于
3月 30, 2019
作者:
R
Richard Stanway
提交者:
jp9000
4月 19, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
obs-ffmpeg: Add logging of last error for passing to UI
上级
f52d8bdd
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
97 addition
and
39 deletion
+97
-39
plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
+9
-9
plugins/obs-ffmpeg/obs-ffmpeg-mux.c
plugins/obs-ffmpeg/obs-ffmpeg-mux.c
+15
-1
plugins/obs-ffmpeg/obs-ffmpeg-output.c
plugins/obs-ffmpeg/obs-ffmpeg-output.c
+73
-29
未找到文件。
plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c
浏览文件 @
ca5a19cf
...
...
@@ -268,7 +268,7 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream,
AVCodec
*
codec
;
if
(
!
desc
)
{
printf
(
"Couldn't find encoder '%s'
\n
"
,
name
);
fprintf
(
stderr
,
"Couldn't find encoder '%s'
\n
"
,
name
);
return
false
;
}
...
...
@@ -276,13 +276,13 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream,
codec
=
avcodec_find_encoder
(
desc
->
id
);
if
(
!
codec
)
{
printf
(
"Couldn't create encoder"
);
fprintf
(
stderr
,
"Couldn't create encoder"
);
return
false
;
}
*
stream
=
avformat_new_stream
(
ffm
->
output
,
codec
);
if
(
!*
stream
)
{
printf
(
"Couldn't create stream for encoder '%s'
\n
"
,
name
);
fprintf
(
stderr
,
"Couldn't create stream for encoder '%s'
\n
"
,
name
);
return
false
;
}
...
...
@@ -469,7 +469,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
ret
=
avio_open
(
&
ffm
->
output
->
pb
,
ffm
->
params
.
file
,
AVIO_FLAG_WRITE
);
if
(
ret
<
0
)
{
printf
(
"Couldn't open '%s', %s"
,
fprintf
(
stderr
,
"Couldn't open '%s', %s"
,
ffm
->
params
.
file
,
av_err2str
(
ret
));
return
FFM_ERROR
;
}
...
...
@@ -482,7 +482,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
AVDictionary
*
dict
=
NULL
;
if
((
ret
=
av_dict_parse_string
(
&
dict
,
ffm
->
params
.
muxer_settings
,
"="
,
" "
,
0
)))
{
printf
(
"Failed to parse muxer settings: %s
\n
%s"
,
fprintf
(
stderr
,
"Failed to parse muxer settings: %s
\n
%s"
,
av_err2str
(
ret
),
ffm
->
params
.
muxer_settings
);
av_dict_free
(
&
dict
);
...
...
@@ -501,7 +501,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
ret
=
avformat_write_header
(
ffm
->
output
,
&
dict
);
if
(
ret
<
0
)
{
printf
(
"Error opening '%s': %s"
,
fprintf
(
stderr
,
"Error opening '%s': %s"
,
ffm
->
params
.
file
,
av_err2str
(
ret
));
av_dict_free
(
&
dict
);
...
...
@@ -521,7 +521,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
output_format
=
av_guess_format
(
NULL
,
ffm
->
params
.
file
,
NULL
);
if
(
output_format
==
NULL
)
{
printf
(
"Couldn't find an appropriate muxer for '%s'
\n
"
,
fprintf
(
stderr
,
"Couldn't find an appropriate muxer for '%s'
\n
"
,
ffm
->
params
.
file
);
return
FFM_ERROR
;
}
...
...
@@ -529,7 +529,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
ret
=
avformat_alloc_output_context2
(
&
ffm
->
output
,
output_format
,
NULL
,
NULL
);
if
(
ret
<
0
)
{
printf
(
"Couldn't initialize output context: %s
\n
"
,
fprintf
(
stderr
,
"Couldn't initialize output context: %s
\n
"
,
av_err2str
(
ret
));
return
FFM_ERROR
;
}
...
...
@@ -679,7 +679,7 @@ int main(int argc, char *argv[])
ret
=
ffmpeg_mux_init
(
&
ffm
,
argc
,
argv
);
if
(
ret
!=
FFM_SUCCESS
)
{
puts
(
"Couldn't initialize muxer
"
);
fprintf
(
stderr
,
"Couldn't initialize muxer
\n
"
);
return
ret
;
}
...
...
plugins/obs-ffmpeg/obs-ffmpeg-mux.c
浏览文件 @
ca5a19cf
...
...
@@ -369,9 +369,23 @@ static void ffmpeg_mux_stop(void *data, uint64_t ts)
static
void
signal_failure
(
struct
ffmpeg_muxer
*
stream
)
{
int
ret
=
deactivate
(
stream
);
char
error
[
1024
];
int
ret
;
int
code
;
size_t
len
;
len
=
os_process_pipe_read_err
(
stream
->
pipe
,
(
uint8_t
*
)
error
,
sizeof
(
error
)
-
1
);
if
(
len
>
0
)
{
error
[
len
]
=
0
;
warn
(
"ffmpeg-mux: %s"
,
error
);
obs_output_set_last_error
(
stream
->
output
,
error
);
}
ret
=
deactivate
(
stream
);
switch
(
ret
)
{
case
FFM_UNSUPPORTED
:
code
=
OBS_OUTPUT_UNSUPPORTED
;
break
;
default:
code
=
OBS_OUTPUT_ERROR
;
...
...
plugins/obs-ffmpeg/obs-ffmpeg-output.c
浏览文件 @
ca5a19cf
...
...
@@ -86,6 +86,8 @@ struct ffmpeg_data {
struct
ffmpeg_cfg
config
;
bool
initialized
;
char
*
last_error
;
};
struct
ffmpeg_output
{
...
...
@@ -114,6 +116,30 @@ struct ffmpeg_output {
/* ------------------------------------------------------------------------- */
static
void
ffmpeg_output_set_last_error
(
struct
ffmpeg_data
*
data
,
const
char
*
error
)
{
if
(
data
->
last_error
)
bfree
(
data
->
last_error
);
data
->
last_error
=
bstrdup
(
error
);
}
void
ffmpeg_log_error
(
int
log_level
,
struct
ffmpeg_data
*
data
,
const
char
*
format
,
...)
{
va_list
args
;
char
out
[
4096
];
va_start
(
args
,
format
);
vsnprintf
(
out
,
sizeof
(
out
),
format
,
args
);
va_end
(
args
);
ffmpeg_output_set_last_error
(
data
,
out
);
blog
(
log_level
,
"%s"
,
out
);
}
static
bool
new_stream
(
struct
ffmpeg_data
*
data
,
AVStream
**
stream
,
AVCodec
**
codec
,
enum
AVCodecID
id
,
const
char
*
name
)
{
...
...
@@ -122,14 +148,14 @@ static bool new_stream(struct ffmpeg_data *data, AVStream **stream,
avcodec_find_encoder
(
id
);
if
(
!*
codec
)
{
blog
(
LOG_WARNING
,
"Couldn't find encoder '%s'"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Couldn't find encoder '%s'"
,
avcodec_get_name
(
id
));
return
false
;
}
*
stream
=
avformat_new_stream
(
data
->
output
,
*
codec
);
if
(
!*
stream
)
{
blog
(
LOG_WARNING
,
"Couldn't create stream for encoder '%s'"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Couldn't create stream for encoder '%s'"
,
avcodec_get_name
(
id
));
return
false
;
}
...
...
@@ -186,14 +212,14 @@ static bool open_video_codec(struct ffmpeg_data *data)
ret
=
avcodec_open2
(
context
,
data
->
vcodec
,
NULL
);
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"Failed to open video codec: %s"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to open video codec: %s"
,
av_err2str
(
ret
));
return
false
;
}
data
->
vframe
=
av_frame_alloc
();
if
(
!
data
->
vframe
)
{
blog
(
LOG_WARNING
,
"Failed to allocate video frame"
);
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to allocate video frame"
);
return
false
;
}
...
...
@@ -205,7 +231,7 @@ static bool open_video_codec(struct ffmpeg_data *data)
ret
=
av_frame_get_buffer
(
data
->
vframe
,
base_get_alignment
());
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"Failed to allocate vframe: %s"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to allocate vframe: %s"
,
av_err2str
(
ret
));
return
false
;
}
...
...
@@ -223,7 +249,7 @@ static bool init_swscale(struct ffmpeg_data *data, AVCodecContext *context)
SWS_BICUBIC
,
NULL
,
NULL
,
NULL
);
if
(
!
data
->
swscale
)
{
blog
(
LOG_WARNING
,
"Could not initialize swscale"
);
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Could not initialize swscale"
);
return
false
;
}
...
...
@@ -237,7 +263,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
struct
obs_video_info
ovi
;
if
(
!
obs_get_video_info
(
&
ovi
))
{
blog
(
LOG_WARNING
,
"No active video"
);
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"No active video"
);
return
false
;
}
...
...
@@ -292,7 +318,7 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx)
data
->
aframe
[
idx
]
=
av_frame_alloc
();
if
(
!
data
->
aframe
[
idx
])
{
blog
(
LOG_WARNING
,
"Failed to allocate audio frame"
);
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to allocate audio frame"
);
return
false
;
}
...
...
@@ -305,7 +331,7 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx)
ret
=
avcodec_open2
(
context
,
data
->
acodec
,
NULL
);
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"Failed to open audio codec: %s"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to open audio codec: %s"
,
av_err2str
(
ret
));
return
false
;
}
...
...
@@ -315,7 +341,7 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx)
ret
=
av_samples_alloc
(
data
->
samples
[
idx
],
NULL
,
context
->
channels
,
data
->
frame_size
,
context
->
sample_fmt
,
0
);
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"Failed to create audio buffer: %s"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to create audio buffer: %s"
,
av_err2str
(
ret
));
return
false
;
}
...
...
@@ -330,7 +356,7 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
struct
obs_audio_info
aoi
;
if
(
!
obs_get_audio_info
(
&
aoi
))
{
blog
(
LOG_WARNING
,
"No active audio"
);
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"No active audio"
);
return
false
;
}
...
...
@@ -396,7 +422,7 @@ static inline bool open_output_file(struct ffmpeg_data *data)
AVDictionary
*
dict
=
NULL
;
if
((
ret
=
av_dict_parse_string
(
&
dict
,
data
->
config
.
muxer_settings
,
"="
,
" "
,
0
)))
{
blog
(
LOG_WARNING
,
"Failed to parse muxer settings: %s
\n
%s"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Failed to parse muxer settings: %s
\n
%s"
,
av_err2str
(
ret
),
data
->
config
.
muxer_settings
);
av_dict_free
(
&
dict
);
...
...
@@ -419,8 +445,9 @@ static inline bool open_output_file(struct ffmpeg_data *data)
ret
=
avio_open2
(
&
data
->
output
->
pb
,
data
->
config
.
url
,
AVIO_FLAG_WRITE
,
NULL
,
&
dict
);
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"Couldn't open '%s', %s"
,
data
->
config
.
url
,
av_err2str
(
ret
));
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Couldn't open '%s', %s"
,
data
->
config
.
url
,
av_err2str
(
ret
));
av_dict_free
(
&
dict
);
return
false
;
}
...
...
@@ -432,7 +459,7 @@ static inline bool open_output_file(struct ffmpeg_data *data)
ret
=
avformat_write_header
(
data
->
output
,
&
dict
);
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"Error opening '%s': %s"
,
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Error opening '%s': %s"
,
data
->
config
.
url
,
av_err2str
(
ret
));
return
false
;
}
...
...
@@ -503,6 +530,9 @@ static void ffmpeg_data_free(struct ffmpeg_data *data)
avformat_free_context
(
data
->
output
);
}
if
(
data
->
last_error
)
bfree
(
data
->
last_error
);
memset
(
data
,
0
,
sizeof
(
struct
ffmpeg_data
));
}
...
...
@@ -565,13 +595,15 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
is_rtmp
?
NULL
:
data
->
config
.
format_mime_type
);
if
(
output_format
==
NULL
)
{
blog
(
LOG_WARNING
,
"Couldn't find matching output format with "
" parameters: name=%s, url=%s, mime=%s"
,
safe_str
(
is_rtmp
?
"flv"
:
data
->
config
.
format_name
),
safe_str
(
data
->
config
.
url
),
safe_str
(
is_rtmp
?
NULL
:
data
->
config
.
format_mime_type
));
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Couldn't find matching output format with "
"parameters: name=%s, url=%s, mime=%s"
,
safe_str
(
is_rtmp
?
"flv"
:
data
->
config
.
format_name
),
safe_str
(
data
->
config
.
url
),
safe_str
(
is_rtmp
?
NULL
:
data
->
config
.
format_mime_type
));
goto
fail
;
}
...
...
@@ -579,7 +611,8 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
NULL
,
NULL
);
if
(
!
data
->
output
)
{
blog
(
LOG_WARNING
,
"Couldn't create avformat context"
);
ffmpeg_log_error
(
LOG_WARNING
,
data
,
"Couldn't create avformat context"
);
goto
fail
;
}
...
...
@@ -603,7 +636,6 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
fail:
blog
(
LOG_WARNING
,
"ffmpeg_data_init failed"
);
ffmpeg_data_free
(
data
);
return
false
;
}
...
...
@@ -758,6 +790,7 @@ static void receive_video(void *param, struct video_data *frame)
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"receive_video: Error encoding "
"video: %s"
,
av_err2str
(
ret
));
//FIXME: stop the encode with an error
return
;
}
...
...
@@ -783,6 +816,7 @@ static void receive_video(void *param, struct video_data *frame)
if
(
ret
!=
0
)
{
blog
(
LOG_WARNING
,
"receive_video: Error writing video: %s"
,
av_err2str
(
ret
));
//FIXME: stop the encode with an error
}
data
->
total_frames
++
;
...
...
@@ -808,6 +842,7 @@ static void encode_audio(struct ffmpeg_output *output, int idx,
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"encode_audio: avcodec_fill_audio_frame "
"failed: %s"
,
av_err2str
(
ret
));
//FIXME: stop the encode with an error
return
;
}
...
...
@@ -829,6 +864,7 @@ static void encode_audio(struct ffmpeg_output *output, int idx,
if
(
ret
<
0
)
{
blog
(
LOG_WARNING
,
"encode_audio: Error encoding audio: %s"
,
av_err2str
(
ret
));
//FIXME: stop the encode with an error
return
;
}
...
...
@@ -989,8 +1025,9 @@ static int process_packet(struct ffmpeg_output *output)
ret
=
av_interleaved_write_frame
(
output
->
ff_data
.
output
,
&
packet
);
if
(
ret
<
0
)
{
av_free_packet
(
&
packet
);
blog
(
LOG_WARNING
,
"receive_audio: Error writing packet: %s"
,
av_err2str
(
ret
));
ffmpeg_log_error
(
LOG_WARNING
,
&
output
->
ff_data
,
"receive_audio: Error writing packet: %s"
,
av_err2str
(
ret
));
return
ret
;
}
...
...
@@ -1108,8 +1145,14 @@ static bool try_connect(struct ffmpeg_output *output)
success
=
ffmpeg_data_init
(
&
output
->
ff_data
,
&
config
);
obs_data_release
(
settings
);
if
(
!
success
)
if
(
!
success
)
{
if
(
output
->
ff_data
.
last_error
)
{
obs_output_set_last_error
(
output
->
output
,
output
->
ff_data
.
last_error
);
}
ffmpeg_data_free
(
&
output
->
ff_data
);
return
false
;
}
struct
audio_convert_info
aci
=
{
.
format
=
output
->
ff_data
.
audio_format
...
...
@@ -1122,8 +1165,9 @@ static bool try_connect(struct ffmpeg_output *output)
ret
=
pthread_create
(
&
output
->
write_thread
,
NULL
,
write_thread
,
output
);
if
(
ret
!=
0
)
{
blog
(
LOG_WARNING
,
"ffmpeg_output_start: failed to create write "
"thread."
);
ffmpeg_log_error
(
LOG_WARNING
,
&
output
->
ff_data
,
"ffmpeg_output_start: failed to create write "
"thread."
);
ffmpeg_output_full_stop
(
output
);
return
false
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录