2013-09-30 19:37:13 -07:00
|
|
|
/******************************************************************************
|
|
|
|
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
|
2013-12-02 21:24:38 -08:00
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
2013-09-30 19:37:13 -07:00
|
|
|
(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/>.
|
|
|
|
******************************************************************************/
|
|
|
|
|
2013-10-14 04:21:15 -07:00
|
|
|
#pragma once
|
2013-09-30 19:37:13 -07:00
|
|
|
|
|
|
|
#include "util/c99defs.h"
|
|
|
|
#include "util/darray.h"
|
|
|
|
#include "util/dstr.h"
|
2013-10-24 00:57:55 -07:00
|
|
|
#include "util/threading.h"
|
2013-10-31 10:28:47 -07:00
|
|
|
#include "media-io/audio-resampler.h"
|
2013-12-26 22:10:15 -08:00
|
|
|
#include "callback/signal.h"
|
|
|
|
#include "callback/proc.h"
|
2013-09-30 19:37:13 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* ===========================================
|
|
|
|
* Sources
|
|
|
|
* ===========================================
|
|
|
|
*
|
|
|
|
* A source is literally a "source" of audio and/or video.
|
|
|
|
*
|
|
|
|
* A module with sources needs to export these functions:
|
|
|
|
* + enum_[type]
|
|
|
|
*
|
2014-01-31 23:49:50 -08:00
|
|
|
* [type] can be one of the following:
|
|
|
|
* + input
|
|
|
|
* + filter
|
|
|
|
* + transition
|
|
|
|
*
|
|
|
|
* input: A source used for directly playing video and/or sound.
|
|
|
|
* filter: A source that is used for filtering other sources, modifying
|
|
|
|
* the audio/video data before it is actually played.
|
|
|
|
* transition: A source used for transitioning between two different sources
|
|
|
|
* on screen.
|
|
|
|
*
|
2013-09-30 19:37:13 -07:00
|
|
|
* Each individual source is then exported by it's name. For example, a
|
|
|
|
* source named "mysource" would have the following exports:
|
2013-11-13 05:24:20 -08:00
|
|
|
* + mysource_getname
|
2013-09-30 19:37:13 -07:00
|
|
|
* + mysource_create
|
|
|
|
* + mysource_destroy
|
2014-01-17 05:24:34 -08:00
|
|
|
* + mysource_get_output_flags
|
2013-09-30 19:37:13 -07:00
|
|
|
*
|
|
|
|
* [and optionally]
|
|
|
|
* + mysource_update
|
2014-01-17 05:24:34 -08:00
|
|
|
* + mysource_activate
|
|
|
|
* + mysource_deactivate
|
2013-09-30 19:37:13 -07:00
|
|
|
* + mysource_video_tick
|
|
|
|
* + mysource_video_render
|
2014-01-17 05:24:34 -08:00
|
|
|
* + mysource_getwidth
|
|
|
|
* + mysource_getheight
|
2013-09-30 19:37:13 -07:00
|
|
|
* + mysource_getparam
|
|
|
|
* + mysource_setparam
|
2014-01-17 05:24:34 -08:00
|
|
|
* + mysource_filtervideo
|
|
|
|
* + mysource_filteraudio
|
2013-09-30 19:37:13 -07:00
|
|
|
*
|
|
|
|
* ===========================================
|
|
|
|
* Primary Exports
|
|
|
|
* ===========================================
|
2014-01-31 23:49:50 -08:00
|
|
|
* bool enum_[type](size_t idx, const char **name);
|
|
|
|
* idx: index of the enumeration.
|
|
|
|
* name: pointer to variable that receives the type of the source
|
2013-09-30 19:37:13 -07:00
|
|
|
* Return value: false when no more available.
|
|
|
|
*
|
|
|
|
* ===========================================
|
|
|
|
* Source Exports
|
|
|
|
* ===========================================
|
2013-11-13 05:24:20 -08:00
|
|
|
* const char *[name]_getname(const char *locale);
|
|
|
|
* Returns the full name of the source type (seen by the user).
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
2014-01-27 22:14:58 -08:00
|
|
|
* void *[name]_create(obs_data_t settings, obs_source_t source);
|
2013-09-30 19:37:13 -07:00
|
|
|
* Creates a source.
|
|
|
|
*
|
|
|
|
* settings: Settings of the source.
|
|
|
|
* source: pointer to main source
|
|
|
|
* Return value: Internal source pointer, or NULL if failed.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* void [name]_destroy(void *data);
|
|
|
|
* Destroys the source.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
2014-01-17 05:24:34 -08:00
|
|
|
* uint32_t [name]_get_output_flags(void *data);
|
2013-09-30 19:37:13 -07:00
|
|
|
* Returns a combination of one of the following values:
|
|
|
|
* + SOURCE_VIDEO: source has video
|
|
|
|
* + SOURCE_AUDIO: source has audio
|
Add preliminary output/encoder interface
- First, I redid the output interface for libobs. I feel like it's
going in a pretty good direction in terms of design.
Right now, the design is so that outputs and encoders are separate.
One or more outputs can connect to a specific encoder to receive its
data, or the output can connect directly to raw data from libobs
output itself, if the output doesn't want to use a designated encoder.
Data is received via callbacks set when you connect to the encoder or
raw output. Multiple outputs can receive the data from a single
encoder context if need be (such as for streaming to multiple channels
at once, and/or recording with the same data).
When an encoder is first connected to, it will connect to raw output,
and start encoding. Additional connections will receive that same
data being encoded as well after that. When the last encoder has
disconnected, it will stop encoding. If for some reason the encoder
needs to stop, it will use the callback with NULL to signal that
encoding has stopped. Some of these things may be subject to change
in the future, though it feels pretty good with this design so far.
Will have to see how well it works out in practice versus theory.
- Second, Started adding preliminary RTMP/x264 output plugin code.
To speed things up, I might just make a direct raw->FFmpeg output to
create a quick output plugin that we can start using for testing all
the subsystems.
2014-01-16 21:34:51 -08:00
|
|
|
* + SOURCE_ASYNC_VIDEO: video is sent asynchronously via RAM
|
|
|
|
* + SOURCE_DEFAULT_EFFECT: source uses default effect
|
|
|
|
* + SOURCE_YUV: source is in YUV color space
|
2013-09-30 19:37:13 -07:00
|
|
|
*
|
|
|
|
* ===========================================
|
|
|
|
* Optional Source Exports
|
|
|
|
* ===========================================
|
2014-01-27 22:14:58 -08:00
|
|
|
* void [name]_update(void *data, obs_data_t settings);
|
2014-01-17 05:24:34 -08:00
|
|
|
* Called to update the settings of the source.
|
2013-09-30 19:37:13 -07:00
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* void [name]_video_activate(void *data);
|
|
|
|
* Called when the source is being displayed.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* void [name]_video_deactivate(void *data);
|
|
|
|
* Called when the source is no longer being displayed.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* void [name]_video_tick(void *data, float seconds);
|
|
|
|
* Called each video frame with the time taken between the last and
|
|
|
|
* current frame, in seconds.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* void [name]_video_render(void *data);
|
|
|
|
* Called to render the source.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
2014-01-17 05:24:34 -08:00
|
|
|
* uint32_t [name]_getwidth(void *data);
|
|
|
|
* Returns the width of a source, or -1 for maximum width. If you render
|
|
|
|
* video, this is required.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* uint32_t [name]_getheight(void *data);
|
|
|
|
* Returns the height of a source, or -1 for maximum height. If you
|
|
|
|
* render video, this is required.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
2013-09-30 19:37:13 -07:00
|
|
|
* void [name]_getparam(void *data, const char *param, void *buf,
|
|
|
|
* size_t buf_size);
|
|
|
|
* Gets a source parameter value.
|
|
|
|
*
|
|
|
|
* param: Name of parameter.
|
|
|
|
* Return value: Value of parameter.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* void [name]_setparam(void *data, const char *param, const void *buf,
|
|
|
|
* size_t size);
|
|
|
|
* Sets a source parameter value.
|
|
|
|
*
|
|
|
|
* param: Name of parameter.
|
|
|
|
* val: Value of parameter to set.
|
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
2013-10-26 14:32:06 -07:00
|
|
|
* struct source_frame *[name]_filter_video(void *data,
|
|
|
|
* const struct source_frame *frame);
|
2013-09-30 19:37:13 -07:00
|
|
|
* Filters audio data. Used with audio filters.
|
|
|
|
*
|
|
|
|
* frame: Video frame data.
|
2013-10-24 00:57:55 -07:00
|
|
|
* returns: New video frame data (or NULL if pending)
|
2013-09-30 19:37:13 -07:00
|
|
|
*
|
|
|
|
* ---------------------------------------------------------
|
2013-10-31 10:28:47 -07:00
|
|
|
* struct filter_audio [name]_filter_audio(void *data,
|
|
|
|
* struct filter_audio *audio);
|
2013-09-30 19:37:13 -07:00
|
|
|
* Filters video data. Used with async video data.
|
|
|
|
*
|
|
|
|
* audio: Audio data.
|
2013-10-24 00:57:55 -07:00
|
|
|
* reutrns New audio data (or NULL if pending)
|
2013-09-30 19:37:13 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
struct obs_source;
|
|
|
|
|
|
|
|
struct source_info {
|
2013-12-20 16:23:19 -08:00
|
|
|
const char *id;
|
2013-09-30 19:37:13 -07:00
|
|
|
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
/* required implementations */
|
|
|
|
|
2013-11-13 05:24:20 -08:00
|
|
|
const char *(*getname)(const char *locale);
|
|
|
|
|
2014-01-27 22:14:58 -08:00
|
|
|
void *(*create)(obs_data_t settings, obs_source_t source);
|
2013-09-30 19:37:13 -07:00
|
|
|
void (*destroy)(void *data);
|
|
|
|
|
|
|
|
uint32_t (*get_output_flags)(void *data);
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
/* optional implementations */
|
|
|
|
|
2014-01-27 22:14:58 -08:00
|
|
|
void (*update)(void *data, obs_data_t settings);
|
2013-09-30 19:37:13 -07:00
|
|
|
|
|
|
|
void (*activate)(void *data);
|
|
|
|
void (*deactivate)(void *data);
|
|
|
|
|
|
|
|
void (*video_tick)(void *data, float seconds);
|
|
|
|
void (*video_render)(void *data);
|
2013-10-17 17:21:42 -07:00
|
|
|
uint32_t (*getwidth)(void *data);
|
|
|
|
uint32_t (*getheight)(void *data);
|
2013-09-30 19:37:13 -07:00
|
|
|
|
|
|
|
size_t (*getparam)(void *data, const char *param, void *data_out,
|
|
|
|
size_t buf_size);
|
|
|
|
void (*setparam)(void *data, const char *param, const void *data_in,
|
|
|
|
size_t size);
|
|
|
|
|
2013-10-26 14:32:06 -07:00
|
|
|
struct source_frame *(*filter_video)(void *data,
|
|
|
|
const struct source_frame *frame);
|
2013-10-31 10:28:47 -07:00
|
|
|
struct filtered_audio *(*filter_audio)(void *data,
|
|
|
|
struct filtered_audio *audio);
|
2013-09-30 19:37:13 -07:00
|
|
|
};
|
|
|
|
|
2013-10-24 00:57:55 -07:00
|
|
|
struct obs_source {
|
2013-11-20 14:00:16 -08:00
|
|
|
volatile int refs;
|
|
|
|
|
|
|
|
/* source-specific data */
|
2013-12-20 16:23:19 -08:00
|
|
|
char *name; /* user-defined name */
|
2013-12-20 18:35:12 -08:00
|
|
|
enum obs_source_type type;
|
2014-01-27 22:14:58 -08:00
|
|
|
obs_data_t settings;
|
2013-11-20 14:00:16 -08:00
|
|
|
void *data;
|
2013-10-24 00:57:55 -07:00
|
|
|
struct source_info callbacks;
|
2013-11-20 14:00:16 -08:00
|
|
|
|
2013-12-26 22:10:15 -08:00
|
|
|
signal_handler_t signals;
|
|
|
|
proc_handler_t procs;
|
|
|
|
|
2013-11-20 14:00:16 -08:00
|
|
|
/* used to indicate that the source has been removed and all
|
|
|
|
* references to it should be released (not exactly how I would prefer
|
|
|
|
* to handle things but it's the best option) */
|
|
|
|
bool removed;
|
2013-10-24 00:57:55 -07:00
|
|
|
|
2013-12-20 10:56:01 -08:00
|
|
|
/* timing (if video is present, is based upon video) */
|
2014-01-12 01:40:51 -08:00
|
|
|
volatile bool timing_set;
|
|
|
|
volatile uint64_t timing_adjust;
|
|
|
|
volatile int audio_reset_ref;
|
|
|
|
uint64_t next_audio_ts_min;
|
|
|
|
uint64_t last_frame_ts;
|
2013-10-26 14:32:06 -07:00
|
|
|
uint64_t last_sys_timestamp;
|
2013-10-24 00:57:55 -07:00
|
|
|
|
2013-12-20 10:56:01 -08:00
|
|
|
/* audio */
|
2013-10-31 10:28:47 -07:00
|
|
|
bool audio_failed;
|
|
|
|
struct resample_info sample_info;
|
|
|
|
audio_resampler_t resampler;
|
2013-10-24 00:57:55 -07:00
|
|
|
audio_line_t audio_line;
|
|
|
|
pthread_mutex_t audio_mutex;
|
2013-10-31 10:28:47 -07:00
|
|
|
struct filtered_audio audio_data;
|
|
|
|
size_t audio_storage_size;
|
2014-01-07 10:03:15 -08:00
|
|
|
float volume;
|
2013-10-24 00:57:55 -07:00
|
|
|
|
2013-12-20 10:56:01 -08:00
|
|
|
/* async video data */
|
|
|
|
texture_t output_texture;
|
|
|
|
DARRAY(struct source_frame*) video_frames;
|
|
|
|
pthread_mutex_t video_mutex;
|
|
|
|
|
2013-10-24 00:57:55 -07:00
|
|
|
/* filters */
|
|
|
|
struct obs_source *filter_parent;
|
|
|
|
struct obs_source *filter_target;
|
|
|
|
DARRAY(struct obs_source*) filters;
|
|
|
|
pthread_mutex_t filter_mutex;
|
|
|
|
bool rendering_filter;
|
2013-09-30 19:37:13 -07:00
|
|
|
};
|
|
|
|
|
2013-12-30 05:56:39 -08:00
|
|
|
extern bool load_source_info(void *module, const char *module_name,
|
2013-09-30 19:37:13 -07:00
|
|
|
const char *source_name, struct source_info *info);
|
|
|
|
|
2014-01-04 12:38:56 -08:00
|
|
|
bool obs_source_init_handlers(struct obs_source *source);
|
2014-01-28 17:41:24 -08:00
|
|
|
extern bool obs_source_init(struct obs_source *source,
|
2013-10-24 00:57:55 -07:00
|
|
|
const struct source_info *info);
|
2013-09-30 19:37:13 -07:00
|
|
|
|
2013-10-14 12:37:52 -07:00
|
|
|
extern void obs_source_activate(obs_source_t source);
|
|
|
|
extern void obs_source_deactivate(obs_source_t source);
|
|
|
|
extern void obs_source_video_tick(obs_source_t source, float seconds);
|