Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement compression classes with MP3 encoding as the first one #247

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 13 additions & 3 deletions inc/ALSACapture.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,29 @@

#include <alsa/asoundlib.h>
#include "logger.h"
#include "AudioCompressor.h"


#define COMPRESSED_AUDIO_FMT_NONE 0
#define COMPRESSED_AUDIO_FMT_MP3 1

#include "DeviceInterface.h"

struct ALSACaptureParameters
{
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) {

ALSACaptureParameters(const char* devname, const std::list<snd_pcm_format_t> & formatList,
unsigned int sampleRate, unsigned int channels, int verbose, AudioCompressor* audioCompressor) :
m_devName(devname), m_formatList(formatList), m_sampleRate(sampleRate), m_channels(channels),
m_verbose(verbose), m_audioCompressor(audioCompressor) {

}

std::string m_devName;
std::list<snd_pcm_format_t> m_formatList;
unsigned int m_sampleRate;
unsigned int m_channels;
int m_verbose;
AudioCompressor* m_audioCompressor;
};

class ALSACapture : public DeviceInterface
Expand Down Expand Up @@ -61,6 +69,8 @@ class ALSACapture : public DeviceInterface
unsigned long m_periodSize;
ALSACaptureParameters m_params;
snd_pcm_format_t m_fmt;


};

#endif
Expand Down
22 changes: 22 additions & 0 deletions inc/AudioCompressor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** AudioCompressor.h
**
** Contains abstract class for audio compressors
**
** -------------------------------------------------------------------------*/

#pragma once

#include "logger.h"

class AudioCompressor
{
public:
AudioCompressor();
virtual int compress(short* pcm_data, int sample_count, char* output_buffer, int output_buffer_size) { return -1; };
private:
};
26 changes: 26 additions & 0 deletions inc/MP3AudioCompressor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** MP3AudioCompressor.h
**
** Contains abstract class for audio compressors
**
** -------------------------------------------------------------------------*/

#pragma once

#include "logger.h"
#include <lame.h>
#include "AudioCompressor.h"

class MP3AudioCompressor: public AudioCompressor
{
public:
MP3AudioCompressor();
MP3AudioCompressor(int channels, int samplerate);
int compress(short* pcm_data, int sample_count, char* output_buffer, int output_buffer_size);
private:
lame_global_flags* gfp;
};
18 changes: 18 additions & 0 deletions inc/NullAudioCompressor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
** -------------------------------------------------------------------------*/

#pragma once

#include "logger.h"
#include "AudioCompressor.h"

class NullAudioCompressor: public AudioCompressor
{
public:
NullAudioCompressor();
int compress(short* pcm_data, int sample_count, char* output_buffer, int output_buffer_size);
private:
};
16 changes: 14 additions & 2 deletions inc/ServerMediaSubsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,20 @@ class BaseServerMediaSubsession
{
public:
BaseServerMediaSubsession(StreamReplicator* replicator): m_replicator(replicator) {

V4L2DeviceSource* deviceSource = dynamic_cast<V4L2DeviceSource*>(replicator->inputSource());

if (deviceSource) {
DeviceInterface* device = deviceSource->getDevice();
if (device->getVideoFormat() >= 0) {
m_format = BaseServerMediaSubsession::getVideoRtpFormat(device->getVideoFormat());
} else {
m_format = BaseServerMediaSubsession::getAudioRtpFormat(device->getAudioFormat(), device->getSampleRate(), device->getChannels());
m_format = BaseServerMediaSubsession::getAudioRtpFormat(device->getAudioFormat(), device->getSampleRate(), device->getChannels());
}
LOG(NOTICE) << "format:" << m_format;
}


}

// -----------------------------------------
Expand All @@ -69,9 +73,13 @@ class BaseServerMediaSubsession
return rtpFormat;
}

/*
* Return the format for the audio part of the RTP session.
*/
static std::string getAudioRtpFormat(int format, int sampleRate, int channels)
{
std::ostringstream os;

#ifdef HAVE_ALSA
os << "audio/";
switch (format) {
Expand Down Expand Up @@ -100,6 +108,8 @@ class BaseServerMediaSubsession
break;
}
os << "/" << sampleRate << "/" << channels;


#endif
return os.str();
}
Expand All @@ -111,6 +121,8 @@ class BaseServerMediaSubsession

protected:
StreamReplicator* m_replicator;
std::string m_format;
std::string m_format;
int m_compressedAudioFmt;

};

3 changes: 2 additions & 1 deletion inc/UnicastServerMediaSubsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ class UnicastServerMediaSubsession : public OnDemandServerMediaSubsession , publ
{
public:
static UnicastServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator);
static UnicastServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, int compressedAudioFmt);

protected:
UnicastServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator)
: OnDemandServerMediaSubsession(env, False), BaseServerMediaSubsession(replicator) {}

virtual FramedSource* createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate);
virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource);
virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource);
Expand Down
7 changes: 4 additions & 3 deletions inc/V4l2RTSPServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "MulticastServerMediaSubsession.h"
#include "TSServerMediaSubsession.h"
#include "HTTPServer.h"
#include "AudioCompressor.h"

class V4l2RTSPServer {
public:
Expand Down Expand Up @@ -124,13 +125,13 @@ class V4l2RTSPServer {
#ifdef HAVE_ALSA
StreamReplicator* CreateAudioReplicator(
const std::string& audioDev, const std::list<snd_pcm_format_t>& audioFmtList, int audioFreq, int audioNbChannels, int verbose,
int queueSize, int useThread);
int queueSize, int useThread, AudioCompressor* compressor);
#endif

// -----------------------------------------
// Add unicast Session
// -----------------------------------------
int AddUnicastSession(const std::string& url, StreamReplicator* videoReplicator, StreamReplicator* audioReplicator) {
int AddUnicastSession(const std::string& url, StreamReplicator* videoReplicator, StreamReplicator* audioReplicator, int compressedAudioFmt) {
// Create Unicast Session
std::list<ServerMediaSubsession*> subSession;
if (videoReplicator)
Expand All @@ -139,7 +140,7 @@ class V4l2RTSPServer {
}
if (audioReplicator)
{
subSession.push_back(UnicastServerMediaSubsession::createNew(*this->env(), audioReplicator));
subSession.push_back(UnicastServerMediaSubsession::createNew(*this->env(), audioReplicator, compressedAudioFmt));
}
return this->addSession(url, subSession);
}
Expand Down
39 changes: 36 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@

#include "DeviceSourceFactory.h"
#include "V4l2RTSPServer.h"
#include "AudioCompressor.h"
#include "NullAudioCompressor.h"
#include "MP3AudioCompressor.h"


// -----------------------------------------
Expand Down Expand Up @@ -156,6 +159,12 @@ int main(int argc, char** argv)
int audioNbChannels = 2;
std::list<snd_pcm_format_t> audioFmtList;
snd_pcm_format_t audioFmt = SND_PCM_FORMAT_UNKNOWN;
int compressedAudioFmt = COMPRESSED_AUDIO_FMT_NONE;

AudioCompressor *compressor;
std::list<AudioCompressor *> audioCompressors;


#endif
const char* defaultPort = getenv("PORT");
if (defaultPort != NULL) {
Expand All @@ -164,7 +173,7 @@ int main(int argc, char** argv)

// decode parameters
int c = 0;
while ((c = getopt (argc, argv, "v::Q:O:b:" "I:P:p:m::u:M:ct:S::" "R:U:" "rwBsf::F:W:H:G:" "A:C:a:" "Vh")) != -1)
while ((c = getopt (argc, argv, "v::Q:O:b:" "I:P:p:m::u:M:ct:S::" "R:U:" "rwBsf::F:W:H:G:" "A:C:a:l:" "Vh")) != -1)
{
switch (c)
{
Expand Down Expand Up @@ -204,6 +213,10 @@ int main(int argc, char** argv)
case 'A': audioFreq = atoi(optarg); break;
case 'C': audioNbChannels = atoi(optarg); break;
case 'a': audioFmt = decodeAudioFormat(optarg); if (audioFmt != SND_PCM_FORMAT_UNKNOWN) {audioFmtList.push_back(audioFmt);} ; break;

case 'l': compressedAudioFmt = atoi(optarg); break;


#endif

// version
Expand Down Expand Up @@ -255,6 +268,8 @@ int main(int argc, char** argv)
std::cout << "\t -A freq : ALSA capture frequency and channel (default " << audioFreq << ")" << std::endl;
std::cout << "\t -C channels : ALSA capture channels (default " << audioNbChannels << ")" << std::endl;
std::cout << "\t -a fmt : ALSA capture audio format (default S16_BE)" << std::endl;
std::cout << "\t -l [number] : Compresssed audio format: 0 - None, 1 - MP3" << std::endl;

#endif

std::cout << "\t Devices :" << std::endl;
Expand Down Expand Up @@ -342,9 +357,26 @@ int main(int argc, char** argv)
// Init Audio Capture
StreamReplicator* audioReplicator = NULL;
#ifdef HAVE_ALSA



if (compressedAudioFmt == COMPRESSED_AUDIO_FMT_NONE) {
compressor = new NullAudioCompressor();
audioCompressors.push_back(compressor);
}

if (compressedAudioFmt == COMPRESSED_AUDIO_FMT_MP3) {
compressor = new MP3AudioCompressor(audioNbChannels, audioFreq);
audioCompressors.push_back(compressor);
}

LOG(NOTICE) << "Using AudioCompressor: " << compressor;


audioReplicator = rtspServer.CreateAudioReplicator(
audioDev, audioFmtList, audioFreq, audioNbChannels, verbose,
queueSize, useThread);
queueSize, useThread, compressor);

#endif


Expand All @@ -361,7 +393,8 @@ int main(int argc, char** argv)
}

// Create Unicast Session
nbSource += rtspServer.AddUnicastSession(baseUrl+url, videoReplicator, audioReplicator);
nbSource += rtspServer.AddUnicastSession(baseUrl+url, videoReplicator, audioReplicator, compressedAudioFmt);

}

if (nbSource>0)
Expand Down