Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
尘离序散
obs-studio
提交
76d7126a
O
obs-studio
项目概览
尘离序散
/
obs-studio
与 Fork 源项目一致
从无法访问的项目Fork
通知
30
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
obs-studio
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
76d7126a
编写于
4月 28, 2014
作者:
J
Jim
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #72 from fryshorts/pulse-input
Several Improvements to the pulseaudio capture
上级
88574a27
9a146615
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
127 addition
and
36 deletion
+127
-36
plugins/linux-pulseaudio/pulse-input.c
plugins/linux-pulseaudio/pulse-input.c
+124
-33
plugins/linux-pulseaudio/pulse-wrapper.c
plugins/linux-pulseaudio/pulse-wrapper.c
+1
-1
plugins/linux-pulseaudio/pulse-wrapper.h
plugins/linux-pulseaudio/pulse-wrapper.h
+2
-2
未找到文件。
plugins/linux-pulseaudio/pulse-input.c
浏览文件 @
76d7126a
...
...
@@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <util/platform.h>
#include <util/bmem.h>
#include <obs.h>
...
...
@@ -34,9 +35,13 @@ struct pulse_data {
uint_fast32_t
bytes_per_frame
;
pa_stream
*
stream
;
bool
ostime
;
};
/*
static
void
pulse_stop_recording
(
struct
pulse_data
*
data
);
/**
* get obs from pulse audio format
*/
static
enum
audio_format
pulse_to_obs_audio_format
(
...
...
@@ -58,8 +63,8 @@ static enum audio_format pulse_to_obs_audio_format(
return
AUDIO_FORMAT_UNKNOWN
;
}
/*
*
g
et the buffer size needed for length msec with current settings
/*
*
*
G
et the buffer size needed for length msec with current settings
*/
static
uint_fast32_t
get_buffer_size
(
struct
pulse_data
*
data
,
uint_fast32_t
length
)
...
...
@@ -67,7 +72,7 @@ static uint_fast32_t get_buffer_size(struct pulse_data *data,
return
(
length
*
data
->
samples_per_sec
*
data
->
bytes_per_frame
)
/
1000
;
}
/*
/*
*
* Get latency for a pulse audio stream
*/
static
int
pulse_get_stream_latency
(
pa_stream
*
stream
,
int64_t
*
latency
)
...
...
@@ -81,8 +86,10 @@ static int pulse_get_stream_latency(pa_stream *stream, int64_t *latency)
return
ret
;
}
/*
/*
*
* Callback for pulse which gets executed when new audio data is available
*
* @warning The function may be called even after disconnecting the stream
*/
static
void
pulse_stream_read
(
pa_stream
*
p
,
size_t
nbytes
,
void
*
userdata
)
{
...
...
@@ -95,6 +102,9 @@ static void pulse_stream_read(pa_stream *p, size_t nbytes, void *userdata)
uint64_t
pa_time
;
int64_t
pa_latency
;
if
(
!
data
->
stream
)
goto
exit
;
pa_stream_peek
(
data
->
stream
,
&
frames
,
&
bytes
);
// check if we got data
...
...
@@ -115,6 +125,7 @@ static void pulse_stream_read(pa_stream *p, size_t nbytes, void *userdata)
pa_stream_drop
(
data
->
stream
);
goto
exit
;
}
pa_time
=
(
!
data
->
ostime
)
?
pa_time
*
1000
:
os_gettime_ns
();
pulse_get_stream_latency
(
data
->
stream
,
&
pa_latency
);
...
...
@@ -124,7 +135,7 @@ static void pulse_stream_read(pa_stream *p, size_t nbytes, void *userdata)
out
.
format
=
pulse_to_obs_audio_format
(
data
->
format
);
out
.
data
[
0
]
=
(
uint8_t
*
)
frames
;
out
.
frames
=
bytes
/
data
->
bytes_per_frame
;
out
.
timestamp
=
(
pa_time
-
pa_latency
)
*
1000
;
out
.
timestamp
=
pa_time
-
(
pa_latency
*
1000
)
;
obs_source_output_audio
(
data
->
source
,
&
out
);
pa_stream_drop
(
data
->
stream
);
...
...
@@ -133,7 +144,7 @@ exit:
pulse_signal
(
0
);
}
/*
/*
*
* Server info callback
*/
static
void
pulse_server_info
(
pa_context
*
c
,
const
pa_server_info
*
i
,
...
...
@@ -154,7 +165,7 @@ static void pulse_server_info(pa_context *c, const pa_server_info *i,
pulse_signal
(
0
);
}
/*
/*
*
* start recording
*/
static
int_fast32_t
pulse_start_recording
(
struct
pulse_data
*
data
)
...
...
@@ -207,6 +218,7 @@ static int_fast32_t pulse_start_recording(struct pulse_data *data)
&
attr
,
flags
);
pulse_unlock
();
if
(
ret
<
0
)
{
pulse_stop_recording
(
data
);
blog
(
LOG_ERROR
,
"pulse-input: Unable to connect to stream"
);
return
-
1
;
}
...
...
@@ -215,7 +227,7 @@ static int_fast32_t pulse_start_recording(struct pulse_data *data)
return
0
;
}
/*
/*
*
* stop recording
*/
static
void
pulse_stop_recording
(
struct
pulse_data
*
data
)
...
...
@@ -224,11 +236,12 @@ static void pulse_stop_recording(struct pulse_data *data)
pulse_lock
();
pa_stream_disconnect
(
data
->
stream
);
pa_stream_unref
(
data
->
stream
);
data
->
stream
=
NULL
;
pulse_unlock
();
}
}
/*
/*
*
* input info callback
*/
static
void
pulse_input_info
(
pa_context
*
c
,
const
pa_source_info
*
i
,
int
eol
,
...
...
@@ -262,8 +275,8 @@ skip:
pulse_signal
(
0
);
}
/*
*
g
et plugin properties
/*
*
*
G
et plugin properties
*/
static
obs_properties_t
pulse_properties
(
const
char
*
locale
,
bool
input
)
{
...
...
@@ -276,6 +289,8 @@ static obs_properties_t pulse_properties(const char *locale, bool input)
pulse_get_source_info_list
(
cb
,
(
void
*
)
devices
);
pulse_unref
();
obs_properties_add_bool
(
props
,
"ostime"
,
"Use OS timestamps"
);
return
props
;
}
...
...
@@ -289,15 +304,67 @@ static obs_properties_t pulse_output_properties(const char *locale)
return
pulse_properties
(
locale
,
false
);
}
/*
*
get plugin defaults
/*
*
*
Server info callback
*/
static
void
pulse_defaults
(
obs_data_t
settings
)
static
void
pulse_input_device
(
pa_context
*
c
,
const
pa_server_info
*
i
,
void
*
userdata
)
{
obs_data_set_default_string
(
settings
,
"device_id"
,
"default"
);
UNUSED_PARAMETER
(
c
);
obs_data_t
settings
=
(
obs_data_t
)
userdata
;
obs_data_set_default_string
(
settings
,
"device_id"
,
i
->
default_source_name
);
blog
(
LOG_DEBUG
,
"pulse-input: Default input device: '%s'"
,
i
->
default_source_name
);
pulse_signal
(
0
);
}
/*
static
void
pulse_output_device
(
pa_context
*
c
,
const
pa_server_info
*
i
,
void
*
userdata
)
{
UNUSED_PARAMETER
(
c
);
obs_data_t
settings
=
(
obs_data_t
)
userdata
;
char
*
monitor
=
bzalloc
(
strlen
(
i
->
default_sink_name
)
+
9
);
strcat
(
monitor
,
i
->
default_sink_name
);
strcat
(
monitor
,
".monitor"
);
obs_data_set_default_string
(
settings
,
"device_id"
,
monitor
);
blog
(
LOG_DEBUG
,
"pulse-input: Default output device: '%s'"
,
monitor
);
bfree
(
monitor
);
pulse_signal
(
0
);
}
/**
* Get plugin defaults
*/
static
void
pulse_defaults
(
obs_data_t
settings
,
bool
input
)
{
pulse_init
();
pa_server_info_cb_t
cb
=
(
input
)
?
pulse_input_device
:
pulse_output_device
;
pulse_get_server_info
(
cb
,
(
void
*
)
settings
);
pulse_unref
();
obs_data_set_default_bool
(
settings
,
"ostime"
,
false
);
}
static
void
pulse_input_defaults
(
obs_data_t
settings
)
{
return
pulse_defaults
(
settings
,
true
);
}
static
void
pulse_output_defaults
(
obs_data_t
settings
)
{
return
pulse_defaults
(
settings
,
false
);
}
/**
* Returns the name of the plugin
*/
static
const
char
*
pulse_input_getname
(
const
char
*
locale
)
...
...
@@ -312,7 +379,7 @@ static const char *pulse_output_getname(const char *locale)
return
"Pulse Audio Output Capture"
;
}
/*
/*
*
* Destroy the plugin object and free all memory
*/
static
void
pulse_destroy
(
void
*
vptr
)
...
...
@@ -322,7 +389,8 @@ static void pulse_destroy(void *vptr)
if
(
!
data
)
return
;
pulse_stop_recording
(
data
);
if
(
data
->
stream
)
pulse_stop_recording
(
data
);
pulse_unref
();
if
(
data
->
device
)
...
...
@@ -332,7 +400,37 @@ static void pulse_destroy(void *vptr)
blog
(
LOG_DEBUG
,
"pulse-input: Input destroyed"
);
}
/*
/**
* Update the input settings
*/
static
void
pulse_update
(
void
*
vptr
,
obs_data_t
settings
)
{
PULSE_DATA
(
vptr
);
bool
restart
=
false
;
char
*
new_device
;
new_device
=
bstrdup
(
obs_data_getstring
(
settings
,
"device_id"
));
if
(
!
data
->
device
||
strcmp
(
data
->
device
,
new_device
)
!=
0
)
{
if
(
data
->
device
)
bfree
(
data
->
device
);
data
->
device
=
new_device
;
restart
=
true
;
}
if
(
data
->
ostime
!=
obs_data_getbool
(
settings
,
"ostime"
))
{
data
->
ostime
=
obs_data_getbool
(
settings
,
"ostime"
);
restart
=
true
;
}
if
(
!
restart
)
return
;
if
(
data
->
stream
)
pulse_stop_recording
(
data
);
pulse_start_recording
(
data
);
}
/**
* Create the plugin object
*/
static
void
*
pulse_create
(
obs_data_t
settings
,
obs_source_t
source
)
...
...
@@ -341,24 +439,17 @@ static void *pulse_create(obs_data_t settings, obs_source_t source)
data
->
source
=
source
;
data
->
speakers
=
SPEAKERS_STEREO
;
data
->
device
=
bstrdup
(
obs_data_getstring
(
settings
,
"device_id"
));
pulse_init
();
if
(
pulse_start_recording
(
data
)
<
0
)
goto
fail
;
pulse_update
(
data
,
settings
);
if
(
data
->
stream
)
return
data
;
return
data
;
fail:
pulse_destroy
(
data
);
return
NULL
;
}
static
void
pulse_update
(
void
*
vptr
,
obs_data_t
settings
)
{
UNUSED_PARAMETER
(
vptr
);
UNUSED_PARAMETER
(
settings
);
}
struct
obs_source_info
pulse_input_capture
=
{
.
id
=
"pulse_input_capture"
,
.
type
=
OBS_SOURCE_TYPE_INPUT
,
...
...
@@ -367,7 +458,7 @@ struct obs_source_info pulse_input_capture = {
.
create
=
pulse_create
,
.
destroy
=
pulse_destroy
,
.
update
=
pulse_update
,
.
defaults
=
pulse_defaults
,
.
defaults
=
pulse_
input_
defaults
,
.
properties
=
pulse_input_properties
};
...
...
@@ -379,6 +470,6 @@ struct obs_source_info pulse_output_capture = {
.
create
=
pulse_create
,
.
destroy
=
pulse_destroy
,
.
update
=
pulse_update
,
.
defaults
=
pulse_defaults
,
.
defaults
=
pulse_
output_
defaults
,
.
properties
=
pulse_output_properties
};
plugins/linux-pulseaudio/pulse-wrapper.c
浏览文件 @
76d7126a
...
...
@@ -86,7 +86,7 @@ static void pulse_init_context()
static
int_fast32_t
pulse_context_ready
()
{
pulse_lock
();
if
(
!
PA_CONTEXT_IS_GOOD
(
pa_context_get_state
(
pulse_context
)))
{
pulse_unlock
();
return
-
1
;
...
...
plugins/linux-pulseaudio/pulse-wrapper.h
浏览文件 @
76d7126a
...
...
@@ -83,7 +83,7 @@ void pulse_accept();
* Request source information
*
* The function will block until the operation was executed and the mainloop
* called the provided callback function
s
.
* called the provided callback function.
*
* @return negative on error
*
...
...
@@ -97,7 +97,7 @@ int_fast32_t pulse_get_source_info_list(pa_source_info_cb_t cb, void *userdata);
* Request server information
*
* The function will block until the operation was executed and the mainloop
* called the provided callback function
s
* called the provided callback function
.
*
* @return negative on error
*
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录