Implement a few more audio options/functions
Implement a few audio options in to the user interface as well as a few inline audio functions in audio-io.h. Make it so ffmpeg plugin automatically converts to the desired format. Use regular interleaved float internally for audio instead of planar float.
This commit is contained in:
parent
0ff0d32731
commit
c232ebde15
@ -519,6 +519,14 @@ bool audio_output_connect(audio_t audio,
|
||||
audio->info.samples_per_sec;
|
||||
}
|
||||
|
||||
if (input.conversion.format == AUDIO_FORMAT_UNKNOWN)
|
||||
input.conversion.format = audio->info.format;
|
||||
if (input.conversion.speakers == SPEAKERS_UNKNOWN)
|
||||
input.conversion.speakers = audio->info.speakers;
|
||||
if (input.conversion.samples_per_sec == 0)
|
||||
input.conversion.samples_per_sec =
|
||||
audio->info.samples_per_sec;
|
||||
|
||||
success = audio_input_init(&input, audio);
|
||||
if (success)
|
||||
da_push_back(audio->inputs, &input);
|
||||
|
@ -127,7 +127,7 @@ static inline size_t get_audio_bytes_per_channel(enum audio_format type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline size_t is_audio_planar(enum audio_format type)
|
||||
static inline bool is_audio_planar(enum audio_format type)
|
||||
{
|
||||
switch (type) {
|
||||
case AUDIO_FORMAT_U8BIT:
|
||||
@ -149,10 +149,18 @@ static inline size_t is_audio_planar(enum audio_format type)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline size_t get_audio_planes(enum audio_format type,
|
||||
enum speaker_layout speakers)
|
||||
{
|
||||
return (is_audio_planar(type) ? get_audio_channels(speakers) : 1);
|
||||
}
|
||||
|
||||
static inline size_t get_audio_size(enum audio_format type,
|
||||
enum speaker_layout speakers, uint32_t frames)
|
||||
{
|
||||
return get_audio_channels(speakers) *
|
||||
bool planar = is_audio_planar(type);
|
||||
|
||||
return (planar ? 1 : get_audio_channels(speakers)) *
|
||||
get_audio_bytes_per_channel(type) *
|
||||
frames;
|
||||
}
|
||||
|
@ -2,6 +2,9 @@
|
||||
<ui version="4.0">
|
||||
<class>NameDialog</class>
|
||||
<widget class="QDialog" name="NameDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@ -10,12 +13,6 @@
|
||||
<height>102</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Dialog</string>
|
||||
</property>
|
||||
@ -31,6 +28,9 @@
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -77,7 +77,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="settingsPages">
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="generalPage">
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
@ -127,14 +127,66 @@
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="desktopAudioDevice1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Sample Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="sampleRate">
|
||||
<property name="currentText">
|
||||
<string notr="true">44.1khz</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>22.05khz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>44.1khz</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>48khz</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Channels:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="channelSetup">
|
||||
<property name="currentText">
|
||||
<string>Stereo</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Mono</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stereo</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -150,7 +202,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="desktopAudioDevice1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Desktop Audio Device 2:</string>
|
||||
@ -160,55 +219,75 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="desktopAudioDevice2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Mic/Aux Audio Device 1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="auxAudioDevice1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Mic/Aux Audio Device 2:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="auxAudioDevice2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Mic/Aux Audio Device 3:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="auxAudioDevice3">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="audioBufferingTime">
|
||||
<property name="minimum">
|
||||
<number>60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>700</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Audio Buffering Time (milliseconds):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="videoPage">
|
||||
|
@ -96,6 +96,11 @@ bool OBSApp::InitGlobalConfigDefaults()
|
||||
config_set_default_uint(globalConfig, "Video", "FPSDen", 1);
|
||||
config_set_default_uint(globalConfig, "Video", "FPSNS", 33333333);
|
||||
|
||||
config_set_default_uint(globalConfig, "Audio", "SampleRate", 44100);
|
||||
config_set_default_string(globalConfig, "Audio", "ChannelSetup",
|
||||
"Stereo");
|
||||
config_set_default_uint(globalConfig, "Audio", "BufferingTime", 700);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -313,13 +313,23 @@ bool OBSBasic::ResetVideo()
|
||||
|
||||
bool OBSBasic::ResetAudio()
|
||||
{
|
||||
/* TODO: load audio settings from config */
|
||||
struct audio_output_info ai;
|
||||
ai.name = "test";
|
||||
ai.samples_per_sec = 44100;
|
||||
ai.format = AUDIO_FORMAT_FLOAT_PLANAR;
|
||||
ai.speakers = SPEAKERS_STEREO;
|
||||
ai.buffer_ms = 700;
|
||||
ai.name = "Main Audio Track";
|
||||
ai.format = AUDIO_FORMAT_FLOAT;
|
||||
|
||||
ai.samples_per_sec = config_get_uint(GetGlobalConfig(), "Audio",
|
||||
"SampleRate");
|
||||
|
||||
const char *channelSetupStr = config_get_string(GetGlobalConfig(),
|
||||
"Audio", "ChannelSetup");
|
||||
|
||||
if (strcmp(channelSetupStr, "Mono") == 0)
|
||||
ai.speakers = SPEAKERS_MONO;
|
||||
else
|
||||
ai.speakers = SPEAKERS_STEREO;
|
||||
|
||||
ai.buffer_ms = config_get_uint(GetGlobalConfig(), "Audio",
|
||||
"BufferingTime");
|
||||
|
||||
return obs_reset_audio(&ai);
|
||||
}
|
||||
|
@ -178,6 +178,8 @@ static const size_t numVals = sizeof(vals)/sizeof(double);
|
||||
|
||||
void OBSBasicSettings::ResetDownscales(uint32_t cx, uint32_t cy)
|
||||
{
|
||||
ui->outputResolution->clear();
|
||||
|
||||
for (size_t idx = 0; idx < numVals; idx++) {
|
||||
uint32_t downscaleCX = uint32_t(double(cx) / vals[idx]);
|
||||
uint32_t downscaleCY = uint32_t(double(cy) / vals[idx]);
|
||||
@ -196,7 +198,6 @@ void OBSBasicSettings::LoadResolutionLists()
|
||||
vector<MonitorInfo> monitors;
|
||||
|
||||
ui->baseResolution->clear();
|
||||
ui->outputResolution->clear();
|
||||
|
||||
GetMonitors(monitors);
|
||||
|
||||
@ -270,14 +271,47 @@ void OBSBasicSettings::LoadVideoSettings()
|
||||
loading = false;
|
||||
}
|
||||
|
||||
void OBSBasicSettings::LoadAudioSettings()
|
||||
{
|
||||
uint32_t sampleRate = config_get_uint(GetGlobalConfig(), "Audio",
|
||||
"SampleRate");
|
||||
const char *speakers = config_get_string(GetGlobalConfig(), "Audio",
|
||||
"ChannelSetup");
|
||||
uint32_t bufferingTime = config_get_uint(GetGlobalConfig(), "Audio",
|
||||
"BufferingTime");
|
||||
|
||||
loading = true;
|
||||
|
||||
const char *str;
|
||||
if (sampleRate == 22050)
|
||||
str = "22.05khz";
|
||||
else if (sampleRate == 48000)
|
||||
str = "48khz";
|
||||
else
|
||||
str = "44.1khz";
|
||||
|
||||
int sampleRateIdx = ui->sampleRate->findText(str);
|
||||
if (sampleRateIdx != -1)
|
||||
ui->sampleRate->setCurrentIndex(sampleRateIdx);
|
||||
|
||||
if (strcmp(speakers, "Mono") == 0)
|
||||
ui->channelSetup->setCurrentIndex(0);
|
||||
else
|
||||
ui->channelSetup->setCurrentIndex(1);
|
||||
|
||||
ui->audioBufferingTime->setValue(bufferingTime);
|
||||
|
||||
loading = false;
|
||||
}
|
||||
|
||||
void OBSBasicSettings::LoadSettings(bool changedOnly)
|
||||
{
|
||||
if (!changedOnly || generalChanged)
|
||||
LoadGeneralSettings();
|
||||
//if (!changedOnly || outputChanged)
|
||||
// LoadOutputSettings();
|
||||
//if (!changedOnly || audioChanged)
|
||||
// LoadOutputSettings();
|
||||
if (!changedOnly || audioChanged)
|
||||
LoadAudioSettings();
|
||||
if (!changedOnly || videoChanged)
|
||||
LoadVideoSettings();
|
||||
}
|
||||
@ -331,14 +365,39 @@ void OBSBasicSettings::SaveVideoSettings()
|
||||
window->ResetVideo();
|
||||
}
|
||||
|
||||
void OBSBasicSettings::SaveAudioSettings()
|
||||
{
|
||||
QString sampleRateStr = ui->sampleRate->currentText();
|
||||
int channelSetupIdx = ui->channelSetup->currentIndex();
|
||||
int bufferingTime = ui->audioBufferingTime->value();
|
||||
|
||||
const char *channelSetup;
|
||||
if (channelSetupIdx == 0)
|
||||
channelSetup = "Mono";
|
||||
else
|
||||
channelSetup = "Stereo";
|
||||
|
||||
int sampleRate = 44100;
|
||||
if (sampleRateStr == "22.05khz")
|
||||
sampleRate = 22050;
|
||||
else if (sampleRateStr == "48khz")
|
||||
sampleRate = 48000;
|
||||
|
||||
config_set_uint(GetGlobalConfig(), "Audio", "SampleRate", sampleRate);
|
||||
config_set_string(GetGlobalConfig(), "Audio", "ChannelSetup",
|
||||
channelSetup);
|
||||
config_set_uint(GetGlobalConfig(), "Audio", "BufferingTime",
|
||||
bufferingTime);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::SaveSettings()
|
||||
{
|
||||
if (generalChanged)
|
||||
SaveGeneralSettings();
|
||||
//if (outputChanged)
|
||||
// SaveOutputSettings();
|
||||
//if (audioChanged)
|
||||
// SaveAudioSettings();
|
||||
if (audioChanged)
|
||||
SaveAudioSettings();
|
||||
if (videoChanged)
|
||||
SaveVideoSettings();
|
||||
|
||||
@ -430,6 +489,30 @@ void OBSBasicSettings::on_language_currentIndexChanged(int index)
|
||||
UNUSED_PARAMETER(index);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_sampleRate_currentIndexChanged(int index)
|
||||
{
|
||||
if (!loading)
|
||||
audioChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(index);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_channelSetup_currentIndexChanged(int index)
|
||||
{
|
||||
if (!loading)
|
||||
audioChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(index);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_audioBufferingTime_valueChanged(int value)
|
||||
{
|
||||
if (!loading)
|
||||
audioChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(value);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_renderer_currentIndexChanged(int index)
|
||||
{
|
||||
if (!loading) {
|
||||
@ -450,8 +533,14 @@ void OBSBasicSettings::on_fpsType_currentIndexChanged(int index)
|
||||
|
||||
void OBSBasicSettings::on_baseResolution_editTextChanged(const QString &text)
|
||||
{
|
||||
if (!loading && ValidResolutions(ui.get()))
|
||||
if (!loading && ValidResolutions(ui.get())) {
|
||||
QString baseResolution = ui->baseResolution->currentText();
|
||||
uint32_t cx, cy;
|
||||
|
||||
ConvertResText(QT_TO_UTF8(baseResolution), cx, cy);
|
||||
ResetDownscales(cx, cy);
|
||||
videoChanged = true;
|
||||
}
|
||||
|
||||
UNUSED_PARAMETER(text);
|
||||
}
|
||||
@ -463,3 +552,35 @@ void OBSBasicSettings::on_outputResolution_editTextChanged(const QString &text)
|
||||
|
||||
UNUSED_PARAMETER(text);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_fpsCommon_currentIndexChanged(int index)
|
||||
{
|
||||
if (!loading)
|
||||
videoChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(index);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_fpsInteger_valueChanged(int value)
|
||||
{
|
||||
if (!loading)
|
||||
videoChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(value);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_fpsNumerator_valueChanged(int value)
|
||||
{
|
||||
if (!loading)
|
||||
videoChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(value);
|
||||
}
|
||||
|
||||
void OBSBasicSettings::on_fpsDenominator_valueChanged(int value)
|
||||
{
|
||||
if (!loading)
|
||||
videoChanged = true;
|
||||
|
||||
UNUSED_PARAMETER(value);
|
||||
}
|
||||
|
@ -56,8 +56,9 @@ private:
|
||||
|
||||
void LoadGeneralSettings();
|
||||
//void LoadOutputSettings();
|
||||
//void LoadAudioSettings();
|
||||
void LoadAudioSettings();
|
||||
void LoadVideoSettings();
|
||||
void LoadSettings(bool changedOnly);
|
||||
|
||||
/* general */
|
||||
void LoadLanguageList();
|
||||
@ -67,11 +68,10 @@ private:
|
||||
void ResetDownscales(uint32_t cx, uint32_t cy);
|
||||
void LoadResolutionLists();
|
||||
void LoadFPSData();
|
||||
void LoadSettings(bool changedOnly);
|
||||
|
||||
void SaveGeneralSettings();
|
||||
//void SaveOutputSettings();
|
||||
//void SaveAudioSettings();
|
||||
void SaveAudioSettings();
|
||||
void SaveVideoSettings();
|
||||
void SaveSettings();
|
||||
|
||||
@ -81,10 +81,18 @@ private slots:
|
||||
|
||||
void on_language_currentIndexChanged(int index);
|
||||
|
||||
void on_sampleRate_currentIndexChanged(int index);
|
||||
void on_channelSetup_currentIndexChanged(int index);
|
||||
void on_audioBufferingTime_valueChanged(int index);
|
||||
|
||||
void on_renderer_currentIndexChanged(int index);
|
||||
void on_fpsType_currentIndexChanged(int index);
|
||||
void on_baseResolution_editTextChanged(const QString &text);
|
||||
void on_outputResolution_editTextChanged(const QString &text);
|
||||
void on_fpsCommon_currentIndexChanged(int index);
|
||||
void on_fpsInteger_valueChanged(int value);
|
||||
void on_fpsNumerator_valueChanged(int value);
|
||||
void on_fpsDenominator_valueChanged(int value);
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
|
||||
/* NOTE: much of this stuff is test stuff that was more or less copied from
|
||||
* the muxing.c ffmpeg example */
|
||||
|
||||
struct ffmpeg_data {
|
||||
AVStream *video;
|
||||
AVStream *audio;
|
||||
@ -34,6 +37,9 @@ struct ffmpeg_data {
|
||||
int frame_size;
|
||||
int total_frames;
|
||||
|
||||
enum audio_format audio_format;
|
||||
size_t audio_planes;
|
||||
size_t audio_size;
|
||||
struct circlebuf excess_frames[MAX_AV_PLANES];
|
||||
uint8_t *samples[MAX_AV_PLANES];
|
||||
AVFrame *aframe;
|
||||
@ -52,12 +58,6 @@ struct ffmpeg_output {
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* TODO: remove these later */
|
||||
#define SPS_TODO 44100
|
||||
|
||||
/* NOTE: much of this stuff is test stuff that was more or less copied from
|
||||
* the muxing.c ffmpeg example */
|
||||
|
||||
static inline enum AVPixelFormat obs_to_ffmpeg_video_format(
|
||||
enum video_format format)
|
||||
{
|
||||
@ -76,6 +76,24 @@ static inline enum AVPixelFormat obs_to_ffmpeg_video_format(
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static inline enum audio_format convert_ffmpeg_sample_format(
|
||||
enum AVSampleFormat format)
|
||||
{
|
||||
switch ((uint32_t)format) {
|
||||
case AV_SAMPLE_FMT_U8: return AUDIO_FORMAT_U8BIT;
|
||||
case AV_SAMPLE_FMT_S16: return AUDIO_FORMAT_16BIT;
|
||||
case AV_SAMPLE_FMT_S32: return AUDIO_FORMAT_32BIT;
|
||||
case AV_SAMPLE_FMT_FLT: return AUDIO_FORMAT_FLOAT;
|
||||
case AV_SAMPLE_FMT_U8P: return AUDIO_FORMAT_U8BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S16P: return AUDIO_FORMAT_16BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S32P: return AUDIO_FORMAT_32BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_FLTP: return AUDIO_FORMAT_FLOAT_PLANAR;
|
||||
}
|
||||
|
||||
/* shouldn't get here */
|
||||
return AUDIO_FORMAT_16BIT;
|
||||
}
|
||||
|
||||
static bool new_stream(struct ffmpeg_data *data, AVStream **stream,
|
||||
AVCodec **codec, enum AVCodecID id)
|
||||
{
|
||||
@ -237,6 +255,10 @@ static bool create_audio_stream(struct ffmpeg_data *data)
|
||||
context->sample_fmt = data->acodec->sample_fmts ?
|
||||
data->acodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||
|
||||
data->audio_format = convert_ffmpeg_sample_format(context->sample_fmt);
|
||||
data->audio_planes = get_audio_planes(data->audio_format, aoi.speakers);
|
||||
data->audio_size = get_audio_size(data->audio_format, aoi.speakers, 1);
|
||||
|
||||
if (data->output->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
context->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
@ -532,21 +554,19 @@ static void receive_audio(void *param, const struct audio_data *frame)
|
||||
struct ffmpeg_data *data = &output->ff_data;
|
||||
|
||||
AVCodecContext *context = data->audio->codec;
|
||||
size_t planes = audio_output_planes(obs_audio());
|
||||
size_t block_size = audio_output_blocksize(obs_audio());
|
||||
|
||||
size_t frame_size_bytes = (size_t)data->frame_size * block_size;
|
||||
size_t frame_size_bytes = (size_t)data->frame_size * data->audio_size;
|
||||
|
||||
for (size_t i = 0; i < planes; i++)
|
||||
for (size_t i = 0; i < data->audio_planes; i++)
|
||||
circlebuf_push_back(&data->excess_frames[i], frame->data[0],
|
||||
frame->frames * block_size);
|
||||
frame->frames * data->audio_size);
|
||||
|
||||
while (data->excess_frames[0].size >= frame_size_bytes) {
|
||||
for (size_t i = 0; i < planes; i++)
|
||||
for (size_t i = 0; i < data->audio_planes; i++)
|
||||
circlebuf_pop_front(&data->excess_frames[i],
|
||||
data->samples[i], frame_size_bytes);
|
||||
|
||||
encode_audio(data, context, block_size);
|
||||
encode_audio(data, context, data->audio_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,9 +595,7 @@ static bool ffmpeg_output_start(void *data)
|
||||
return false;
|
||||
|
||||
struct audio_convert_info aci = {
|
||||
.samples_per_sec = SPS_TODO,
|
||||
.format = AUDIO_FORMAT_FLOAT_PLANAR,
|
||||
.speakers = SPEAKERS_STEREO
|
||||
.format = output->ff_data.audio_format
|
||||
};
|
||||
|
||||
struct video_scale_info vsi = {
|
||||
|
@ -37,7 +37,7 @@ static void *sinewave_thread(void *pdata)
|
||||
if (cos_val > M_PI_X2)
|
||||
cos_val -= M_PI_X2;
|
||||
|
||||
double wave = cos(cos_val);
|
||||
double wave = cos(cos_val) * 0.5;
|
||||
bytes[i] = (uint8_t)((wave+1.0)*0.5 * 255.0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user