整理代码

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

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);
}
});
}
}
}