libobs: Process all scene audio actions if no audio playing
When there are audio sources in a scene and they've all stopped playing their audio (audio is pending), all scene item audio actions (volume changes, toggling visibility) will perpetually buffer and no longer be processed until audio plays again. So instead of that, if all audio sources have stopped playing in the scene, just process all pending scene item audio actions immediately to prevent them from never being processed while waiting for a scene item to start playing audio.
This commit is contained in:
parent
521c40460e
commit
e71137534c
@ -741,11 +741,13 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
|
||||
bool cur_visible = item->visible;
|
||||
uint64_t frame_num = 0;
|
||||
size_t deref_count = 0;
|
||||
float *buf;
|
||||
float *buf = NULL;
|
||||
|
||||
if (!*p_buf)
|
||||
*p_buf = malloc(AUDIO_OUTPUT_FRAMES * sizeof(float));
|
||||
buf = *p_buf;
|
||||
if (p_buf) {
|
||||
if (!*p_buf)
|
||||
*p_buf = malloc(AUDIO_OUTPUT_FRAMES * sizeof(float));
|
||||
buf = *p_buf;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&item->actions_mutex);
|
||||
|
||||
@ -760,7 +762,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
|
||||
new_frame_num = (timestamp - ts) * (uint64_t)sample_rate /
|
||||
1000000000ULL;
|
||||
|
||||
if (new_frame_num >= AUDIO_OUTPUT_FRAMES)
|
||||
if (ts && new_frame_num >= AUDIO_OUTPUT_FRAMES)
|
||||
break;
|
||||
|
||||
da_erase(item->audio_actions, i--);
|
||||
@ -769,7 +771,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
|
||||
if (!item->visible)
|
||||
deref_count++;
|
||||
|
||||
if (new_frame_num > frame_num) {
|
||||
if (buf && new_frame_num > frame_num) {
|
||||
for (; frame_num < new_frame_num; frame_num++)
|
||||
buf[frame_num] = cur_visible ? 1.0f : 0.0f;
|
||||
}
|
||||
@ -777,8 +779,10 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
|
||||
cur_visible = item->visible;
|
||||
}
|
||||
|
||||
for (; frame_num < AUDIO_OUTPUT_FRAMES; frame_num++)
|
||||
buf[frame_num] = cur_visible ? 1.0f : 0.0f;
|
||||
if (buf) {
|
||||
for (; frame_num < AUDIO_OUTPUT_FRAMES; frame_num++)
|
||||
buf[frame_num] = cur_visible ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&item->actions_mutex);
|
||||
|
||||
@ -790,7 +794,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool apply_scene_item_volume(struct obs_scene_item *item,
|
||||
static bool apply_scene_item_volume(struct obs_scene_item *item,
|
||||
float **buf, uint64_t ts, size_t sample_rate)
|
||||
{
|
||||
bool actions_pending;
|
||||
@ -808,7 +812,7 @@ static inline bool apply_scene_item_volume(struct obs_scene_item *item,
|
||||
uint64_t duration = (uint64_t)AUDIO_OUTPUT_FRAMES *
|
||||
1000000000ULL / (uint64_t)sample_rate;
|
||||
|
||||
if (action.timestamp < (ts + duration)) {
|
||||
if (!ts || action.timestamp < (ts + duration)) {
|
||||
apply_scene_item_audio_actions(item, buf, ts,
|
||||
sample_rate);
|
||||
return true;
|
||||
@ -818,6 +822,12 @@ static inline bool apply_scene_item_volume(struct obs_scene_item *item,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void process_all_audio_actions(struct obs_scene_item *item,
|
||||
size_t sample_rate)
|
||||
{
|
||||
while (apply_scene_item_volume(item, NULL, 0, sample_rate));
|
||||
}
|
||||
|
||||
static void mix_audio_with_buf(float *p_out, float *p_in, float *buf_in,
|
||||
size_t pos, size_t count)
|
||||
{
|
||||
@ -867,6 +877,14 @@ static bool scene_audio_render(void *data, uint64_t *ts_out,
|
||||
}
|
||||
|
||||
if (!timestamp) {
|
||||
/* just process all pending audio actions if no audio playing,
|
||||
* otherwise audio actions will just never be processed */
|
||||
item = scene->first_item;
|
||||
while (item) {
|
||||
process_all_audio_actions(item, sample_rate);
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
audio_unlock(scene);
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user