整理代码
This commit is contained in:
commit
c7b4e178ec
364 changed files with 59691 additions and 0 deletions
162
video/alsa/Output.cpp
Normal file
162
video/alsa/Output.cpp
Normal 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue