mirror of
https://github.com/mpromonet/v4l2rtspserver
synced 2024-11-02 03:40:13 +00:00
close ALSA when initialization failed
This commit is contained in:
parent
ccb7c3adba
commit
333cc4a39c
@ -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;
|
||||
}
|
||||
|
100
src/main.cpp
100
src/main.cpp
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user