整理代码

This commit is contained in:
蒲爽 2026-09-28 21:33:04 +08:00
commit c7b4e178ec
364 changed files with 59691 additions and 0 deletions

144
video/alsa/Input.cpp Normal file
View file

@ -0,0 +1,144 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "Input.h"
#include "Util.h"
#include "../core/System.h"
#include "Logger.h"
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
Input::Input(const std::string& name): Core::AbstractAudioInput(name)
{
setSoundCard(nullptr);
}
Input::~Input()
{
}
void Input::start()
{
_established = tryEstablishSoundCard();
run();
}
void Input::stop()
{
cancel();
if (_established)
{
_pcm.close();
_established = false;
}
}
void Input::onConfigChanged(ParameterNames& names)
{
if (!started())
return;
stop();
start();
AbstractAudioInput::onConfigChanged(names);
}
Core::Frame::Ptr Input::readFrame()
{
if (!_established)
_established = tryEstablishSoundCard();
if (!_established)
{
_traffic = 0;
return nullptr;
}
Core::Frame::Ptr pFrame = new Core::Frame;
pFrame->length = _linesize;
pFrame->timestamp = Core::System::timestamp();
int rc;
if (SND_PCM_ACCESS_RW_NONINTERLEAVED == _access)
{
uint8_t* ptrs[_channels];
for (int i = 0; i < _channels; i++)
{
pFrame->data[i] = new uint8_t[_linesize];
ptrs[i] = pFrame->data[i].get();
}
rc = _pcm.read(ptrs, _samples);
}
else
{
pFrame->data[0] = new uint8_t[_linesize];
uint8_t* ptr = pFrame->data[0].get();
rc = _pcm.read(ptr, _samples);
}
if (rc < 0)
{
_established = false;
_pcm.close();
_traffic = 0;
return nullptr;
}
_traffic++;
return pFrame;
}
bool Input::tryEstablishSoundCard()
{
auto pCard = getSoundCard();
if (pCard)
{
int rc = _pcm.open(pCard, SND_PCM_STREAM_CAPTURE);
if (rc >= 0)
{
const auto sampleRate = Util::getSuitableSampleRate(pCard, getSampleRate());
const auto access = Util::getSuitableAccess(pCard, sampleFormatIsPlanar(getSampleFormat()));
const auto format = Util::getSuitableSampleFormat(pCard, getSampleFormat());
const auto sampleFormat = Util::convertSampleFormat(format, access == SND_PCM_ACCESS_RW_INTERLEAVED);
logger().debug("%s: Suitable config found: %s %s %uHz", name(), std::string(snd_pcm_access_name(access)),
std::string(snd_pcm_format_name(format)), sampleRate);
rc = _pcm.config(access, format, pCard->info().channels, sampleRate, getFrameSize(),
sampleFormatBytesPerSample(sampleFormat));
if (rc >= 0)
{
if (pCard->info().channels == 1 && getChannelLayout() != Core::ChannelLayout::MONO)
setChannelLayout(Core::ChannelLayout::MONO);
setSampleRate(sampleRate);
setSampleFormat(sampleFormat);
_linesize = sampleFormatCalcLineSize(sampleFormat, getChannelLayout(), getFrameSize());
_channels = channelLayoutChannels(getChannelLayout());
_samples = getFrameSize();
_access = access;
serialCodeManager().increment();
return true;
}
_pcm.close();
}
}
return false;
}
}
}

53
video/alsa/Input.h Normal file
View file

@ -0,0 +1,53 @@
#ifndef C0535B0C_9BD8_4FDC_9429_8FEF7E58BFCE
#define C0535B0C_9BD8_4FDC_9429_8FEF7E58BFCE
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "../core/AbstractAudioInput.h"
#include "SoundCard.h"
#include "PCM.h"
#include "util/SimpleFactory.h"
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DECLARE
*******************************************************************************
*/
class Input: public Core::AbstractAudioInput, public ::Util::SimpleFactory<Input, const std::string&>
{
public:
using Ptr = Poco::AutoPtr<Input>;
public:
Input(const std::string& name);
~Input();
public:
CONFIGURABLE_DECLARE_PARAMETER(SoundCard, SoundCard::Ptr);
protected:
void start() override;
void stop() override;
void onConfigChanged(ParameterNames& names) override;
Core::Frame::Ptr readFrame() override;
bool tryEstablishSoundCard();
private:
PCM _pcm;
std::atomic<bool> _established;
int _linesize;
int _channels;
int _samples;
snd_pcm_access_t _access;
};
}
}
#endif

162
video/alsa/Output.cpp Normal file
View file

@ -0,0 +1,162 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "Output.h"
#include "PCM.h"
#include "SoundCard.h"
#include "Util.h"
#include "Logger.h"
#include "../core/System.h"
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
Output::Output(const std::string& arg): Core::AudioOutput("ALSA::Output(" + arg + ")")
{
auto pos = arg.find(':');
_soundCardID = (pos != std::string::npos) ? arg.substr(pos + 1) : arg;
}
Output::~Output()
{
}
void Output::initialize()
{
setSoundCardEstablished(tryEstablishSoundCard());
if (!getSoundCardEstablished())
runSearchTask();
}
void Output::deinitialize()
{
_searchTask.cancel();
if (getSoundCardEstablished())
_pcm.close();
}
void Output::onConfigChanged(ParameterNames& names)
{
}
void Output::writeFrame(Core::Frame::Ptr pFrame)
{
if (!getSoundCardEstablished())
return;
int rc;
if (SND_PCM_ACCESS_RW_NONINTERLEAVED == _access)
{
uint8_t* ptrs[_channels];
for (int i = 0; i < _channels; i++)
ptrs[i] = pFrame->data[i].get();
rc = _pcm.write(ptrs, _samples);
}
else
{
rc = _pcm.write(pFrame->data[0].get(), _samples);
}
if (rc < 0)
{
setSoundCardEstablished(false);
_pcm.close();
}
}
SoundCard::Ptr Output::getSoundCard()
{
auto cards = SoundCard::getSoundCards([this](SoundCard::Ptr pCard) -> bool
{ return (pCard->info().components == _soundCardID); });
if (cards.size() > 0)
return *(cards.begin());
return nullptr;
}
bool Output::tryEstablishSoundCard()
{
try
{
auto pCard = getSoundCard();
if (pCard)
{
int rc = _pcm.open(pCard, SND_PCM_STREAM_PLAYBACK);
if (rc >= 0)
{
const auto sampleRate = Util::getSuitableSampleRate(pCard, getSampleRate());
const auto access = Util::getSuitableAccess(pCard, sampleFormatIsPlanar(getSampleFormat()));
const auto format = Util::getSuitableSampleFormat(pCard, getSampleFormat());
const auto sampleFormat = Util::convertSampleFormat(format, access == SND_PCM_ACCESS_RW_INTERLEAVED);
logger().debug("%s: Suitable config found: %s %s %uHz", name(),
std::string(snd_pcm_access_name(access)), std::string(snd_pcm_format_name(format)),
sampleRate);
rc = _pcm.config(access, format, pCard->info().channels, sampleRate, getFrameSize(),
sampleFormatBytesPerSample(sampleFormat));
if (rc >= 0)
{
if (pCard->info().channels == 1 && getChannelLayout() != Core::ChannelLayout::MONO)
setChannelLayout(Core::ChannelLayout::MONO);
setSampleRate(sampleRate);
setSampleFormat(sampleFormat);
_channels = channelLayoutChannels(getChannelLayout());
_samples = getFrameSize();
_access = access;
serialCodeManager().increment();
return true;
}
_pcm.close();
}
}
}
catch (Poco::Exception& e)
{
logger().error("%s: %s", name(), e.displayText());
}
catch (std::exception& e)
{
logger().error("%s: %s", name(), std::string(e.what()));
}
return false;
}
void Output::runSearchTask()
{
if (_searchTask.isRunning())
return;
_searchTask.run(
[this](std::atomic<bool>& isCancelled) -> void
{
while (!isCancelled)
{
if (tryEstablishSoundCard())
{
setSoundCardEstablished(true);
break;
}
Poco::Thread::sleep(2000);
}
});
}
}
}

50
video/alsa/Output.h Normal file
View file

@ -0,0 +1,50 @@
#ifndef A7586F47_A0A8_4B55_9701_8E79240D6736
#define A7586F47_A0A8_4B55_9701_8E79240D6736
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "../core/AudioOutput.h"
#include "PCM.h"
#include "SoundCard.h"
#include "util/Task.h"
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DECLARE
*******************************************************************************
*/
class Output: public Core::AudioOutput
{
public:
Output(const std::string& arg);
~Output();
protected:
void initialize() override;
void deinitialize() override;
void onConfigChanged(ParameterNames& names) override;
void writeFrame(Core::Frame::Ptr pFrame) override;
SoundCard::Ptr getSoundCard();
bool tryEstablishSoundCard();
void runSearchTask();
PROPERTY_DECLARE(SoundCardEstablished, bool, false, protected, protected)
private:
std::string _soundCardID;
::Util::Task _searchTask;
PCM _pcm;
snd_pcm_access_t _access;
int _samples;
int _channels;
};
}
}
#endif

144
video/alsa/PCM.cpp Normal file
View file

@ -0,0 +1,144 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "PCM.h"
#include <alsa/asoundlib.h>
#include <iostream>
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
PCM::PCM()
{
}
PCM::~PCM()
{
}
int PCM::open(SoundCard::Ptr pSoundCard, snd_pcm_stream_t stream)
{
_stream = stream;
return snd_pcm_open((snd_pcm_t**)&_pPCM, pSoundCard->info().device.c_str(), stream, 0);
}
int PCM::close()
{
snd_pcm_drain((snd_pcm_t*)_pPCM);
snd_pcm_close((snd_pcm_t*)_pPCM);
return 0;
}
int PCM::config(snd_pcm_access_t access, snd_pcm_format_t format, int channels, int rate, int framesz, int samplesz)
{
#define __check_error(x) \
rc = x; \
if (rc < 0) \
{ \
std::cout << "Error: " << snd_strerror(rc) << "@" << #x << std::endl; \
goto out; \
}
snd_pcm_hw_params_t* hwParams = nullptr;
snd_pcm_sw_params_t* swParams = nullptr;
int rc;
__check_error(snd_pcm_hw_params_malloc(&hwParams));
__check_error(snd_pcm_hw_params_any((snd_pcm_t*)_pPCM, hwParams));
__check_error(snd_pcm_hw_params_set_access((snd_pcm_t*)_pPCM, hwParams, access));
__check_error(snd_pcm_hw_params_set_format((snd_pcm_t*)_pPCM, hwParams, format));
__check_error(snd_pcm_hw_params_set_channels((snd_pcm_t*)_pPCM, hwParams, channels));
__check_error(snd_pcm_hw_params_set_rate((snd_pcm_t*)_pPCM, hwParams, rate, 0));
__check_error(snd_pcm_hw_params_set_period_size((snd_pcm_t*)_pPCM, hwParams, framesz, 0));
__check_error(snd_pcm_hw_params_set_periods((snd_pcm_t*)_pPCM, hwParams, samplesz, 0));
__check_error(snd_pcm_hw_params_set_buffer_size((snd_pcm_t*)_pPCM, hwParams, samplesz * framesz));
__check_error(snd_pcm_hw_params((snd_pcm_t*)_pPCM, hwParams));
if (_stream == SND_PCM_STREAM_PLAYBACK)
{
__check_error(snd_pcm_sw_params_malloc(&swParams));
__check_error(snd_pcm_sw_params_current((snd_pcm_t*)_pPCM, swParams));
__check_error(snd_pcm_sw_params_set_avail_min((snd_pcm_t*)_pPCM, swParams, framesz));
__check_error(snd_pcm_sw_params_set_start_threshold((snd_pcm_t*)_pPCM, swParams, framesz * samplesz));
__check_error(snd_pcm_sw_params((snd_pcm_t*)_pPCM, swParams));
}
out:
if (hwParams)
snd_pcm_hw_params_free(hwParams);
if (swParams)
snd_pcm_sw_params_free(swParams);
return rc;
}
int PCM::write(const void* data, uint32_t framesz)
{
int rc = snd_pcm_writei((snd_pcm_t*)_pPCM, data, framesz);
if (rc < 0)
{
if (rc == -EPIPE)
rc = snd_pcm_prepare((snd_pcm_t*)_pPCM);
}
return rc;
}
int PCM::write(void** datas, uint32_t framesz)
{
int rc = snd_pcm_writen((snd_pcm_t*)_pPCM, datas, framesz);
if (rc < 0)
{
if (rc == -EPIPE)
rc = snd_pcm_prepare((snd_pcm_t*)_pPCM);
}
return rc;
}
int PCM::read(void* buffer, uint32_t framesz)
{
int rc = snd_pcm_readi((snd_pcm_t*)_pPCM, buffer, (snd_pcm_uframes_t)framesz);
if (rc < 0)
{
std::cout << "ALSA error: " << rc << " -> " << snd_strerror(rc) << "@" << framesz << std::endl;
if (rc == -EPIPE)
rc = snd_pcm_prepare((snd_pcm_t*)_pPCM);
}
return rc;
}
int PCM::read(void** buffers, uint32_t framesz)
{
int rc = snd_pcm_readn((snd_pcm_t*)_pPCM, buffers, (snd_pcm_uframes_t)framesz);
if (rc < 0)
{
std::cout << "ALSA error: " << rc << " -> " << snd_strerror(rc) << "@" << framesz << std::endl;
if (rc == -EPIPE)
rc = snd_pcm_prepare((snd_pcm_t*)_pPCM);
}
return rc;
}
}
}

43
video/alsa/PCM.h Normal file
View file

@ -0,0 +1,43 @@
#ifndef F1145346_5CCE_48F8_8398_073AFB8758C6
#define F1145346_5CCE_48F8_8398_073AFB8758C6
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "SoundCard.h"
#include <alsa/asoundlib.h>
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DECLARE
*******************************************************************************
*/
class PCM
{
public:
PCM();
~PCM();
public:
int open(SoundCard::Ptr pSoundCard, snd_pcm_stream_t st);
int close();
int config(snd_pcm_access_t access, snd_pcm_format_t format, int channels, int rate, int framesz, int samplesz);
int write(const void* data, uint32_t framesz);
int write(void** datas, uint32_t framesz);
int read(void* buffer, uint32_t framesz);
int read(void** buffers, uint32_t framesz);
private:
void* _pPCM;
snd_pcm_stream_t _stream;
};
}
}
#endif

124
video/alsa/SoundCard.cpp Normal file
View file

@ -0,0 +1,124 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "SoundCard.h"
#include <Poco/Format.h>
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
SoundCard::SoundCard(int index): _index(index)
{
initialize();
}
SoundCard::~SoundCard()
{
}
void SoundCard::initialize()
{
_info.device = Poco::format("hw:%d", _index);
int rc;
snd_ctl_t* handle;
if ((rc = snd_ctl_open(&handle, _info.device.c_str(), 0)) < 0)
throw Poco::InvalidAccessException("SoundCard: Cannot open device");
snd_ctl_card_info_t* info;
snd_ctl_card_info_alloca(&info);
if ((rc = snd_ctl_card_info(handle, info)) < 0)
throw Poco::InvalidAccessException("SoundCard: Cannot get card info");
_info.id = snd_ctl_card_info_get_id(info);
_info.name = snd_ctl_card_info_get_name(info);
_info.longname = snd_ctl_card_info_get_longname(info);
_info.driver = snd_ctl_card_info_get_driver(info);
_info.components = snd_ctl_card_info_get_components(info);
_info.mixername = snd_ctl_card_info_get_mixername(info);
snd_ctl_close(handle);
auto enumerateCapabilities = [](snd_pcm_t* pcm, Info& info)
{
snd_pcm_hw_params_t* params;
snd_pcm_hw_params_alloca(&params);
snd_pcm_hw_params_any(pcm, params);
for (int access = 0; access <= SND_PCM_ACCESS_LAST; access++)
info.access[access] = (snd_pcm_hw_params_test_access(pcm, params, (snd_pcm_access_t)access) == 0);
for (int format = 0; format <= SND_PCM_FORMAT_LAST; format++)
{
if (snd_pcm_hw_params_test_format(pcm, params, (snd_pcm_format_t)format) == 0)
info.formats.push_back((snd_pcm_format_t)format);
}
for (unsigned int rate = 1000; rate <= 384000; rate += 1000)
{
if (snd_pcm_hw_params_test_rate(pcm, params, rate, 0) == 0)
info.sampleRates.push_back(rate);
}
for (int channels = 1; channels <= 16; channels++)
{
if (snd_pcm_hw_params_test_channels(pcm, params, channels) == 0)
{
info.channels = channels;
break;
}
}
for (snd_pcm_uframes_t val = 16; val <= 1048576; val *= 2)
{
if (snd_pcm_hw_params_test_buffer_size(pcm, params, val) == 0)
info.bufferSizes.push_back(val);
}
};
snd_pcm_t* pcm;
int err = snd_pcm_open(&pcm, _info.device.c_str(), SND_PCM_STREAM_CAPTURE, 0);
if (err < 0)
_info.supportCapture = false;
else
{
_info.supportCapture = true;
enumerateCapabilities(pcm, _info);
snd_pcm_close(pcm);
}
err = snd_pcm_open(&pcm, _info.device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0)
_info.supportPlayback = false;
else
{
_info.supportPlayback = true;
if (!_info.supportCapture)
enumerateCapabilities(pcm, _info);
snd_pcm_close(pcm);
}
}
SoundCard::Info& SoundCard::info()
{
return _info;
}
SoundCard::SoundCards SoundCard::getSoundCards()
{
SoundCards cards;
int id = -1;
while (snd_card_next(&id), id >= 0)
cards.push_back(new SoundCard(id));
return cards;
}
}
}

83
video/alsa/SoundCard.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef A83739DB_6BC9_4B7C_8FA0_11DC60C05AA3
#define A83739DB_6BC9_4B7C_8FA0_11DC60C05AA3
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include <alsa/asoundlib.h>
#include <Poco/SharedPtr.h>
#include <string>
#include <vector>
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DECLARE
*******************************************************************************
*/
class SoundCard
{
public:
struct Info
{
std::string id;
std::string device;
std::string name;
std::string longname;
std::string driver;
std::string components;
std::string mixername;
bool access[SND_PCM_ACCESS_LAST + 1];
std::vector<snd_pcm_format_t> formats;
int channels;
std::vector<uint32_t> sampleRates;
std::vector<uint32_t> bufferSizes;
bool supportCapture;
bool supportPlayback;
bool operator==(const Info& other)
{
return components == other.components;
}
};
using Ptr = Poco::SharedPtr<SoundCard>;
using SoundCards = std::vector<Ptr>;
private:
SoundCard(int index);
void initialize();
public:
~SoundCard();
Info& info();
private:
int _index;
Info _info;
public:
static SoundCards getSoundCards();
template <class F> static SoundCards getSoundCards(F&& filter);
};
template <class F> inline SoundCard::SoundCards SoundCard::getSoundCards(F&& filter)
{
SoundCard::SoundCards cards;
for (auto& card : ALSA::SoundCard::getSoundCards())
{
if (filter(card))
cards.push_back(card);
}
return cards;
}
}
}
#endif

154
video/alsa/Util.cpp Normal file
View file

@ -0,0 +1,154 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "Util.h"
#include "Logger.h"
#include <cstdint>
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
uint32_t Util::getSuitableSampleRate(SoundCard::Ptr pCard, uint32_t target)
{
uint32_t suitable = target;
if (!pCard->info().sampleRates.empty())
{
for (auto sr : pCard->info().sampleRates)
{
if (sr % target == 0 || target % sr == 0)
{
suitable = sr;
goto out;
}
}
int minDiff = __INT32_MAX__;
for (auto sr : pCard->info().sampleRates)
{
int diff = std::abs(static_cast<int>(sr - target));
if (diff < minDiff || (diff == minDiff && sr > suitable))
{
minDiff = diff;
suitable = sr;
}
}
}
out:
return suitable;
}
snd_pcm_format_t Util::getSuitableSampleFormat(SoundCard::Ptr pCard, Core::SampleFormat refer)
{
auto target = convertSampleFormat(refer);
if (pCard->info().formats.empty())
return SND_PCM_FORMAT_S16_LE;
for (auto& fmt : pCard->info().formats)
{
if (fmt == (int)target)
return target;
}
target = *(pCard->info().formats.begin());
return target;
}
snd_pcm_access_t Util::getSuitableAccess(SoundCard::Ptr pCard, bool planar)
{
if (planar && (pCard->info().access[SND_PCM_ACCESS_RW_NONINTERLEAVED]))
return SND_PCM_ACCESS_RW_NONINTERLEAVED;
return SND_PCM_ACCESS_RW_INTERLEAVED;
}
snd_pcm_format_t Util::convertSampleFormat(Core::SampleFormat format)
{
switch (sampleFormatGetPlanarFormat(format))
{
case Core::SampleFormat::U8P:
return SND_PCM_FORMAT_U8;
case Core::SampleFormat::S16P:
return SND_PCM_FORMAT_S16_LE;
case Core::SampleFormat::S32P:
return SND_PCM_FORMAT_S32_LE;
case Core::SampleFormat::FLTP:
return SND_PCM_FORMAT_FLOAT_LE;
case Core::SampleFormat::DBLP:
return SND_PCM_FORMAT_FLOAT64_LE;
default:
return SND_PCM_FORMAT_S16_LE;
}
}
Core::SampleFormat Util::convertSampleFormat(snd_pcm_format_t format, bool interleaved)
{
Core::SampleFormat result;
switch (format)
{
case SND_PCM_FORMAT_U8:
result = Core::SampleFormat::U8P;
break;
case SND_PCM_FORMAT_S8:
result = Core::SampleFormat::U8P;
break;
case SND_PCM_FORMAT_S16_LE:
result = Core::SampleFormat::S16P;
break;
case SND_PCM_FORMAT_S16_BE:
result = Core::SampleFormat::S16P;
break;
case SND_PCM_FORMAT_S32_LE:
result = Core::SampleFormat::S32P;
break;
case SND_PCM_FORMAT_S32_BE:
result = Core::SampleFormat::S32P;
break;
case SND_PCM_FORMAT_FLOAT_LE:
result = Core::SampleFormat::FLTP;
break;
case SND_PCM_FORMAT_FLOAT_BE:
result = Core::SampleFormat::FLTP;
break;
case SND_PCM_FORMAT_FLOAT64_LE:
result = Core::SampleFormat::DBLP;
break;
case SND_PCM_FORMAT_FLOAT64_BE:
result = Core::SampleFormat::DBLP;
break;
case SND_PCM_FORMAT_SPECIAL:
case SND_PCM_FORMAT_S24_3LE:
case SND_PCM_FORMAT_S24_3BE:
case SND_PCM_FORMAT_U24_3LE:
case SND_PCM_FORMAT_U24_3BE:
case SND_PCM_FORMAT_S20_3LE:
case SND_PCM_FORMAT_S20_3BE:
case SND_PCM_FORMAT_U20_3LE:
case SND_PCM_FORMAT_U20_3BE:
case SND_PCM_FORMAT_S18_3LE:
case SND_PCM_FORMAT_S18_3BE:
case SND_PCM_FORMAT_U18_3LE:
default:
logger().warning(": Unsupported format: %s", std::string(snd_pcm_format_name(format)));
result = Core::SampleFormat::S32P;
break;
}
if (interleaved)
result = Core::sampleFormatGetPackedFormat(result);
return result;
}
}
}

31
video/alsa/Util.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef C0D42E11_A47F_4E62_820B_17AD3C7FE57C
#define C0D42E11_A47F_4E62_820B_17AD3C7FE57C
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "SoundCard.h"
#include "../core/SampleFormat.h"
namespace Video
{
namespace ALSA
{
/*
*******************************************************************************
* CLASS DECLARE
*******************************************************************************
*/
class Util
{
public:
static uint32_t getSuitableSampleRate(SoundCard::Ptr pCard, uint32_t target);
static snd_pcm_format_t getSuitableSampleFormat(SoundCard::Ptr pCard, Core::SampleFormat refer);
static snd_pcm_access_t getSuitableAccess(SoundCard::Ptr pCard, bool planar);
static snd_pcm_format_t convertSampleFormat(Core::SampleFormat format);
static Core::SampleFormat convertSampleFormat(snd_pcm_format_t format, bool interleaved);
};
}
}
#endif