[Opalvoip-svn] SF.net SVN: opalvoip:[24407] opal/trunk
Brought to you by:
csoutheren,
rjongbloed
From: <cso...@us...> - 2010-05-27 11:04:05
|
Revision: 24407 http://opalvoip.svn.sourceforge.net/opalvoip/?rev=24407&view=rev Author: csoutheren Date: 2010-05-27 11:03:57 +0000 (Thu, 27 May 2010) Log Message: ----------- Add better support for stereo audio Thanks to Christopher Zimmermann Modified Paths: -------------- opal/trunk/include/codec/opalplugin.h opal/trunk/include/codec/opalpluginmgr.h opal/trunk/include/opal/mediafmt.h opal/trunk/samples/opalcodecinfo/main.cxx opal/trunk/src/codec/opalpluginmgr.cxx opal/trunk/src/opal/ivr.cxx opal/trunk/src/opal/manager.cxx opal/trunk/src/opal/mediafmt.cxx Modified: opal/trunk/include/codec/opalplugin.h =================================================================== --- opal/trunk/include/codec/opalplugin.h 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/include/codec/opalplugin.h 2010-05-27 11:03:57 UTC (rev 24407) @@ -173,6 +173,9 @@ PluginCodec_BitsPerSamplePos = 12, PluginCodec_BitsPerSampleMask = 0xf000, + + PluginCodec_ChannelsPos = 16, + PluginCodec_ChannelsMask = 0x003f0000 }; enum PluginCodec_CoderFlags { @@ -280,6 +283,7 @@ // Normalised option names #define PLUGINCODEC_OPTION_NEEDS_JITTER "Needs Jitter" #define PLUGINCODEC_OPTION_CLOCK_RATE "Clock Rate" +#define PLUGINCODEC_OPTION_CHANNELS "Channels" #define PLUGINCODEC_OPTION_FRAME_TIME "Frame Time" #define PLUGINCODEC_OPTION_MAX_FRAME_SIZE "Max Frame Size" #define PLUGINCODEC_OPTION_MAX_BIT_RATE "Max Bit Rate" Modified: opal/trunk/include/codec/opalpluginmgr.h =================================================================== --- opal/trunk/include/codec/opalpluginmgr.h 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/include/codec/opalpluginmgr.h 2010-05-27 11:03:57 UTC (rev 24407) @@ -81,6 +81,8 @@ public: OpalPluginCodecHandler(); + static int GetChannelCount(const PluginCodec_Definition * codeDefn); + virtual OpalMediaFormatInternal * OnCreateAudioFormat(OpalPluginCodecManager & mgr, const PluginCodec_Definition * codecDefn, const char * fmtName, @@ -356,7 +358,7 @@ ////////////////////////////////////////////////////// // -// this is the base class for codecs accesible via the abstract factory functions +// this is the base class for codecs accessible via the abstract factory functions // /**Class for codcs which is accessible via the abstract factory functions. Modified: opal/trunk/include/opal/mediafmt.h =================================================================== --- opal/trunk/include/opal/mediafmt.h 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/include/opal/mediafmt.h 2010-05-27 11:03:57 UTC (rev 24407) @@ -605,6 +605,7 @@ PSortedList<OpalMediaOption> options; time_t codecVersionTime; bool forceIsTransportable; + int m_channels; friend bool operator==(const char * other, const OpalMediaFormat & fmt); friend bool operator!=(const char * other, const OpalMediaFormat & fmt); @@ -864,6 +865,11 @@ unsigned GetClockRate() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->GetOptionInteger(ClockRateOption(), 1000); } static const PString & ClockRateOption(); + /**Get the number of audio channels for this format. + */ + unsigned GetChannels() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->GetOptionInteger(ChannelsOption(), 1); } + static const PString & ChannelsOption(); + /**Get the name of the OpalMediaOption indicating the protocol the format is being used on. */ static const PString & ProtocolOption(); @@ -1258,10 +1264,12 @@ #define OPAL_PCM16_16KHZ "PCM-16-16kHz" #define OPAL_PCM16_32KHZ "PCM-16-32kHz" #define OPAL_PCM16_48KHZ "PCM-16-48kHz" +#define OPAL_PCM16S_48KHZ "PCM-16S-48kHz" #define OPAL_L16_MONO_8KHZ "Linear-16-Mono-8kHz" #define OPAL_L16_MONO_16KHZ "Linear-16-Mono-16kHz" #define OPAL_L16_MONO_32KHZ "Linear-16-Mono-32kHz" #define OPAL_L16_MONO_48KHZ "Linear-16-Mono-48kHz" +#define OPAL_L16_STEREO_48KHZ "Linear-16-Stereo-48kHz" #define OPAL_G711_ULAW_64K "G.711-uLaw-64k" #define OPAL_G711_ALAW_64K "G.711-ALaw-64k" #define OPAL_G722 "G.722" @@ -1297,6 +1305,7 @@ extern const OpalAudioFormat & GetOpalPCM16_16KHZ(); extern const OpalAudioFormat & GetOpalPCM16_32KHZ(); extern const OpalAudioFormat & GetOpalPCM16_48KHZ(); +extern const OpalAudioFormat & GetOpalPCM16S_48KHZ(); extern const OpalAudioFormat & GetOpalL16_MONO_8KHZ(); extern const OpalAudioFormat & GetOpalL16_MONO_16KHZ(); extern const OpalAudioFormat & GetOpalL16_MONO_32KHZ(); @@ -1336,6 +1345,7 @@ #define OpalPCM16_16KHZ GetOpalPCM16_16KHZ() #define OpalPCM16_32KHZ GetOpalPCM16_32KHZ() #define OpalPCM16_48KHZ GetOpalPCM16_48KHZ() +#define OpalPCM16S_48KHZ GetOpalPCM16S_48KHZ() #define OpalL16_MONO_8KHZ GetOpalL16_MONO_8KHZ() #define OpalL16_MONO_16KHZ GetOpalL16_MONO_16KHZ() #define OpalL16_MONO_32KHZ GetOpalL16_MONO_32KHZ() Modified: opal/trunk/samples/opalcodecinfo/main.cxx =================================================================== --- opal/trunk/samples/opalcodecinfo/main.cxx 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/samples/opalcodecinfo/main.cxx 2010-05-27 11:03:57 UTC (rev 24407) @@ -172,7 +172,8 @@ cout << " Samples/frame: " << defn.parm.audio.samplesPerFrame << endl << " Bytes/frame: " << defn.parm.audio.bytesPerFrame << endl << " Frames/packet: " << defn.parm.audio.recommendedFramesPerPacket << endl - << " Frames/packet (max): " << defn.parm.audio.maxFramesPerPacket << endl; + << " Frames/packet (max): " << defn.parm.audio.maxFramesPerPacket << endl + << " Channels: " << defn.parm.audio.channels << endl; } else { cout << " Frame width (max): " << defn.parm.video.maxFrameWidth << endl Modified: opal/trunk/src/codec/opalpluginmgr.cxx =================================================================== --- opal/trunk/src/codec/opalpluginmgr.cxx 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/src/codec/opalpluginmgr.cxx 2010-05-27 11:03:57 UTC (rev 24407) @@ -549,6 +549,8 @@ // Override calculated value if we have an explicit bit rate if (codecDefn->bitsPerSec > 0) SetOptionInteger(OpalMediaFormat::MaxBitRateOption(), codecDefn->bitsPerSec); + + m_channels = OpalPluginCodecHandler::GetChannelCount(codecDefn); } @@ -671,11 +673,13 @@ // Plugin framed audio codec classes // -static OpalMediaFormat GetRawPCM(const char * fmtName, unsigned sampleRate) +static OpalMediaFormat GetRawPCM(const char * fmtName, unsigned sampleRate, unsigned channels) { - if (strcmp(fmtName, "L16") != 0) + if (strcmp(fmtName, "L16") != 0 && strcmp(fmtName, "L16S") != 0) return fmtName; + if (channels == 2 && sampleRate == 48000) + return OpalPCM16S_48KHZ; switch (sampleRate) { default : case 8000 : @@ -691,8 +695,8 @@ OpalPluginFramedAudioTranscoder::OpalPluginFramedAudioTranscoder(const PluginCodec_Definition * codecDefn, bool isEncoder) - : OpalFramedTranscoder(GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate), - GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate)) + : OpalFramedTranscoder(GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)), + GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn))) , OpalPluginTranscoder(codecDefn, isEncoder) { inputIsRTP = (codecDef->flags & PluginCodec_InputTypeMask) == PluginCodec_InputTypeRTP; @@ -772,8 +776,8 @@ OpalPluginStreamedAudioTranscoder::OpalPluginStreamedAudioTranscoder(const PluginCodec_Definition * codecDefn, bool isEncoder) - : OpalStreamedTranscoder(GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate), - GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate), + : OpalStreamedTranscoder(GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)), + GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)), 16, 16) , OpalPluginTranscoder(codecDefn, isEncoder) { @@ -1091,8 +1095,8 @@ public: OpalFaxTranscoder(const PluginCodec_Definition * codecDefn, bool isEncoder) - : OpalTranscoder(GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate), - GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate)) + : OpalTranscoder(GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)), + GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn))) , OpalPluginTranscoder(codecDefn, isEncoder) , getCodecStatistics(codecDefn, PLUGINCODEC_CONTROL_GET_STATISTICS) { @@ -1368,11 +1372,11 @@ return ((encoder.h323CapabilityType != PluginCodec_H323Codec_undefined) && ( ( ((encoder.flags & PluginCodec_MediaTypeMask) == PluginCodec_MediaTypeAudio) && - (strcmp(encoder.sourceFormat, "L16") == 0 || strncmp(encoder.sourceFormat, "PCM-16", 6) == 0) + (strncmp(encoder.sourceFormat, "L16", 3) == 0 || strncmp(encoder.sourceFormat, "PCM-16", 6) == 0) ) || ( ((encoder.flags & PluginCodec_MediaTypeMask) == PluginCodec_MediaTypeAudioStreamed) && - (strcmp(encoder.sourceFormat, "L16") == 0 || strncmp(encoder.sourceFormat, "PCM-16", 6) == 0) + (strncmp(encoder.sourceFormat, "L16", 3) == 0 || strncmp(encoder.sourceFormat, "PCM-16", 6) == 0) ) || ( videoSupported && @@ -1382,7 +1386,7 @@ ( faxSupported && ((encoder.flags & PluginCodec_MediaTypeMask) == PluginCodec_MediaTypeFax) && - (strcmp(encoder.sourceFormat, "L16") == 0 || strncmp(encoder.sourceFormat, "PCM-16", 6) == 0) + (strncmp(encoder.sourceFormat, "L16", 3) == 0 || strncmp(encoder.sourceFormat, "PCM-16", 6) == 0) ) )); } @@ -1416,7 +1420,7 @@ const char * fmtName) { // Create (if needed) the media format - OpalMediaFormat existingFormat = GetRawPCM(fmtName, codecDefn->sampleRate); + OpalMediaFormat existingFormat = GetRawPCM(fmtName, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)); // deal with codec having no info, or timestamp in future time_t timeStamp; @@ -1487,18 +1491,22 @@ // if the codec has been flagged to use a shared RTP payload type, then find a codec with the same SDP name // and clock rate and use that RTP code rather than creating a new one. That prevents codecs (like Speex) from // consuming dozens of dynamic RTP types + int channels = OpalPluginCodecHandler::GetChannelCount(codecDefn); if ((codecDefn->flags & PluginCodec_RTPTypeShared) != 0 && (codecDefn->sdpFormat != NULL)) { OpalMediaFormatList list = OpalMediaFormat::GetAllRegisteredMediaFormats(); for (OpalMediaFormatList::iterator iterFmt = list.begin(); iterFmt != list.end(); ++iterFmt) { OpalPluginMediaFormat * opalFmt = dynamic_cast<OpalPluginMediaFormat *>(&*iterFmt); if (opalFmt != NULL) { OpalPluginMediaFormatInternal * fmt = opalFmt->GetInfo(); - if (fmt != NULL && - fmt->codecDef->sdpFormat != NULL && - codecDefn->sampleRate == fmt->codecDef->sampleRate && - strcasecmp(codecDefn->sdpFormat, fmt->codecDef->sdpFormat) == 0) { - mediaFormat->SetPayloadType(opalFmt->GetPayloadType()); - break; + if (fmt != NULL) { + int fmtChannels = OpalPluginCodecHandler::GetChannelCount(fmt->codecDef); + if (fmt->codecDef->sdpFormat != NULL && + codecDefn->sampleRate == fmt->codecDef->sampleRate && + channels == fmtChannels && + strcasecmp(codecDefn->sdpFormat, fmt->codecDef->sdpFormat) == 0) { + mediaFormat->SetPayloadType(opalFmt->GetPayloadType()); + break; + } } } } @@ -1519,6 +1527,7 @@ GetOpalPCM16_16KHZ(); GetOpalPCM16_32KHZ(); GetOpalPCM16_48KHZ(); + GetOpalPCM16S_48KHZ(); #if OPAL_VIDEO GetOpalYUV420P(); #endif @@ -1534,8 +1543,8 @@ continue; // Create transcoder factories for the codecs - OpalMediaFormat src = GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate); - OpalMediaFormat dst = GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate); + OpalMediaFormat src = GetRawPCM(codecDefn->sourceFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)); + OpalMediaFormat dst = GetRawPCM(codecDefn->destFormat, codecDefn->sampleRate, OpalPluginCodecHandler::GetChannelCount(codecDefn)); bool isEncoder = IsEncoder(*codecDefn); switch (codecDefn->flags & PluginCodec_MediaTypeMask) { #if OPAL_VIDEO @@ -1578,6 +1587,14 @@ } +int OpalPluginCodecHandler::GetChannelCount(const PluginCodec_Definition * codecDefn) +{ + if (codecDefn == NULL) + return 0; + return ((codecDefn->flags & PluginCodec_ChannelsMask) >> PluginCodec_ChannelsPos) + 1; +} + + OpalMediaFormatInternal * OpalPluginCodecHandler::OnCreateAudioFormat(OpalPluginCodecManager & /*mgr*/, const PluginCodec_Definition * codecDefn, const char * fmtName, Modified: opal/trunk/src/opal/ivr.cxx =================================================================== --- opal/trunk/src/opal/ivr.cxx 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/src/opal/ivr.cxx 2010-05-27 11:03:57 UTC (rev 24407) @@ -61,6 +61,8 @@ "</vxml>\n") { defaultMediaFormats += OpalPCM16; + defaultMediaFormats += OpalPCM16_48KHZ; + defaultMediaFormats += OpalPCM16S_48KHZ; defaultMediaFormats += OpalRFC2833; #if OPAL_T38_CAPABILITY defaultMediaFormats += OpalCiscoNSE; Modified: opal/trunk/src/opal/manager.cxx =================================================================== --- opal/trunk/src/opal/manager.cxx 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/src/opal/manager.cxx 2010-05-27 11:03:57 UTC (rev 24407) @@ -45,6 +45,7 @@ #include <codec/g711codec.h> #include <codec/vidcodec.h> #include <codec/rfc4175.h> +#include <codec/rfc2435.h> #include <codec/opalpluginmgr.h> #if OPAL_HAS_H224 @@ -86,7 +87,12 @@ OPAL_REGISTER_RFC4175(); #endif +// Same deal for RC2435 video +#if OPAL_RFC2435 +OPAL_REGISTER_RFC2435_JPEG(); +#endif + #define new PNEW @@ -723,6 +729,7 @@ if (pcmAudio) { // Sound cards can only do 16 bit PCM, but at various sample rates // The following will be in order of preference, so lets do wideband first + formats += OpalPCM16S_48KHZ; formats += OpalPCM16_48KHZ; formats += OpalPCM16_32KHZ; formats += OpalPCM16_16KHZ; Modified: opal/trunk/src/opal/mediafmt.cxx =================================================================== --- opal/trunk/src/opal/mediafmt.cxx 2010-05-27 11:00:30 UTC (rev 24406) +++ opal/trunk/src/opal/mediafmt.cxx 2010-05-27 11:03:57 UTC (rev 24407) @@ -88,18 +88,31 @@ } }; +const OpalAudioFormat & GetOpalPCM16S_48KHZ() +{ + static OpalStereoAudioFormat stereo48k(OPAL_PCM16S_48KHZ, // name of the media format + RTP_DataFrame::L16_Stereo, // RTP payload code + "", // encoding name + 192, // frame size in bytes + 48, // frame time (1 ms in clock units) + 240, // recommended rx frames/packet + 0, // recommended tx frames/packet + 256, // max tx frame size + 48000); // clock rate + return stereo48k; +}; const OpalAudioFormat & GetOpalL16_STEREO_48KHZ() { - static OpalStereoAudioFormat stereo48k("Linear-16-Stereo-48kHz", // name of the meda format - RTP_DataFrame::DynamicBase, // RTP payload code - "L16", // encoding name - 16, // frame size in bytes - 48, // frame time (1 ms in clock units) - 20, // recommended rx frames/packet - 20, // recommended tx frames/packet - 50, // max tx frame size - 48000); // clock rate + static OpalStereoAudioFormat stereo48k(OPAL_L16_STEREO_48KHZ, // name of the media format + RTP_DataFrame::L16_Stereo, // RTP payload code + "L16S", // encoding name + 192, // frame size in bytes + 48, // frame time (1 ms in clock units) + 240, // recommended rx frames/packet + 30, // recommended tx frames/packet + 256, // max tx frame size + 48000); // clock rate return stereo48k; }; @@ -963,12 +976,13 @@ PINDEX fs, unsigned ft, unsigned cr, - time_t ts) + time_t ts) : formatName(fullName), mediaType(_mediaType), forceIsTransportable(false) { codecVersionTime = ts; - rtpPayloadType = pt; - rtpEncodingName = en; + rtpPayloadType = pt; + rtpEncodingName = en; + m_channels = 1; // this is the default - it's up to descendant classes to change it if (nj) AddOption(new OpalMediaOptionBoolean(OpalMediaFormat::NeedsJitterOption(), true, OpalMediaOption::OrMerge, true)); @@ -1498,7 +1512,7 @@ AddOption(new OpalMediaOptionUnsigned(OpalAudioFormat::TxFramesPerPacketOption(), false, OpalMediaOption::AlwaysMerge, txFrames, 1, maxFrames)); AddOption(new OpalMediaOptionUnsigned(OpalAudioFormat::MaxFramesPerPacketOption(), true, OpalMediaOption::NoMerge, maxFrames)); - AddOption(new OpalMediaOptionUnsigned(OpalAudioFormat::ChannelsOption(), false, OpalMediaOption::NoMerge, 1, 1, 5)); + AddOption(new OpalMediaOptionUnsigned(OpalAudioFormat::ChannelsOption(), false, OpalMediaOption::NoMerge, m_channels, 1, 5)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |