use audio freq/channel comming from ALSA capture instead of harcoding ti

This commit is contained in:
Michel Promonet 2017-05-14 20:22:16 +02:00
parent 333cc4a39c
commit 081c07e425
3 changed files with 60 additions and 43 deletions

View File

@ -64,61 +64,60 @@ class ALSACapture
LOG(NOTICE) << "Open ALSA device: \"" << params.m_devName << "\"";
snd_pcm_hw_params_t *hw_params = NULL;
unsigned int rate = params.m_sampleRate;
int err = 0;
// open PCM device
if ((err = snd_pcm_open (&m_pcm, params.m_devName.c_str(), SND_PCM_STREAM_CAPTURE, 0)) < 0) {
LOG(ERROR) << "cannot open audio device: " << params.m_devName << " error:" << snd_strerror (err);
if ((err = snd_pcm_open (&m_pcm, m_params.m_devName.c_str(), SND_PCM_STREAM_CAPTURE, 0)) < 0) {
LOG(ERROR) << "cannot open audio device: " << m_params.m_devName << " error:" << snd_strerror (err);
}
// 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);
LOG(ERROR) << "cannot allocate hardware parameter structure device: " << m_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);
LOG(ERROR) << "cannot initialize hardware parameter structure device: " << m_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);
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, params.m_fmt)) < 0) {
LOG(ERROR) << "cannot set sample format device: " << params.m_devName << " error:" << snd_strerror (err);
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);
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);
else if ((err = snd_pcm_hw_params_set_rate_near (m_pcm, hw_params, &m_params.m_sampleRate, 0)) < 0) {
LOG(ERROR) << "cannot set sample rate device: " << m_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);
else if ((err = snd_pcm_hw_params_set_channels (m_pcm, hw_params, m_params.m_channels)) < 0) {
LOG(ERROR) << "cannot set channel count device: " << m_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);
LOG(ERROR) << "cannot set parameters device: " << m_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);
LOG(ERROR) << "cannot get parameters device: " << m_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);
LOG(ERROR) << "cannot prepare audio interface for use device: " << m_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);
LOG(ERROR) << "cannot start audio interface for use device: " << m_params.m_devName << " error:" << snd_strerror (err);
this->close();
}
LOG(NOTICE) << "ALSA device: \"" << params.m_devName << "\" buffer_size:" << m_bufferSize << " period_size:" << m_periodSize;
LOG(NOTICE) << "ALSA device: \"" << m_params.m_devName << "\" buffer_size:" << m_bufferSize << " period_size:" << m_periodSize << " rate:" << m_params.m_sampleRate;
}
public:
@ -127,29 +126,29 @@ class ALSACapture
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;
// swap if capture in not in network order
if (!snd_pcm_format_big_endian(m_params.m_fmt)) {
int fmt_phys_width_bits = snd_pcm_format_physical_width(m_params.m_fmt);
int 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);
LOG(DEBUG) << "ALSA buffer in_size:" << m_periodSize*fmt_phys_width_bytes << " read_size:" << ret;
if (ret > 0) {
size = ret;
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;
// swap if capture in not in network order
if (!snd_pcm_format_big_endian(m_params.m_fmt)) {
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;
@ -173,6 +172,8 @@ class ALSACapture
}
unsigned long getBufferSize() { return m_bufferSize; };
unsigned long getSampleRate() { return m_params.m_sampleRate; };
unsigned long getChannels () { return m_params.m_channels; };
private:
snd_pcm_t* m_pcm;

View File

@ -69,9 +69,17 @@ RTPSink* BaseServerMediaSubsession::createSink(UsageEnvironment& env, Groupsock
{
videoSink = JPEGVideoRTPSink::createNew (env, rtpGroupsock);
}
else if (format == "audio/L16")
else if (format.find("audio/L16") == 0)
{
videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, 44100, "audio", "L16", 2, True, False);
std::istringstream is(format);
std::string dummy;
getline(is, dummy, '/');
getline(is, dummy, '/');
std::string sampleRate("44100");
getline(is, sampleRate, '/');
std::string channels("2");
getline(is, channels);
videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, std::stoi(sampleRate), "audio", "L16", std::stoi(channels), True, False);
}
return videoSink;
}

View File

@ -464,6 +464,7 @@ int main(int argc, char** argv)
// Init Audio Capture
StreamReplicator* audioReplicator = NULL;
std::string rtpAudioFormat;
if (!audioDev.empty())
{
// Init audio capture
@ -481,6 +482,10 @@ int main(int argc, char** argv)
}
else
{
rtpAudioFormat.assign("audio/L16");
rtpAudioFormat.append("/").append(std::to_string(audioCapture->getSampleRate()));
rtpAudioFormat.append("/").append(std::to_string(audioCapture->getChannels()));
// extend buffer size if needed
if (audioCapture->getBufferSize() > OutPacketBuffer::maxSize)
{
@ -509,7 +514,7 @@ int main(int argc, char** argv)
if (audioReplicator)
{
subSession.push_back(MulticastServerMediaSubsession::createNew(*env, destinationAddress, Port(rtpPortNum), Port(rtcpPortNum), ttl, audioReplicator, "audio/L16"));
subSession.push_back(MulticastServerMediaSubsession::createNew(*env, destinationAddress, Port(rtpPortNum), Port(rtcpPortNum), ttl, audioReplicator, rtpAudioFormat));
// increment ports for next sessions
rtpPortNum+=2;
@ -521,7 +526,10 @@ int main(int argc, char** argv)
if (hlsSegment > 0)
{
std::list<ServerMediaSubsession*> subSession;
subSession.push_back(HLSServerMediaSubsession::createNew(*env, videoReplicator, rtpFormat, hlsSegment));
if (videoReplicator)
{
subSession.push_back(HLSServerMediaSubsession::createNew(*env, videoReplicator, rtpFormat, hlsSegment));
}
nbSource += addSession(rtspServer, baseUrl+url, subSession);
struct in_addr ip;
@ -538,7 +546,7 @@ int main(int argc, char** argv)
}
if (audioReplicator)
{
subSession.push_back(UnicastServerMediaSubsession::createNew(*env, audioReplicator, "audio/L16"));
subSession.push_back(UnicastServerMediaSubsession::createNew(*env, audioReplicator, rtpAudioFormat));
}
nbSource += addSession(rtspServer, baseUrl+url, subSession);
}