first commit

This commit is contained in:
jp9000
2013-09-30 19:37:13 -07:00
commit f255ae1922
545 changed files with 95469 additions and 0 deletions

134
libobs/media-io/audio-io.c Normal file
View File

@@ -0,0 +1,134 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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/threading.h"
#include "../util/darray.h"
#include "../util/platform.h"
#include "audio-io.h"
/* TODO: Incomplete */
struct audio_output {
struct audio_info info;
media_t media;
media_output_t output;
pthread_t thread;
pthread_mutex_t data_mutex;
event_t stop_event;
struct darray pending_frames;
bool initialized;
};
/* ------------------------------------------------------------------------- */
static void *audio_thread(void *param)
{
struct audio_output *audio = param;
while (event_try(&audio->stop_event) == EAGAIN) {
os_sleep_ms(5);
/* TODO */
}
return NULL;
}
/* ------------------------------------------------------------------------- */
static inline bool valid_audio_params(struct audio_info *info)
{
return info->channels > 0 && info->format && info->name &&
info->samples_per_sec > 0 && info->speakers > 0;
}
static inline bool ao_add_to_media(audio_t audio)
{
struct media_output_info oi;
oi.format = audio->info.format;
oi.obj = audio;
oi.connect = NULL;
audio->output = media_output_create(&oi);
if (!audio->output)
return false;
media_add_output(audio->media, audio->output);
return true;
}
int audio_output_open(audio_t *audio, media_t media, struct audio_info *info)
{
struct audio_output *out;
if (!valid_audio_params(info))
return AUDIO_OUTPUT_INVALIDPARAM;
out = bmalloc(sizeof(struct audio_output));
memset(out, 0, sizeof(struct audio_output));
memcpy(&out->info, info, sizeof(struct audio_info));
out->media = media;
if (pthread_mutex_init(&out->data_mutex, NULL) != 0)
goto fail;
if (event_init(&out->stop_event, true) != 0)
goto fail;
if (!ao_add_to_media(out))
goto fail;
if (pthread_create(&out->thread, NULL, audio_thread, out) != 0)
goto fail;
out->initialized = true;
*audio = out;
return AUDIO_OUTPUT_SUCCESS;
fail:
audio_output_close(out);
return AUDIO_OUTPUT_FAIL;
}
void audio_output_data(audio_t audio, struct audio_data *data)
{
pthread_mutex_lock(&audio->data_mutex);
/* TODO */
pthread_mutex_unlock(&audio->data_mutex);
}
void audio_output_close(audio_t audio)
{
void *thread_ret;
if (!audio)
return;
if (audio->initialized) {
event_signal(&audio->stop_event);
pthread_join(audio->thread, &thread_ret);
}
media_remove_output(audio->media, audio->output);
event_destroy(&audio->stop_event);
pthread_mutex_destroy(&audio->data_mutex);
bfree(audio);
}

View File

@@ -0,0 +1,91 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#ifndef AUDIO_IO_H
#define AUDIO_IO_H
#include "../util/c99defs.h"
#include "media-io.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Base audio output component. Use this to create an audio output track
* for the media.
*/
struct audio_output;
typedef struct audio_output *audio_t;
enum audio_type {
AUDIO_FORMAT_UNKNOWN,
AUDIO_FORMAT_8BIT,
AUDIO_FORMAT_16BIT,
AUDIO_FORMAT_24BIT,
AUDIO_FORMAT_32BIT,
AUDIO_FORMAT_FLOAT,
};
enum speaker_setup {
SPEAKERS_UNKNOWN,
SPEAKERS_MONO,
SPEAKERS_STEREO,
SPEAKERS_2POINT1,
SPEAKERS_QUAD,
SPEAKERS_4POINT1,
SPEAKERS_5POINT1,
SPEAKERS_5POINT1_SURROUND,
SPEAKERS_7POINT1,
SPEAKERS_7POINT1_SURROUND,
SPEAKERS_SURROUND,
};
struct audio_data {
void *data;
uint32_t frames;
uint32_t speakers;
uint32_t samples_per_sec;
enum audio_type type;
uint64_t timestamp;
};
struct audio_info {
const char *name;
const char *format;
uint32_t channels;
uint32_t samples_per_sec;
enum audio_type type;
enum speaker_setup speakers;
};
#define AUDIO_OUTPUT_SUCCESS 0
#define AUDIO_OUTPUT_INVALIDPARAM -1
#define AUDIO_OUTPUT_FAIL -2
EXPORT int audio_output_open(audio_t *audio, media_t media,
struct audio_info *info);
EXPORT void audio_output_data(audio_t audio, struct audio_data *data);
EXPORT void audio_output_close(audio_t audio);
#ifdef __cplusplus
}
#endif
#endif

View File

158
libobs/media-io/media-io.c Normal file
View File

@@ -0,0 +1,158 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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/threading.h"
#include "../util/darray.h"
#include "../util/bmem.h"
#include "media-io.h"
/* TODO: Incomplete */
struct media_input {
struct media_input_info info;
struct media_output *connection;
};
struct media_output {
struct media_output_info info;
DARRAY(media_input_t) connections;
pthread_mutex_t mutex;
};
struct media_data {
DARRAY(media_output_t) outputs;
};
/* ------------------------------------------------------------------------- */
media_input_t media_input_create(struct media_input_info *info)
{
struct media_input *input;
if (!info || !info->format || !info->on_input)
return NULL;
input = bmalloc(sizeof(struct media_input));
input->connection = NULL;
memcpy(&input->info, info, sizeof(struct media_input_info));
return input;
}
void media_input_destroy(media_input_t input)
{
if (input)
bfree(input);
}
/* ------------------------------------------------------------------------- */
media_output_t media_output_create(struct media_output_info *info)
{
struct media_output *output;
if (!info || !info->format)
return NULL;
output = bmalloc(sizeof(struct media_output));
da_init(output->connections);
memcpy(&output->info, info, sizeof(struct media_output_info));
if (pthread_mutex_init(&output->mutex, NULL) != 0) {
bfree(output);
return NULL;
}
return output;
}
void media_output_data(media_output_t output, const void *data)
{
size_t i;
pthread_mutex_lock(&output->mutex);
for (i = 0; i < output->connections.num; i++) {
media_input_t input = output->connections.array[i];
input->info.on_input(input->info.obj, data);
}
pthread_mutex_unlock(&output->mutex);
}
void media_output_destroy(media_output_t output)
{
if (output) {
da_free(output->connections);
pthread_mutex_destroy(&output->mutex);
bfree(output);
}
}
/* ------------------------------------------------------------------------- */
media_t media_open(void)
{
struct media_data *media = bmalloc(sizeof(struct media_data));
da_init(media->outputs);
return media;
}
bool media_add_input(media_t media, media_input_t input)
{
media_output_t *outputs = media->outputs.array;
size_t i;
for (i = 0; i < media->outputs.num; i++) {
media_output_t output = outputs[i];
if (strcmp(output->info.format, input->info.format) == 0) {
da_push_back(output->connections, input);
return true;
}
}
return false;
}
void media_add_output(media_t media, media_output_t output)
{
da_push_back(media->outputs, output);
}
void media_remove_input(media_t media, media_input_t input)
{
if (!input->connection)
return;
da_erase_item(input->connection->connections, input);
}
void media_remove_output(media_t media, media_output_t output)
{
da_erase_item(media->outputs, output);
}
void media_close(media_t media)
{
if (media) {
da_free(media->outputs);
bfree(media);
}
}

View File

@@ -0,0 +1,77 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#ifndef MEDIA_IO_H
#define MEDIA_IO_H
/*
* Media input/output components used for connecting media outputs/inputs
* together. An input requests a connection to an output and the output
* sends frames to it through the callbacks in media_data_in structure.
*
* The id member should indicate the format/parameters used in text form.
*/
/* opaque data types */
struct media_input;
struct media_output;
struct media_data;
typedef struct media_input *media_input_t;
typedef struct media_output *media_output_t;
typedef struct media_data *media_t;
#include "../util/c99defs.h"
#include "video-io.h"
#include "audio-io.h"
#ifdef __cplusplus
extern "C" {
#endif
struct media_input_info {
const char *format;
void *obj;
void (*on_input)(void *obj, const void *data);
};
struct media_output_info {
const char *format;
void *obj;
bool (*connect)(void *obj, media_input_t input);
};
EXPORT media_input_t media_input_create(struct media_input_info *info);
EXPORT void media_input_destroy(media_input_t input);
EXPORT media_output_t media_output_create(struct media_output_info *info);
EXPORT void media_output_data(media_output_t out, const void *data);
EXPORT void media_output_destroy(media_output_t output);
EXPORT media_t media_open(void);
EXPORT bool media_add_input(media_t media, media_input_t input);
EXPORT void media_add_output(media_t media, media_output_t output);
EXPORT void media_remove_input(media_t media, media_input_t input);
EXPORT void media_remove_output(media_t media, media_output_t output);
EXPORT void media_close(media_t media);
#ifdef __cplusplus
}
#endif
#endif

194
libobs/media-io/video-io.c Normal file
View File

@@ -0,0 +1,194 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 <assert.h>
#include "../util/bmem.h"
#include "../util/platform.h"
#include "../util/threading.h"
#include "video-io.h"
struct video_output {
struct video_info info;
media_t media;
media_output_t output;
pthread_t thread;
pthread_mutex_t data_mutex;
event_t stop_event;
struct video_frame *cur_frame;
struct video_frame *next_frame;
event_t update_event;
uint64_t frame_time;
volatile uint64_t cur_video_time;
bool initialized;
};
/* ------------------------------------------------------------------------- */
static inline void video_swapframes(struct video_output *video)
{
pthread_mutex_lock(&video->data_mutex);
if (video->next_frame) {
video->cur_frame = video->next_frame;
video->next_frame = NULL;
}
pthread_mutex_unlock(&video->data_mutex);
}
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) {
/* wait half a frame, update frame */
os_sleepto_ns(cur_time += (video->frame_time/2));
video->cur_video_time = cur_time;
event_signal(&video->update_event);
/* wait another half a frame, swap and output frames */
os_sleepto_ns(cur_time += (video->frame_time/2));
video_swapframes(video);
if (video->cur_frame)
media_output_data(video->output, video->cur_frame);
}
return NULL;
}
/* ------------------------------------------------------------------------- */
static inline bool valid_video_params(struct video_info *info)
{
return info->height != 0 && info->width != 0 && info->fps_den != 0 &&
info->fps_num != 0 && info->format != NULL;
}
static inline bool vo_add_to_media(video_t video)
{
struct media_output_info oi;
oi.format = video->info.format;
oi.obj = video;
oi.connect = NULL;
video->output = media_output_create(&oi);
if (!video->output)
return false;
media_add_output(video->media, video->output);
return true;
}
int video_output_open(video_t *video, media_t media, struct video_info *info)
{
struct video_output *out;
if (!valid_video_params(info))
return VIDEO_OUTPUT_INVALIDPARAM;
out = bmalloc(sizeof(struct video_output));
memset(out, 0, sizeof(struct video_output));
memcpy(&out->info, info, sizeof(struct video_info));
out->frame_time = (uint64_t)(1000000000.0 * (double)info->fps_den /
(double)info->fps_num);
out->media = media;
out->initialized = false;
if (pthread_mutex_init(&out->data_mutex, NULL) != 0)
goto fail;
if (event_init(&out->stop_event, true) != 0)
goto fail;
if (event_init(&out->update_event, false) != 0)
goto fail;
if (!vo_add_to_media(out))
goto fail;
if (pthread_create(&out->thread, NULL, video_thread, out) != 0)
goto fail;
out->initialized = true;
*video = out;
return VIDEO_OUTPUT_SUCCESS;
fail:
video_output_close(out);
return VIDEO_OUTPUT_FAIL;
}
void video_output_frame(video_t video, struct video_frame *frame)
{
pthread_mutex_lock(&video->data_mutex);
video->next_frame = frame;
pthread_mutex_unlock(&video->data_mutex);
}
bool video_output_wait(video_t video)
{
event_wait(&video->update_event);
return event_try(&video->stop_event) == EAGAIN;
}
uint64_t video_getframetime(video_t video)
{
return video->frame_time;
}
uint64_t video_gettime(video_t video)
{
return video->cur_video_time;
}
void video_output_stop(video_t video)
{
void *thread_ret;
if (!video)
return;
if (video->initialized) {
event_signal(&video->stop_event);
pthread_join(video->thread, &thread_ret);
event_signal(&video->update_event);
}
}
void video_output_close(video_t video)
{
if (!video)
return;
video_output_stop(video);
if (video->output) {
media_remove_output(video->media, video->output);
media_output_destroy(video->output);
}
event_destroy(&video->update_event);
event_destroy(&video->stop_event);
pthread_mutex_destroy(&video->data_mutex);
bfree(video);
}

View File

@@ -0,0 +1,69 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#ifndef VIDEO_IO_H
#define VIDEO_IO_H
#include "../util/c99defs.h"
#include "media-io.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Base video output component. Use this to create an video output track
* for the media.
*/
struct video_output;
typedef struct video_output *video_t;
struct video_frame {
const void *data;
uint32_t row_size;
uint64_t timestamp;
};
struct video_info {
const char *name;
const char *format;
uint32_t fps_num; /* numerator */
uint32_t fps_den; /* denominator */
uint32_t width;
uint32_t height;
};
#define VIDEO_OUTPUT_SUCCESS 0
#define VIDEO_OUTPUT_INVALIDPARAM -1
#define VIDEO_OUTPUT_FAIL -2
EXPORT int video_output_open(video_t *video, media_t media,
struct video_info *info);
EXPORT void video_output_frame(video_t video, struct video_frame *frame);
EXPORT bool video_output_wait(video_t video);
EXPORT uint64_t video_getframetime(video_t video);
EXPORT uint64_t video_gettime(video_t video);
EXPORT void video_output_stop(video_t video);
EXPORT void video_output_close(video_t video);
#ifdef __cplusplus
}
#endif
#endif