close ALSA when initialization failed

This commit is contained in:
Michel Promonet 2017-05-14 19:22:17 +02:00
parent ccb7c3adba
commit 333cc4a39c
2 changed files with 92 additions and 65 deletions

View File

@ -46,10 +46,15 @@ class ALSACapture
return capture;
}
virtual ~ALSACapture()
{
this->close();
}
void close()
{
if (m_pcm != NULL)
{
snd_pcm_close (m_pcm);
m_pcm = NULL;
}
}
@ -70,37 +75,47 @@ class ALSACapture
// configure hw_params
else if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
LOG(ERROR) << "cannot allocate hardware parameter structure device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params_any (m_pcm, hw_params)) < 0) {
LOG(ERROR) << "cannot initialize hardware parameter structure device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params_set_access (m_pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
LOG(ERROR) << "cannot set access type device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params_set_format (m_pcm, hw_params, params.m_fmt)) < 0) {
LOG(ERROR) << "cannot set sample format device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params_set_rate_near (m_pcm, hw_params, &rate, 0)) < 0) {
LOG(ERROR) << "cannot set sample rate device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params_set_channels (m_pcm, hw_params, params.m_channels)) < 0) {
LOG(ERROR) << "cannot set channel count device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params (m_pcm, hw_params)) < 0) {
LOG(ERROR) << "cannot set parameters device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
// get buffer size
else if ((err = snd_pcm_get_params(m_pcm, &m_bufferSize, &m_periodSize)) < 0) {
LOG(ERROR) << "cannot get parameters device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
// start capture
else if ((err = snd_pcm_prepare (m_pcm)) < 0) {
LOG(ERROR) << "cannot prepare audio interface for use device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_start (m_pcm)) < 0) {
LOG(ERROR) << "cannot start audio interface for use device: " << params.m_devName << " error:" << snd_strerror (err);
this->close();
}
LOG(NOTICE) << "ALSA device: \"" << params.m_devName << "\" buffer_size:" << m_bufferSize << " period_size:" << m_periodSize;
@ -109,29 +124,33 @@ class ALSACapture
public:
virtual size_t read(char* buffer, size_t bufferSize)
{
size_t size = snd_pcm_readi (m_pcm, buffer, m_periodSize);
LOG(DEBUG) << "ALSA buffer size:" << m_bufferSize << " " << m_periodSize*m_params.m_channels << " " << size;
// swap if capture in not in network order
if (!snd_pcm_format_big_endian(m_params.m_fmt)) {
size_t size = 0;
if (m_pcm != 0)
{
size = snd_pcm_readi (m_pcm, buffer, m_periodSize);
LOG(DEBUG) << "ALSA buffer size:" << m_bufferSize << " " << m_periodSize*m_params.m_channels << " " << size;
int fmt_phys_width_bits = snd_pcm_format_physical_width(m_params.m_fmt);
int fmt_phys_width_bytes = fmt_phys_width_bits / 8;
for(unsigned int i = 0; i < size; i++){
char * ptr = &buffer[i * fmt_phys_width_bytes * m_params.m_channels];
// swap if capture in not in network order
if (!snd_pcm_format_big_endian(m_params.m_fmt)) {
for(unsigned int j = 0; j < m_params.m_channels; j++){
ptr += j * fmt_phys_width_bytes;
for (int k = 0; k < fmt_phys_width_bytes/2; k++) {
char byte = ptr[k];
ptr[k] = ptr[fmt_phys_width_bytes - 1 - k];
ptr[fmt_phys_width_bytes - 1 - k] = byte;
int fmt_phys_width_bits = snd_pcm_format_physical_width(m_params.m_fmt);
int fmt_phys_width_bytes = fmt_phys_width_bits / 8;
for(unsigned int i = 0; i < size; i++){
char * ptr = &buffer[i * fmt_phys_width_bytes * m_params.m_channels];
for(unsigned int j = 0; j < m_params.m_channels; j++){
ptr += j * fmt_phys_width_bytes;
for (int k = 0; k < fmt_phys_width_bytes/2; k++) {
char byte = ptr[k];
ptr[k] = ptr[fmt_phys_width_bytes - 1 - k];
ptr[fmt_phys_width_bytes - 1 - k] = byte;
}
}
}
}
}
}
}
return size*m_params.m_channels;
}

View File

@ -124,24 +124,27 @@ FramedSource* createFramedSource(UsageEnvironment* env, int format, DeviceCaptur
int addSession(RTSPServer* rtspServer, const std::string & sessionName, const std::list<ServerMediaSubsession*> & subSession)
{
int nbSubsession = 0;
UsageEnvironment& env(rtspServer->envir());
ServerMediaSession* sms = ServerMediaSession::createNew(env, sessionName.c_str());
if (sms != NULL)
if (subSession.empty() == false)
{
std::list<ServerMediaSubsession*>::const_iterator subIt;
for (subIt = subSession.begin(); subIt != subSession.end(); ++subIt)
UsageEnvironment& env(rtspServer->envir());
ServerMediaSession* sms = ServerMediaSession::createNew(env, sessionName.c_str());
if (sms != NULL)
{
sms->addSubsession(*subIt);
nbSubsession++;
}
rtspServer->addServerMediaSession(sms);
std::list<ServerMediaSubsession*>::const_iterator subIt;
for (subIt = subSession.begin(); subIt != subSession.end(); ++subIt)
{
sms->addSubsession(*subIt);
nbSubsession++;
}
rtspServer->addServerMediaSession(sms);
char* url = rtspServer->rtspURL(sms);
if (url != NULL)
{
LOG(NOTICE) << "Play this stream using the URL \"" << url << "\"";
delete[] url;
char* url = rtspServer->rtspURL(sms);
if (url != NULL)
{
LOG(NOTICE) << "Play this stream using the URL \"" << url << "\"";
delete[] url;
}
}
}
return nbSubsession;
@ -415,44 +418,47 @@ int main(int argc, char** argv)
baseUrl.append("/");
}
// Init video capture
LOG(NOTICE) << "Create V4L2 Source..." << videoDev;
StreamReplicator* videoReplicator = NULL;
std::string rtpFormat;
V4L2DeviceParameters param(videoDev.c_str(), format, width, height, fps, verbose);
V4l2Capture* videoCapture = V4l2Capture::create(param, ioTypeIn);
if (videoCapture)
if (!videoDev.empty())
{
format = videoCapture->getFormat();
int outfd = -1;
// Init video capture
LOG(NOTICE) << "Create V4L2 Source..." << videoDev;
if (!outputFile.empty())
V4L2DeviceParameters param(videoDev.c_str(), format, width, height, fps, verbose);
V4l2Capture* videoCapture = V4l2Capture::create(param, ioTypeIn);
if (videoCapture)
{
V4L2DeviceParameters outparam(outputFile.c_str(), videoCapture->getFormat(), videoCapture->getWidth(), videoCapture->getHeight(), 0,verbose);
out = V4l2Output::create(outparam, ioTypeOut);
if (out != NULL)
format = videoCapture->getFormat();
int outfd = -1;
if (!outputFile.empty())
{
outfd = out->getFd();
V4L2DeviceParameters outparam(outputFile.c_str(), videoCapture->getFormat(), videoCapture->getWidth(), videoCapture->getHeight(), 0,verbose);
out = V4l2Output::create(outparam, ioTypeOut);
if (out != NULL)
{
outfd = out->getFd();
}
}
}
LOG(NOTICE) << "Create Source ..." << videoDev;
rtpFormat.assign(getRtpFormat(format, muxTS));
FramedSource* videoSource = createFramedSource(env, videoCapture->getFormat(), new V4L2DeviceCapture<V4l2Capture>(videoCapture), outfd, queueSize, useThread, repeatConfig, muxTS);
if (videoSource == NULL)
{
LOG(FATAL) << "Unable to create source for device " << videoDev;
delete videoCapture;
}
else
{
// extend buffer size if needed
if (videoCapture->getBufferSize() > OutPacketBuffer::maxSize)
LOG(NOTICE) << "Create Source ..." << videoDev;
rtpFormat.assign(getRtpFormat(format, muxTS));
FramedSource* videoSource = createFramedSource(env, videoCapture->getFormat(), new V4L2DeviceCapture<V4l2Capture>(videoCapture), outfd, queueSize, useThread, repeatConfig, muxTS);
if (videoSource == NULL)
{
OutPacketBuffer::maxSize = videoCapture->getBufferSize();
LOG(FATAL) << "Unable to create source for device " << videoDev;
delete videoCapture;
}
else
{
// extend buffer size if needed
if (videoCapture->getBufferSize() > OutPacketBuffer::maxSize)
{
OutPacketBuffer::maxSize = videoCapture->getBufferSize();
}
videoReplicator = StreamReplicator::createNew(*env, videoSource, false);
}
videoReplicator = StreamReplicator::createNew(*env, videoSource, false);
}
}
@ -460,6 +466,9 @@ int main(int argc, char** argv)
StreamReplicator* audioReplicator = NULL;
if (!audioDev.empty())
{
// Init audio capture
LOG(NOTICE) << "Create ALSA Source..." << audioDev;
ALSACaptureParameters param(audioDev.c_str(), audioFmt, audioFreq, audioNbChannels, verbose);
ALSACapture* audioCapture = ALSACapture::createNew(param);
if (audioCapture)
@ -476,8 +485,7 @@ int main(int argc, char** argv)
if (audioCapture->getBufferSize() > OutPacketBuffer::maxSize)
{
OutPacketBuffer::maxSize = audioCapture->getBufferSize();
}
}
audioReplicator = StreamReplicator::createNew(*env, audioSource, false);
}
}