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
|
|
|
|
2014-02-14 14:13:36 -08:00
|
|
|
#include "media-io-defs.h"
|
2013-09-30 19:37:13 -07:00
|
|
|
#include "../util/c99defs.h"
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Base audio output component. Use this to create an audio output track
|
|
|
|
* for the media.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct audio_output;
|
2013-10-24 00:57:55 -07:00
|
|
|
struct audio_line;
|
2013-09-30 19:37:13 -07:00
|
|
|
typedef struct audio_output *audio_t;
|
2013-10-24 00:57:55 -07:00
|
|
|
typedef struct audio_line *audio_line_t;
|
2013-09-30 19:37:13 -07:00
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
enum audio_format {
|
2013-09-30 19:37:13 -07:00
|
|
|
AUDIO_FORMAT_UNKNOWN,
|
2014-02-07 02:03:54 -08:00
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
AUDIO_FORMAT_U8BIT,
|
2013-09-30 19:37:13 -07:00
|
|
|
AUDIO_FORMAT_16BIT,
|
|
|
|
AUDIO_FORMAT_32BIT,
|
|
|
|
AUDIO_FORMAT_FLOAT,
|
2014-02-07 02:03:54 -08:00
|
|
|
|
|
|
|
AUDIO_FORMAT_U8BIT_PLANAR,
|
|
|
|
AUDIO_FORMAT_16BIT_PLANAR,
|
|
|
|
AUDIO_FORMAT_32BIT_PLANAR,
|
|
|
|
AUDIO_FORMAT_FLOAT_PLANAR,
|
2013-09-30 19:37:13 -07:00
|
|
|
};
|
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
enum speaker_layout {
|
2013-09-30 19:37:13 -07:00
|
|
|
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 {
|
2014-02-14 14:13:36 -08:00
|
|
|
const uint8_t *data[MAX_AV_PLANES];
|
2013-10-30 17:07:01 -07:00
|
|
|
uint32_t frames;
|
|
|
|
uint64_t timestamp;
|
2014-01-07 10:03:15 -08:00
|
|
|
float volume;
|
2013-09-30 19:37:13 -07:00
|
|
|
};
|
|
|
|
|
Simplify media i/o interfaces
Completely revamped the entire media i/o data and handlers. The
original idea was to have a system that would have connecting media
inputs and outputs, but at a certain point I realized that this was an
unnecessary complexity for what we wanted to do. (Also, it reminded me
of directshow filters, and I HATE directshow with a passion, and
wouldn't wish it upon my greatest enemy)
Now, audio/video outputs are connected to directly, with better callback
handlers, and will eventually have the ability to automatically handle
conversions such as 4:4:4 to 4:2:0 when connecting to an input that uses
them. Doing this will allow the video/audio i/o handlers to also
prevent duplicate conversion, as well as make it easier/simple to use.
My true goal for this is to make output and encoder plugins as simple to
create as possible. I want to be able to be able to create an output
plugin with almost no real hassle of having to worry about image
conversions, media inputs/outputs, etc. A plugin developer shouldn't
have to handle that sort of stuff when he/she doesn't really need to.
Plugins will be able to simply create a callback via obs_video() and/or
obs_audio(), and they will automatically receive the audio/video data in
the formats requested via a simple callback, without needing to do
almost anything else at all.
2014-01-14 00:58:47 -08:00
|
|
|
struct audio_output_info {
|
2013-10-30 17:07:01 -07:00
|
|
|
const char *name;
|
2013-09-30 19:37:13 -07:00
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
uint32_t samples_per_sec;
|
2013-10-31 10:28:47 -07:00
|
|
|
enum audio_format format;
|
2013-10-30 17:07:01 -07:00
|
|
|
enum speaker_layout speakers;
|
2014-01-09 18:08:20 -08:00
|
|
|
uint64_t buffer_ms;
|
2013-09-30 19:37:13 -07:00
|
|
|
};
|
|
|
|
|
2014-01-19 02:16:41 -08:00
|
|
|
struct audio_convert_info {
|
Simplify media i/o interfaces
Completely revamped the entire media i/o data and handlers. The
original idea was to have a system that would have connecting media
inputs and outputs, but at a certain point I realized that this was an
unnecessary complexity for what we wanted to do. (Also, it reminded me
of directshow filters, and I HATE directshow with a passion, and
wouldn't wish it upon my greatest enemy)
Now, audio/video outputs are connected to directly, with better callback
handlers, and will eventually have the ability to automatically handle
conversions such as 4:4:4 to 4:2:0 when connecting to an input that uses
them. Doing this will allow the video/audio i/o handlers to also
prevent duplicate conversion, as well as make it easier/simple to use.
My true goal for this is to make output and encoder plugins as simple to
create as possible. I want to be able to be able to create an output
plugin with almost no real hassle of having to worry about image
conversions, media inputs/outputs, etc. A plugin developer shouldn't
have to handle that sort of stuff when he/she doesn't really need to.
Plugins will be able to simply create a callback via obs_video() and/or
obs_audio(), and they will automatically receive the audio/video data in
the formats requested via a simple callback, without needing to do
almost anything else at all.
2014-01-14 00:58:47 -08:00
|
|
|
uint32_t samples_per_sec;
|
|
|
|
enum audio_format format;
|
|
|
|
enum speaker_layout speakers;
|
|
|
|
};
|
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
static inline uint32_t get_audio_channels(enum speaker_layout speakers)
|
2013-10-24 00:57:55 -07:00
|
|
|
{
|
|
|
|
switch (speakers) {
|
|
|
|
case SPEAKERS_MONO: return 1;
|
|
|
|
case SPEAKERS_STEREO: return 2;
|
|
|
|
case SPEAKERS_2POINT1: return 3;
|
|
|
|
case SPEAKERS_SURROUND:
|
|
|
|
case SPEAKERS_QUAD: return 4;
|
|
|
|
case SPEAKERS_4POINT1: return 5;
|
|
|
|
case SPEAKERS_5POINT1:
|
|
|
|
case SPEAKERS_5POINT1_SURROUND: return 6;
|
|
|
|
case SPEAKERS_7POINT1: return 8;
|
|
|
|
case SPEAKERS_7POINT1_SURROUND: return 8;
|
|
|
|
case SPEAKERS_UNKNOWN: return 0;
|
|
|
|
}
|
2013-10-24 01:29:06 -07:00
|
|
|
|
|
|
|
return 0;
|
2013-10-24 00:57:55 -07:00
|
|
|
}
|
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
static inline size_t get_audio_bytes_per_channel(enum audio_format type)
|
2013-10-24 00:57:55 -07:00
|
|
|
{
|
|
|
|
switch (type) {
|
2014-02-07 02:03:54 -08:00
|
|
|
case AUDIO_FORMAT_U8BIT:
|
|
|
|
case AUDIO_FORMAT_U8BIT_PLANAR:
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case AUDIO_FORMAT_16BIT:
|
|
|
|
case AUDIO_FORMAT_16BIT_PLANAR:
|
|
|
|
return 2;
|
|
|
|
|
2013-10-24 00:57:55 -07:00
|
|
|
case AUDIO_FORMAT_FLOAT:
|
2014-02-07 02:03:54 -08:00
|
|
|
case AUDIO_FORMAT_FLOAT_PLANAR:
|
|
|
|
case AUDIO_FORMAT_32BIT:
|
|
|
|
case AUDIO_FORMAT_32BIT_PLANAR:
|
|
|
|
return 4;
|
|
|
|
|
|
|
|
case AUDIO_FORMAT_UNKNOWN:
|
|
|
|
return 0;
|
2013-10-24 00:57:55 -07:00
|
|
|
}
|
2013-10-24 01:29:06 -07:00
|
|
|
|
|
|
|
return 0;
|
2013-10-24 00:57:55 -07:00
|
|
|
}
|
|
|
|
|
2014-02-07 02:03:54 -08:00
|
|
|
static inline size_t is_audio_planar(enum audio_format type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case AUDIO_FORMAT_U8BIT:
|
|
|
|
case AUDIO_FORMAT_16BIT:
|
|
|
|
case AUDIO_FORMAT_32BIT:
|
|
|
|
case AUDIO_FORMAT_FLOAT:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case AUDIO_FORMAT_U8BIT_PLANAR:
|
|
|
|
case AUDIO_FORMAT_FLOAT_PLANAR:
|
|
|
|
case AUDIO_FORMAT_16BIT_PLANAR:
|
|
|
|
case AUDIO_FORMAT_32BIT_PLANAR:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case AUDIO_FORMAT_UNKNOWN:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-10-30 17:07:01 -07:00
|
|
|
static inline size_t get_audio_size(enum audio_format type,
|
|
|
|
enum speaker_layout speakers, uint32_t frames)
|
2013-10-24 00:57:55 -07:00
|
|
|
{
|
|
|
|
return get_audio_channels(speakers) *
|
|
|
|
get_audio_bytes_per_channel(type) *
|
|
|
|
frames;
|
|
|
|
}
|
|
|
|
|
2013-09-30 19:37:13 -07:00
|
|
|
#define AUDIO_OUTPUT_SUCCESS 0
|
|
|
|
#define AUDIO_OUTPUT_INVALIDPARAM -1
|
|
|
|
#define AUDIO_OUTPUT_FAIL -2
|
|
|
|
|
Simplify media i/o interfaces
Completely revamped the entire media i/o data and handlers. The
original idea was to have a system that would have connecting media
inputs and outputs, but at a certain point I realized that this was an
unnecessary complexity for what we wanted to do. (Also, it reminded me
of directshow filters, and I HATE directshow with a passion, and
wouldn't wish it upon my greatest enemy)
Now, audio/video outputs are connected to directly, with better callback
handlers, and will eventually have the ability to automatically handle
conversions such as 4:4:4 to 4:2:0 when connecting to an input that uses
them. Doing this will allow the video/audio i/o handlers to also
prevent duplicate conversion, as well as make it easier/simple to use.
My true goal for this is to make output and encoder plugins as simple to
create as possible. I want to be able to be able to create an output
plugin with almost no real hassle of having to worry about image
conversions, media inputs/outputs, etc. A plugin developer shouldn't
have to handle that sort of stuff when he/she doesn't really need to.
Plugins will be able to simply create a callback via obs_video() and/or
obs_audio(), and they will automatically receive the audio/video data in
the formats requested via a simple callback, without needing to do
almost anything else at all.
2014-01-14 00:58:47 -08:00
|
|
|
EXPORT int audio_output_open(audio_t *audio, struct audio_output_info *info);
|
2013-09-30 19:37:13 -07:00
|
|
|
EXPORT void audio_output_close(audio_t audio);
|
|
|
|
|
2014-02-18 12:37:56 -08:00
|
|
|
EXPORT bool audio_output_connect(audio_t video,
|
2014-01-19 02:16:41 -08:00
|
|
|
struct audio_convert_info *conversion,
|
Simplify media i/o interfaces
Completely revamped the entire media i/o data and handlers. The
original idea was to have a system that would have connecting media
inputs and outputs, but at a certain point I realized that this was an
unnecessary complexity for what we wanted to do. (Also, it reminded me
of directshow filters, and I HATE directshow with a passion, and
wouldn't wish it upon my greatest enemy)
Now, audio/video outputs are connected to directly, with better callback
handlers, and will eventually have the ability to automatically handle
conversions such as 4:4:4 to 4:2:0 when connecting to an input that uses
them. Doing this will allow the video/audio i/o handlers to also
prevent duplicate conversion, as well as make it easier/simple to use.
My true goal for this is to make output and encoder plugins as simple to
create as possible. I want to be able to be able to create an output
plugin with almost no real hassle of having to worry about image
conversions, media inputs/outputs, etc. A plugin developer shouldn't
have to handle that sort of stuff when he/she doesn't really need to.
Plugins will be able to simply create a callback via obs_video() and/or
obs_audio(), and they will automatically receive the audio/video data in
the formats requested via a simple callback, without needing to do
almost anything else at all.
2014-01-14 00:58:47 -08:00
|
|
|
void (*callback)(void *param, const struct audio_data *data),
|
|
|
|
void *param);
|
|
|
|
EXPORT void audio_output_disconnect(audio_t video,
|
|
|
|
void (*callback)(void *param, const struct audio_data *data),
|
|
|
|
void *param);
|
|
|
|
|
|
|
|
EXPORT size_t audio_output_blocksize(audio_t audio);
|
2014-02-07 02:03:54 -08:00
|
|
|
EXPORT size_t audio_output_planes(audio_t audio);
|
|
|
|
EXPORT size_t audio_output_channels(audio_t audio);
|
Simplify media i/o interfaces
Completely revamped the entire media i/o data and handlers. The
original idea was to have a system that would have connecting media
inputs and outputs, but at a certain point I realized that this was an
unnecessary complexity for what we wanted to do. (Also, it reminded me
of directshow filters, and I HATE directshow with a passion, and
wouldn't wish it upon my greatest enemy)
Now, audio/video outputs are connected to directly, with better callback
handlers, and will eventually have the ability to automatically handle
conversions such as 4:4:4 to 4:2:0 when connecting to an input that uses
them. Doing this will allow the video/audio i/o handlers to also
prevent duplicate conversion, as well as make it easier/simple to use.
My true goal for this is to make output and encoder plugins as simple to
create as possible. I want to be able to be able to create an output
plugin with almost no real hassle of having to worry about image
conversions, media inputs/outputs, etc. A plugin developer shouldn't
have to handle that sort of stuff when he/she doesn't really need to.
Plugins will be able to simply create a callback via obs_video() and/or
obs_audio(), and they will automatically receive the audio/video data in
the formats requested via a simple callback, without needing to do
almost anything else at all.
2014-01-14 00:58:47 -08:00
|
|
|
EXPORT const struct audio_output_info *audio_output_getinfo(audio_t audio);
|
|
|
|
|
|
|
|
EXPORT audio_line_t audio_output_createline(audio_t audio, const char *name);
|
2013-10-24 00:57:55 -07:00
|
|
|
EXPORT void audio_line_destroy(audio_line_t line);
|
|
|
|
EXPORT void audio_line_output(audio_line_t line, const struct audio_data *data);
|
|
|
|
|
2013-09-30 19:37:13 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|