allow several audio format try

pull/92/merge
Michel Promonet 6 years ago
parent b3178a061c
commit 83039d9b7f

@ -14,16 +14,20 @@
#ifndef ALSA_CAPTURE
#define ALSA_CAPTURE
#include <list>
#include <alsa/asoundlib.h>
#include "logger.h"
struct ALSACaptureParameters
{
ALSACaptureParameters(const char* devname, snd_pcm_format_t fmt, unsigned int sampleRate, unsigned int channels, int verbose) :
m_devName(devname), m_fmt(fmt), m_sampleRate(sampleRate), m_channels(channels), m_verbose(verbose) {};
ALSACaptureParameters(const char* devname, const std::list<snd_pcm_format_t> & formatList, unsigned int sampleRate, unsigned int channels, int verbose) :
m_devName(devname), m_formatList(formatList), m_sampleRate(sampleRate), m_channels(channels), m_verbose(verbose) {
}
std::string m_devName;
snd_pcm_format_t m_fmt;
std::list<snd_pcm_format_t> m_formatList;
unsigned int m_sampleRate;
unsigned int m_channels;
int m_verbose;
@ -38,6 +42,7 @@ class ALSACapture
protected:
ALSACapture(const ALSACaptureParameters & params);
int configureFormat(snd_pcm_hw_params_t *hw_params);
public:
virtual size_t read(char* buffer, size_t bufferSize);
@ -55,6 +60,7 @@ class ALSACapture
unsigned long m_bufferSize;
unsigned long m_periodSize;
ALSACaptureParameters m_params;
snd_pcm_format_t m_fmt;
};
#endif

@ -69,8 +69,7 @@ ALSACapture::ALSACapture(const ALSACaptureParameters & params) : m_pcm(NULL), m_
LOG(ERROR) << "cannot set access type device: " << m_params.m_devName << " error:" << snd_strerror (err);
this->close();
}
else if ((err = snd_pcm_hw_params_set_format (m_pcm, hw_params, m_params.m_fmt)) < 0) {
LOG(ERROR) << "cannot set sample format device: " << m_params.m_devName << " error:" << snd_strerror (err);
else if (this->configureFormat(hw_params) < 0) {
this->close();
}
else if ((err = snd_pcm_hw_params_set_rate_near (m_pcm, hw_params, &m_params.m_sampleRate, 0)) < 0) {
@ -105,13 +104,31 @@ ALSACapture::ALSACapture(const ALSACaptureParameters & params) : m_pcm(NULL), m_
LOG(NOTICE) << "ALSA device: \"" << m_params.m_devName << "\" buffer_size:" << m_bufferSize << " period_size:" << m_periodSize << " rate:" << m_params.m_sampleRate;
}
int ALSACapture::configureFormat(snd_pcm_hw_params_t *hw_params) {
// try to set format, widht, height
std::list<snd_pcm_format_t>::iterator it;
for (it = m_params.m_formatList.begin(); it != m_params.m_formatList.end(); ++it) {
snd_pcm_format_t format = *it;
int err = snd_pcm_hw_params_set_format (m_pcm, hw_params, format);
if (err < 0) {
LOG(NOTICE) << "cannot set sample format device: " << m_params.m_devName << " to:" << format << " error:" << snd_strerror (err);
} else {
LOG(NOTICE) << "set sample format device: " << m_params.m_devName << " to:" << format << " ok";
m_fmt = format;
return 0;
}
}
return -1;
}
size_t ALSACapture::read(char* buffer, size_t bufferSize)
{
size_t size = 0;
int fmt_phys_width_bytes = 0;
if (m_pcm != 0)
{
int fmt_phys_width_bits = snd_pcm_format_physical_width(m_params.m_fmt);
int fmt_phys_width_bits = snd_pcm_format_physical_width(m_fmt);
fmt_phys_width_bytes = fmt_phys_width_bits / 8;
snd_pcm_sframes_t ret = snd_pcm_readi (m_pcm, buffer, m_periodSize*fmt_phys_width_bytes);
@ -120,7 +137,7 @@ size_t ALSACapture::read(char* buffer, size_t bufferSize)
size = ret;
// swap if capture in not in network order
if (!snd_pcm_format_big_endian(m_params.m_fmt)) {
if (!snd_pcm_format_big_endian(m_fmt)) {
for(unsigned int i = 0; i < size; i++){
char * ptr = &buffer[i * fmt_phys_width_bytes * m_params.m_channels];

@ -370,8 +370,9 @@ std::string getV4l2Alsa(const std::string& v4l2device) {
int main(int argc, char** argv)
{
// default parameters
const char *dev_name = "/dev/video0";
std::list<unsigned int> formatList;
const char *dev_name = "/dev/video0,/dev/video0";
unsigned int format = ~0;
std::list<unsigned int> videoformatList;
int width = 0;
int height = 0;
int queueSize = 10;
@ -396,9 +397,9 @@ int main(int argc, char** argv)
std::list<std::string> userPasswordList;
int audioFreq = 44100;
int audioNbChannels = 2;
unsigned int format = ~0;
#ifdef HAVE_ALSA
snd_pcm_format_t audioFmt = SND_PCM_FORMAT_S16_BE;
std::list<snd_pcm_format_t> audioFmtList;
snd_pcm_format_t audioFmt = SND_PCM_FORMAT_UNKNOWN;
#endif
const char* defaultPort = getenv("PORT");
if (defaultPort != NULL) {
@ -435,7 +436,7 @@ int main(int argc, char** argv)
case 'r': ioTypeIn = V4l2Access::IOTYPE_READWRITE; break;
case 'w': ioTypeOut = V4l2Access::IOTYPE_READWRITE; break;
case 's': useThread = false; break;
case 'f': format = decodeVideoFormat(optarg); if (format) {formatList.push_back(format);}; break;
case 'f': format = decodeVideoFormat(optarg); if (format) {videoformatList.push_back(format);}; break;
case 'F': fps = atoi(optarg); break;
case 'W': width = atoi(optarg); break;
case 'H': height = atoi(optarg); break;
@ -444,7 +445,7 @@ int main(int argc, char** argv)
#ifdef HAVE_ALSA
case 'A': audioFreq = atoi(optarg); break;
case 'C': audioNbChannels = atoi(optarg); break;
case 'a': audioFmt = decodeAudioFormat(optarg); break;
case 'a': audioFmt = decodeAudioFormat(optarg); if (audioFmt != SND_PCM_FORMAT_UNKNOWN) {audioFmtList.push_back(audioFmt);} ; break;
#endif
// version
@ -512,11 +513,18 @@ int main(int argc, char** argv)
}
// default format tries
if ((formatList.empty()) && (format!=0)) {
std::cout << "use default format H264/MJPEG" << std::endl;
formatList.push_back(V4L2_PIX_FMT_H264);
formatList.push_back(V4L2_PIX_FMT_MJPEG);
if ((videoformatList.empty()) && (format!=0)) {
videoformatList.push_back(V4L2_PIX_FMT_H264);
videoformatList.push_back(V4L2_PIX_FMT_MJPEG);
}
#ifdef HAVE_ALSA
// default audio format tries
if (audioFmtList.empty()) {
audioFmtList.push_back(SND_PCM_FORMAT_S16_LE);
audioFmtList.push_back(SND_PCM_FORMAT_S16_BE);
}
#endif
// init logger
initLogger(verbose);
@ -570,7 +578,7 @@ int main(int argc, char** argv)
// Init video capture
LOG(NOTICE) << "Create V4L2 Source..." << videoDev;
V4L2DeviceParameters param(videoDev.c_str(), formatList, width, height, fps, verbose);
V4L2DeviceParameters param(videoDev.c_str(), videoformatList, width, height, fps, verbose);
V4l2Capture* videoCapture = V4l2Capture::create(param, ioTypeIn);
if (videoCapture)
{
@ -623,7 +631,7 @@ int main(int argc, char** argv)
// Init audio capture
LOG(NOTICE) << "Create ALSA Source..." << audioDev;
ALSACaptureParameters param(audioDev.c_str(), audioFmt, audioFreq, audioNbChannels, verbose);
ALSACaptureParameters param(audioDev.c_str(), audioFmtList, audioFreq, audioNbChannels, verbose);
ALSACapture* audioCapture = ALSACapture::createNew(param);
if (audioCapture)
{

Loading…
Cancel
Save