Fix audio streaming and mac semaphores

...The reason why audio didn't work was because I overwrote the bitrate
values.

As for semaphores, mac doesn't support unnamed semaphores without using
mach semaphores.  So, I just implemented a semaphore wrapper for each
OS.
This commit is contained in:
jp9000
2014-03-10 19:04:00 -07:00
parent faabeff743
commit 585fd8f969
7 changed files with 203 additions and 77 deletions

View File

@@ -80,7 +80,7 @@ struct audio_output {
size_t planes;
pthread_t thread;
event_t stop_event;
os_event_t stop_event;
DARRAY(uint8_t) mix_buffers[MAX_AV_PLANES];
@@ -437,7 +437,7 @@ static void *audio_thread(void *param)
uint64_t prev_time = os_gettime_ns() - buffer_time;
uint64_t audio_time;
while (event_try(audio->stop_event) == EAGAIN) {
while (os_event_try(audio->stop_event) == EAGAIN) {
os_sleep_ms(AUDIO_WAIT_TIME);
pthread_mutex_lock(&audio->line_mutex);
@@ -590,7 +590,7 @@ int audio_output_open(audio_t *audio, struct audio_output_info *info)
goto fail;
if (pthread_mutex_init(&out->input_mutex, NULL) != 0)
goto fail;
if (event_init(&out->stop_event, EVENT_TYPE_MANUAL) != 0)
if (os_event_init(&out->stop_event, OS_EVENT_TYPE_MANUAL) != 0)
goto fail;
if (pthread_create(&out->thread, NULL, audio_thread, out) != 0)
goto fail;
@@ -613,7 +613,7 @@ void audio_output_close(audio_t audio)
return;
if (audio->initialized) {
event_signal(audio->stop_event);
os_event_signal(audio->stop_event);
pthread_join(audio->thread, &thread_ret);
}
@@ -631,7 +631,7 @@ void audio_output_close(audio_t audio)
da_free(audio->mix_buffers[i]);
da_free(audio->inputs);
event_destroy(audio->stop_event);
os_event_destroy(audio->stop_event);
pthread_mutex_destroy(&audio->line_mutex);
bfree(audio);
}

View File

@@ -50,13 +50,13 @@ struct video_output {
pthread_t thread;
pthread_mutex_t data_mutex;
event_t stop_event;
os_event_t stop_event;
struct video_data cur_frame;
struct video_data next_frame;
bool new_frame;
event_t update_event;
os_event_t update_event;
uint64_t frame_time;
volatile uint64_t cur_video_time;
@@ -125,13 +125,13 @@ static void *video_thread(void *param)
struct video_output *video = param;
uint64_t cur_time = os_gettime_ns();
while (event_try(video->stop_event) == EAGAIN) {
while (os_event_try(video->stop_event) == EAGAIN) {
/* wait half a frame, update frame */
cur_time += (video->frame_time/2);
os_sleepto_ns(cur_time);
video->cur_video_time = cur_time;
event_signal(video->update_event);
os_event_signal(video->update_event);
/* wait another half a frame, swap and output frames */
cur_time += (video->frame_time/2);
@@ -174,9 +174,9 @@ int video_output_open(video_t *video, struct video_output_info *info)
goto fail;
if (pthread_mutex_init(&out->input_mutex, NULL) != 0)
goto fail;
if (event_init(&out->stop_event, EVENT_TYPE_MANUAL) != 0)
if (os_event_init(&out->stop_event, OS_EVENT_TYPE_MANUAL) != 0)
goto fail;
if (event_init(&out->update_event, EVENT_TYPE_AUTO) != 0)
if (os_event_init(&out->update_event, OS_EVENT_TYPE_AUTO) != 0)
goto fail;
if (pthread_create(&out->thread, NULL, video_thread, out) != 0)
goto fail;
@@ -201,8 +201,8 @@ void video_output_close(video_t video)
video_input_free(&video->inputs.array[i]);
da_free(video->inputs);
event_destroy(video->update_event);
event_destroy(video->stop_event);
os_event_destroy(video->update_event);
os_event_destroy(video->stop_event);
pthread_mutex_destroy(&video->data_mutex);
pthread_mutex_destroy(&video->input_mutex);
bfree(video);
@@ -342,8 +342,8 @@ bool video_output_wait(video_t video)
{
if (!video) return false;
event_wait(video->update_event);
return event_try(video->stop_event) == EAGAIN;
os_event_wait(video->update_event);
return os_event_try(video->stop_event) == EAGAIN;
}
uint64_t video_getframetime(video_t video)
@@ -364,8 +364,8 @@ void video_output_stop(video_t video)
return;
if (video->initialized) {
event_signal(video->stop_event);
os_event_signal(video->stop_event);
pthread_join(video->thread, &thread_ret);
event_signal(video->update_event);
os_event_signal(video->update_event);
}
}

View File

@@ -16,6 +16,9 @@
#ifdef __APPLE__
#include <sys/time.h>
#include <mach/semaphore.h>
#else
#include <semaphore.h>
#endif
#include "bmem.h"
@@ -45,7 +48,7 @@ int event_init(event_t *event, enum event_type type)
return code;
}
data->manual = (type == EVENT_TYPE_MANUAL);
data->manual = (type == OS_EVENT_TYPE_MANUAL);
data->signalled = false;
*event = data;
@@ -149,3 +152,84 @@ void event_reset(event_t event)
event->signalled = false;
pthread_mutex_unlock(&event->mutex);
}
#ifdef __APPLE__
struct os_sem_data {
semaphore_t sem;
task_t task;
};
int os_sem_init(os_sem_t *sem, int value)
{
semaphore_t new_sem;
task_t task = mach_task_self();
if (semaphore_create(task, &new_sem, 0, value) != KERN_SUCCESS)
return -1;
*sem = bzalloc(sizeof(struct os_sem_data));
(*sem)->sem = new_sem;
(*sem)->task = task;
return 0;
}
void os_sem_destroy(os_sem_t sem)
{
if (sem) {
semaphore_destroy(sem->task, sem->sem);
bfree(sem);
}
}
int os_sem_post(os_sem_t sem)
{
if (!sem) return -1;
return (semaphore_signal(sem->sem) == KERN_SUCCESS) ? 0 : -1;
}
int os_sem_wait(os_sem_t sem)
{
if (!sem) return -1;
return (semaphore_wait(sem->sem) == KERN_SUCCESS) ? 0 : -1;
}
#else
struct os_sem_data {
sem_t sem;
};
int os_sem_init(os_sem_t *sem, int value)
{
sem_t new_sem;
int ret = sem_init(&new_sem, 0, value);
if (ret != 0)
return ret;
*sem = bzalloc(sizeof(struct os_sem_data));
(*sem)->sem = new_sem;
return 0;
}
void os_sem_destroy(os_sem_t sem)
{
if (sem) {
semaphore_destroy(&sem->sem);
bfree(sem);
}
}
int os_sem_post(os_sem_t sem)
{
if (!sem) return -1;
return sem_post(&sem->sem);
}
int os_sem_wait(os_sem_t sem)
{
if (!sem) return -1;
return sem_wait(&sem->sem);
}
#endif

View File

@@ -20,27 +20,31 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
struct event_data {
struct os_event_data {
HANDLE handle;
};
int event_init(event_t *event, enum event_type type)
struct os_sem_data {
HANDLE handle;
};
int os_event_init(os_event_t *event, enum os_event_type type)
{
HANDLE handle;
struct event_data *data;
struct os_event_data *data;
handle = CreateEvent(NULL, (type == EVENT_TYPE_MANUAL), FALSE, NULL);
handle = CreateEvent(NULL, (type == OS_EVENT_TYPE_MANUAL), FALSE, NULL);
if (!handle)
return -1;
data = bmalloc(sizeof(struct event_data));
data = bmalloc(sizeof(struct os_event_data));
data->handle = handle;
*event = data;
return 0;
}
void event_destroy(event_t event)
void os_event_destroy(os_event_t event)
{
if (event) {
CloseHandle(event->handle);
@@ -48,7 +52,7 @@ void event_destroy(event_t event)
}
}
int event_wait(event_t event)
int os_event_wait(os_event_t event)
{
DWORD code;
@@ -62,7 +66,7 @@ int event_wait(event_t event)
return 0;
}
int event_timedwait(event_t event, unsigned long milliseconds)
int os_event_timedwait(os_event_t event, unsigned long milliseconds)
{
DWORD code;
@@ -78,7 +82,7 @@ int event_timedwait(event_t event, unsigned long milliseconds)
return 0;
}
int event_try(event_t event)
int os_event_try(os_event_t event)
{
DWORD code;
@@ -94,7 +98,7 @@ int event_try(event_t event)
return 0;
}
int event_signal(event_t event)
int os_event_signal(os_event_t event)
{
if (!event)
return EINVAL;
@@ -105,10 +109,44 @@ int event_signal(event_t event)
return 0;
}
void event_reset(event_t event)
void os_event_reset(os_event_t event)
{
if (!event)
return;
ResetEvent(event->handle);
}
int os_sem_init(os_sem_t *sem, int value)
{
HANDLE handle = CreateSemaphore(NULL, (LONG)value, 0x7FFFFFFF, NULL);
if (!handle)
return -1;
*sem = bzalloc(sizeof(struct os_sem_data));
(*sem)->handle = handle;
return 0;
}
void os_sem_destroy(os_sem_t sem)
{
if (sem) {
CloseHandle(sem->handle);
bfree(sem);
}
}
int os_sem_post(os_sem_t sem)
{
if (!sem) return -1;
return ReleaseSemaphore(sem->handle, 1, NULL) ? 0 : -1;
}
int os_sem_wait(os_sem_t sem)
{
DWORD ret;
if (!sem) return -1;
ret = WaitForSingleObject(sem->handle, INFINITE);
return (ret == WAIT_OBJECT_0) ? 0 : -1;
}

View File

@@ -28,11 +28,9 @@
#ifdef _MSC_VER
#include "../../deps/w32-pthreads/pthread.h"
#include "../../deps/w32-pthreads/semaphore.h"
#else
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#endif
#ifdef __cplusplus
@@ -46,21 +44,28 @@ static inline void pthread_mutex_init_value(pthread_mutex_t *mutex)
*mutex = init_val;
}
enum event_type {
EVENT_TYPE_AUTO,
EVENT_TYPE_MANUAL
enum os_event_type {
OS_EVENT_TYPE_AUTO,
OS_EVENT_TYPE_MANUAL
};
struct event_data;
typedef struct event_data *event_t;
struct os_event_data;
struct os_sem_data;
typedef struct os_event_data *os_event_t;
typedef struct os_sem_data *os_sem_t;
EXPORT int event_init(event_t *event, enum event_type type);
EXPORT void event_destroy(event_t event);
EXPORT int event_wait(event_t event);
EXPORT int event_timedwait(event_t event, unsigned long milliseconds);
EXPORT int event_try(event_t event);
EXPORT int event_signal(event_t event);
EXPORT void event_reset(event_t event);
EXPORT int os_event_init(os_event_t *event, enum os_event_type type);
EXPORT void os_event_destroy(os_event_t event);
EXPORT int os_event_wait(os_event_t event);
EXPORT int os_event_timedwait(os_event_t event, unsigned long milliseconds);
EXPORT int os_event_try(os_event_t event);
EXPORT int os_event_signal(os_event_t event);
EXPORT void os_event_reset(os_event_t event);
EXPORT int os_sem_init(os_sem_t *sem, int value);
EXPORT void os_sem_destroy(os_sem_t sem);
EXPORT int os_sem_post(os_sem_t sem);
EXPORT int os_sem_wait(os_sem_t sem);
#ifdef __cplusplus