mirror of
https://github.com/mpromonet/v4l2rtspserver
synced 2024-11-02 03:40:13 +00:00
use audio freq/channel comming from ALSA capture instead of harcoding ti
This commit is contained in:
parent
333cc4a39c
commit
081c07e425
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
14
src/main.cpp
14
src/main.cpp
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user