1 /*
2  * codecs.cxx
3  *
4  * H.323 protocol handler
5  *
6  * Open H323 Library
7  *
8  * Copyright (c) 1998-2000 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open H323 Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions of this code were written with the assisance of funding from
25  * Vovida Networks, Inc. http://www.vovida.com.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Id$
30  *
31  */
32 
33 #include <ptlib.h>
34 
35 #ifdef __GNUC__
36 #pragma implementation "codecs.h"
37 #endif
38 
39 #ifdef _MSC_VER
40 #include "../include/codecs.h"
41 #else
42 #include "codecs.h"
43 #endif
44 
45 #include "channels.h"
46 #include "h323pdu.h"
47 #include "h323con.h"
48 
49 #ifdef H323_AEC
50 #include <etc/h323aec.h>
51 #endif // H323_AEC
52 
53 extern "C" {
54 #include "g711.h"
55 };
56 
57 #define new PNEW
58 
59 /////////////////////////////////////////////////////////////////////////////
60 
H323Codec(const OpalMediaFormat & fmt,Direction dir)61 H323Codec::H323Codec(const OpalMediaFormat & fmt, Direction dir)
62   : mediaFormat(fmt)
63 {
64   logicalChannel = NULL;
65   direction = dir;
66 
67   lastSequenceNumber = 1;
68   rawDataChannel = NULL;
69   deleteChannel  = FALSE;
70 
71   rtpInformation.m_sessionID=0;
72   rtpInformation.m_sendTime=0;
73   rtpInformation.m_timeStamp=0;
74   rtpInformation.m_clockRate=0;
75   rtpInformation.m_frameLost=0;
76   rtpInformation.m_recvTime=0;
77   rtpInformation.m_frame=NULL;
78 
79   rtpSync.m_realTimeStamp = 0;
80   rtpSync.m_rtpTimeStamp = 0;
81 }
82 
83 
Open(H323Connection &)84 PBoolean H323Codec::Open(H323Connection & /*connection*/)
85 {
86   return TRUE;
87 }
88 
GetFrameRate() const89 unsigned H323Codec::GetFrameRate() const
90 {
91   return mediaFormat.GetFrameTime();
92 }
93 
94 
OnFlowControl(long PTRACE_PARAM (bitRateRestriction))95 void H323Codec::OnFlowControl(long PTRACE_PARAM(bitRateRestriction))
96 {
97   PTRACE(3, "Codec\tOnFlowControl: " << bitRateRestriction);
98 }
99 
100 
OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & PTRACE_PARAM (type))101 void H323Codec::OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & PTRACE_PARAM(type))
102 {
103   PTRACE(3, "Codec\tOnMiscellaneousCommand: " << type.GetTagName());
104 }
105 
106 
OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & PTRACE_PARAM (type))107 void H323Codec::OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & PTRACE_PARAM(type))
108 {
109   PTRACE(3, "Codec\tOnMiscellaneousIndication: " << type.GetTagName());
110 }
111 
112 
AttachChannel(PChannel * channel,PBoolean autoDelete)113 PBoolean H323Codec::AttachChannel(PChannel * channel, PBoolean autoDelete)
114 {
115   PWaitAndSignal mutex(rawChannelMutex);
116 
117   CloseRawDataChannel();
118 
119   rawDataChannel = channel;
120   deleteChannel = autoDelete;
121 
122   if (channel == NULL){
123 	PTRACE(3, "Codec\tError attaching channel. channel is NULL");
124     return FALSE;
125   }
126 
127   return channel->IsOpen();
128 }
129 
SwapChannel(PChannel * newChannel,PBoolean autoDelete)130 PChannel * H323Codec::SwapChannel(PChannel * newChannel, PBoolean autoDelete)
131 {
132   PWaitAndSignal mutex(rawChannelMutex);
133 
134   PChannel * oldChannel = rawDataChannel;
135 
136   rawDataChannel = newChannel;
137   deleteChannel = autoDelete;
138 
139   return oldChannel;
140 }
141 
142 
CloseRawDataChannel()143 PBoolean H323Codec::CloseRawDataChannel()
144 {
145   if (rawDataChannel == NULL)
146     return FALSE;
147 
148   PBoolean closeOK = rawDataChannel->Close();
149 
150   if (deleteChannel) {
151      delete rawDataChannel;
152      rawDataChannel = NULL;
153   }
154 
155   return closeOK;
156 }
157 
158 
IsRawDataChannelNative() const159 PBoolean H323Codec::IsRawDataChannelNative() const
160 {
161   return FALSE;
162 }
163 
164 
ReadRaw(void * data,PINDEX size,PINDEX & length)165 PBoolean H323Codec::ReadRaw(void * data, PINDEX size, PINDEX & length)
166 {
167   if (rawDataChannel == NULL) {
168     PTRACE(1, "Codec\tNo audio channel for read");
169     return FALSE;
170   }
171 
172   if (!rawDataChannel->Read(data, size)) {
173     PTRACE(1, "Codec\tAudio read failed: " << rawDataChannel->GetErrorText(PChannel::LastReadError));
174     return FALSE;
175   }
176 
177   length = rawDataChannel->GetLastReadCount();
178   for (PINDEX i = 0; i < filters.GetSize(); i++) {
179       length = filters[i].ProcessFilter(data, size, length);
180   }
181 
182   return TRUE;
183 }
184 
WriteRaw(void * data,PINDEX length,void * mark)185 PBoolean H323Codec::WriteRaw(void * data, PINDEX length, void * mark)
186 {
187     return WriteInternal(data, length, mark);
188 }
189 
WriteInternal(void * data,PINDEX length,void * mark)190 PBoolean H323Codec::WriteInternal(void * data, PINDEX length, void * mark)
191 {
192   if (rawDataChannel == NULL) {
193     PTRACE(1, "Codec\tNo audio channel for write");
194     return FALSE;
195   }
196 
197   for (PINDEX i = 0; i < filters.GetSize(); i++) {
198       length = filters[i].ProcessFilter(data, length, length);
199   }
200 
201 #if PTLIB_VER < 290
202   if (rawDataChannel->Write(data, length))
203 #else
204   if (rawDataChannel->Write(data, length, mark))
205 #endif
206     return TRUE;
207 
208   PTRACE(1, "Codec\tWrite failed: " << rawDataChannel->GetErrorText(PChannel::LastWriteError));
209   return FALSE;
210 }
211 
212 
AttachLogicalChannel(H323Channel * channel)213 PBoolean H323Codec::AttachLogicalChannel(H323Channel *channel)
214 {
215   logicalChannel = channel;
216   rtpInformation.m_sessionID=logicalChannel->GetSessionID();
217 
218   return TRUE;
219 }
220 
221 
AddFilter(const PNotifier & notifier)222 void H323Codec::AddFilter(const PNotifier & notifier)
223 {
224   rawChannelMutex.Wait();
225   filters.Append(new FilterData(*this,notifier));
226   rawChannelMutex.Signal();
227 }
228 
SetRawDataHeld(PBoolean)229 PBoolean H323Codec::SetRawDataHeld(PBoolean /*hold*/)
230 {
231 	return FALSE;
232 }
233 
OnRxSenderReport(DWORD rtpTimeStamp,const PInt64 & realTimeStamp)234 PBoolean H323Codec::OnRxSenderReport(DWORD rtpTimeStamp, const PInt64 & realTimeStamp)
235 {
236     rtpSync.m_rtpTimeStamp = rtpTimeStamp;
237     rtpSync.m_realTimeStamp = realTimeStamp;
238     return true;
239 }
240 
CalculateRTPSendTime(DWORD timeStamp,unsigned rate) const241 PTime H323Codec::CalculateRTPSendTime(DWORD timeStamp, unsigned rate) const
242 {
243     if (rtpSync.m_rtpTimeStamp == 0)
244         return 0;
245 
246     DWORD timeDiff = (timeStamp - rtpSync.m_rtpTimeStamp)/rate;
247 
248     return rtpSync.m_realTimeStamp + timeDiff;
249 
250 }
251 
CalculateRTPSendTime(DWORD timeStamp,unsigned rate,PInt64 & sendTime) const252 void H323Codec::CalculateRTPSendTime(DWORD timeStamp, unsigned rate, PInt64 & sendTime) const
253 {
254     if (rtpSync.m_rtpTimeStamp == 0) {
255         sendTime = 0;
256         return;
257     }
258 
259     DWORD timeDiff = (timeStamp - rtpSync.m_rtpTimeStamp)/rate;
260 
261     sendTime = rtpSync.m_realTimeStamp + timeDiff;
262 }
263 
264 /////////////////////////////////////////////////////////////////////////////
265 
266 #ifdef H323_VIDEO
267 
H323VideoCodec(const OpalMediaFormat & fmt,Direction dir)268 H323VideoCodec::H323VideoCodec(const OpalMediaFormat & fmt, Direction dir)
269   : H323Codec(fmt, dir),
270     frameWidth(0), frameHeight(0), fillLevel(0), sarWidth(1), sarHeight(1),
271     videoBitRateControlModes(None), bitRateHighLimit(0), oldLength(0), oldTime(0), newTime(0),
272     targetFrameTimeMs(0), frameBytes(0), sumFrameTimeMs(0), sumAdjFrameTimeMs(0), sumFrameBytes(0),
273     videoQMax(0), videoQMin(0), videoQuality(0), frameStartTime(0), grabInterval(0), frameNum(0),
274     packetNum(0), oldPacketNum(0), framesPerSec(0)
275 {
276 
277 }
278 
279 
~H323VideoCodec()280 H323VideoCodec::~H323VideoCodec()
281 {
282   Close();    //The close operation may delete the rawDataChannel.
283 
284   //mediaFormat.RemoveAllOptions();
285 }
286 
287 
Open(H323Connection & connection)288 PBoolean H323VideoCodec::Open(H323Connection & connection)
289 {
290 #ifdef H323_H239
291   if (rtpInformation.m_sessionID != OpalMediaFormat::DefaultVideoSessionID)
292     return connection.OpenExtendedVideoChannel(direction == Encoder, *this);
293   else
294 #endif
295     return connection.OpenVideoChannel(direction == Encoder, *this);
296 }
297 
298 
OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & type)299 void H323VideoCodec::OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & type)
300 {
301   switch (type.GetTag()) {
302     case H245_MiscellaneousCommand_type::e_videoFreezePicture :
303       OnFreezePicture();
304       break;
305 
306     case H245_MiscellaneousCommand_type::e_videoFastUpdatePicture :
307       OnFastUpdatePicture();
308       break;
309 
310     case H245_MiscellaneousCommand_type::e_videoFastUpdateGOB :
311     {
312       const H245_MiscellaneousCommand_type_videoFastUpdateGOB & fuGOB = type;
313       OnFastUpdateGOB(fuGOB.m_firstGOB, fuGOB.m_numberOfGOBs);
314       break;
315     }
316 
317     case H245_MiscellaneousCommand_type::e_videoFastUpdateMB :
318     {
319       const H245_MiscellaneousCommand_type_videoFastUpdateMB & fuMB = type;
320       OnFastUpdateMB(fuMB.HasOptionalField(H245_MiscellaneousCommand_type_videoFastUpdateMB::e_firstGOB) ? (int)fuMB.m_firstGOB : -1,
321                      fuMB.HasOptionalField(H245_MiscellaneousCommand_type_videoFastUpdateMB::e_firstMB)  ? (int)fuMB.m_firstMB  : -1,
322                      fuMB.m_numberOfMBs);
323       break;
324     }
325 
326     case H245_MiscellaneousCommand_type::e_lostPartialPicture :
327       OnLostPartialPicture();
328       break;
329 
330     case H245_MiscellaneousCommand_type::e_lostPicture :
331       OnLostPicture();
332       break;
333 
334     case H245_MiscellaneousCommand_type::e_videoTemporalSpatialTradeOff :
335     {
336       const PASN_Integer & newQuality = type;
337       OnVideoTemporalSpatialTradeOffCommand(newQuality);
338       break;
339     }
340   }
341 
342   H323Codec::OnMiscellaneousCommand(type);
343 }
344 
345 
OnFreezePicture()346 void H323VideoCodec::OnFreezePicture()
347 {
348   PTRACE(3, "Codec\tOnFreezePicture()");
349 }
350 
351 
OnFastUpdatePicture()352 void H323VideoCodec::OnFastUpdatePicture()
353 {
354   PTRACE(3, "Codec\tOnFastUpdatePicture()");
355 }
356 
357 
OnFastUpdateGOB(unsigned PTRACE_PARAM (firstGOB),unsigned PTRACE_PARAM (numberOfGOBs))358 void H323VideoCodec::OnFastUpdateGOB(unsigned PTRACE_PARAM(firstGOB),
359                                      unsigned PTRACE_PARAM(numberOfGOBs))
360 {
361   PTRACE(3, "Codecs\tOnFastUpdateGOB(" << firstGOB << ',' << numberOfGOBs << ')');
362 }
363 
364 
OnFastUpdateMB(int PTRACE_PARAM (firstGOB),int PTRACE_PARAM (firstMB),unsigned PTRACE_PARAM (numberOfMBs))365 void H323VideoCodec::OnFastUpdateMB(int PTRACE_PARAM(firstGOB),
366                                     int PTRACE_PARAM(firstMB),
367                                     unsigned PTRACE_PARAM(numberOfMBs))
368 {
369   PTRACE(3, "Codecs\tOnFastUpdateMB(" << firstGOB << ',' << firstMB << ',' << numberOfMBs << ')');
370 }
371 
372 
OnLostPartialPicture()373 void H323VideoCodec::OnLostPartialPicture()
374 {
375   PTRACE(3, "Codec\tOnLostPartialPicture()");
376 }
377 
378 
OnLostPicture()379 void H323VideoCodec::OnLostPicture()
380 {
381   PTRACE(3, "Codec\tOnLostPicture()");
382 }
383 
384 
OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & type)385 void H323VideoCodec::OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & type)
386 {
387   switch (type.GetTag()) {
388     case H245_MiscellaneousIndication_type::e_videoIndicateReadyToActivate :
389       OnVideoIndicateReadyToActivate();
390       break;
391 
392     case H245_MiscellaneousIndication_type::e_videoTemporalSpatialTradeOff :
393     {
394       const PASN_Integer & newQuality = type;
395       OnVideoTemporalSpatialTradeOffIndication(newQuality);
396       break;
397     }
398 
399     case H245_MiscellaneousIndication_type::e_videoNotDecodedMBs :
400     {
401       const H245_MiscellaneousIndication_type_videoNotDecodedMBs & vndMB = type;
402       OnVideoNotDecodedMBs(vndMB.m_firstMB, vndMB.m_numberOfMBs, vndMB.m_temporalReference);
403       break;
404     }
405   }
406 
407   H323Codec::OnMiscellaneousIndication(type);
408 }
409 
410 
OnVideoIndicateReadyToActivate()411 void H323VideoCodec::OnVideoIndicateReadyToActivate()
412 {
413   PTRACE(3, "Codec\tOnVideoIndicateReadyToActivate()");
414 }
415 
416 
OnVideoTemporalSpatialTradeOffCommand(int PTRACE_PARAM (newQuality))417 void H323VideoCodec::OnVideoTemporalSpatialTradeOffCommand(int PTRACE_PARAM(newQuality))
418 {
419   PTRACE(3, "Codecs\tOnVideoTemporalSpatialTradeOffCommand(" << newQuality << ')');
420 }
421 
422 
OnVideoTemporalSpatialTradeOffIndication(int PTRACE_PARAM (newQuality))423 void H323VideoCodec::OnVideoTemporalSpatialTradeOffIndication(int PTRACE_PARAM(newQuality))
424 {
425   PTRACE(3, "Codecs\tOnVideoTemporalSpatialTradeOffIndication(" << newQuality << ')');
426 }
427 
428 
OnVideoNotDecodedMBs(unsigned PTRACE_PARAM (firstMB),unsigned PTRACE_PARAM (numberOfMBs),unsigned PTRACE_PARAM (temporalReference))429 void H323VideoCodec::OnVideoNotDecodedMBs(unsigned PTRACE_PARAM(firstMB),
430                                           unsigned PTRACE_PARAM(numberOfMBs),
431                                           unsigned PTRACE_PARAM(temporalReference))
432 {
433   PTRACE(3, "Codecs\tOnVideoNotDecodedMBs(" << firstMB << ',' << numberOfMBs << ',' << temporalReference << ')');
434 }
435 
436 
Close()437 void H323VideoCodec::Close()
438 {
439   PWaitAndSignal mutex1(videoHandlerActive);
440 
441   CloseRawDataChannel();
442 }
443 
444 
SetMaxBitRate(unsigned bitRate)445 PBoolean H323VideoCodec::SetMaxBitRate(unsigned bitRate)
446 {
447   PTRACE(1,"Set bitRateHighLimit for video to " << bitRate << " bps");
448 
449   bitRateHighLimit = bitRate;
450 
451   if (0 == bitRateHighLimit) // disable bitrate control
452     videoBitRateControlModes &= ~AdaptivePacketDelay;
453 
454   // Set the maximum bit rate for capability exchange
455   GetWritableMediaFormat().SetBandwidth(bitRate);
456   return TRUE;
457 }
458 
SetTargetFrameTimeMs(unsigned ms)459 PBoolean H323VideoCodec::SetTargetFrameTimeMs(unsigned ms)
460 {
461   PTRACE(1,"Set targetFrameTimeMs for video to " << ms << " milliseconds");
462 
463   targetFrameTimeMs = ms;
464 
465   if (0 == targetFrameTimeMs)
466     videoBitRateControlModes &= ~DynamicVideoQuality;
467   return TRUE;
468 }
469 
SetEmphasisSpeed(bool)470 void H323VideoCodec::SetEmphasisSpeed(bool /*speed*/)
471 {
472 
473 }
474 
SetMaxPayloadSize(int)475 void H323VideoCodec::SetMaxPayloadSize(int /*maxSize*/)
476 {
477 
478 }
479 
SetGeneralCodecOption(const char *,int)480 void H323VideoCodec::SetGeneralCodecOption(const char * /*opt*/,  int /*val*/)
481 {
482 }
483 
484 
SendMiscCommand(unsigned command)485 void H323VideoCodec::SendMiscCommand(unsigned command)
486 {
487   if (logicalChannel != NULL)
488     logicalChannel->SendMiscCommand(command);
489 }
490 
SetSupportedFormats(std::list<PVideoFrameInfo> &)491 PBoolean H323VideoCodec::SetSupportedFormats(std::list<PVideoFrameInfo> & /*info*/)
492 {
493     return false;
494 }
495 
496 #endif // H323_VIDEO
497 
498 
499 /////////////////////////////////////////////////////////////////////////////
500 
501 #ifdef H323_AUDIO_CODECS
502 
H323AudioCodec(const OpalMediaFormat & fmt,Direction dir)503 H323AudioCodec::H323AudioCodec(const OpalMediaFormat & fmt, Direction dir)
504   : H323Codec(fmt, dir)
505 {
506   framesReceived = 0;
507   samplesPerFrame = mediaFormat.GetFrameTime() * mediaFormat.GetTimeUnits();
508   if (samplesPerFrame == 0)
509     samplesPerFrame = 8; // Default for non-frame based codecs.
510 
511   // Start off in silent mode
512   inTalkBurst = FALSE;
513 
514   IsRawDataHeld = FALSE;
515 
516   // Initialise the adaptive threshold variables.
517   SetSilenceDetectionMode(AdaptiveSilenceDetection);
518 }
519 
520 
~H323AudioCodec()521 H323AudioCodec::~H323AudioCodec()
522 {
523   Close();
524 
525   CloseRawDataChannel();
526 
527   //mediaFormat.RemoveAllOptions();
528 }
529 
530 
Open(H323Connection & connection)531 PBoolean H323AudioCodec::Open(H323Connection & connection)
532 {
533   return connection.OpenAudioChannel(direction == Encoder, samplesPerFrame*2, *this);
534 }
535 
536 
Close()537 void H323AudioCodec::Close()
538 {
539   //PWaitAndSignal mutex(rawChannelMutex); - TODO: This causes a lockup. Is it needed? -SH
540 
541   if (rawDataChannel != NULL)
542     rawDataChannel->Close();
543 
544 }
545 
546 
GetFrameRate() const547 unsigned H323AudioCodec::GetFrameRate() const
548 {
549   return samplesPerFrame;
550 }
551 
GetFrameTime() const552 unsigned H323AudioCodec::GetFrameTime() const
553 {
554     return mediaFormat.GetFrameTime();
555 }
556 
GetSilenceDetectionMode(PBoolean * isInTalkBurst,unsigned * currentThreshold) const557 H323AudioCodec::SilenceDetectionMode H323AudioCodec::GetSilenceDetectionMode(
558                                 PBoolean * isInTalkBurst, unsigned * currentThreshold) const
559 {
560   if (isInTalkBurst != NULL)
561     *isInTalkBurst = inTalkBurst;
562 
563   if (currentThreshold != NULL)
564     *currentThreshold = ulaw2linear((BYTE)(levelThreshold ^ 0xff));
565 
566   return silenceDetectMode;
567 }
568 
569 
SetSilenceDetectionMode(SilenceDetectionMode mode,unsigned threshold,unsigned signalDeadband,unsigned silenceDeadband,unsigned adaptivePeriod)570 void H323AudioCodec::SetSilenceDetectionMode(SilenceDetectionMode mode,
571                                              unsigned threshold,
572                                              unsigned signalDeadband,
573                                              unsigned silenceDeadband,
574                                              unsigned adaptivePeriod)
575 {
576   silenceDetectMode = mode;
577 
578   // The silence deadband is the number of frames of low energy that have to
579   // occur before the system stops sending data over the RTP link.
580   signalDeadbandFrames = (signalDeadband+samplesPerFrame-1)/samplesPerFrame;
581   silenceDeadbandFrames = (silenceDeadband+samplesPerFrame-1)/samplesPerFrame;
582 
583   // This is the period over which the adaptive algorithm operates
584   adaptiveThresholdFrames = (adaptivePeriod+samplesPerFrame-1)/samplesPerFrame;
585 
586   if (mode != AdaptiveSilenceDetection) {
587     levelThreshold = threshold;
588     return;
589   }
590 
591   // Initials threshold levels
592   levelThreshold = 0;
593 
594   // Initialise the adaptive threshold variables.
595   signalMinimum = UINT_MAX;
596   silenceMaximum = 0;
597   signalFramesReceived = 0;
598   silenceFramesReceived = 0;
599 
600   // Restart in silent mode
601   inTalkBurst = FALSE;
602 }
603 
604 
DetectSilence()605 PBoolean H323AudioCodec::DetectSilence()
606 {
607   // Can never have silence if NoSilenceDetection
608   if (silenceDetectMode == NoSilenceDetection)
609     return FALSE;
610 
611   // Can never have average signal level that high, this indicates that the
612   // hardware cannot do silence detection.
613   unsigned level = GetAverageSignalLevel();
614   if (level == UINT_MAX)
615     return FALSE;
616 
617   // Convert to a logarithmic scale - use uLaw which is complemented
618   level = linear2ulaw(level) ^ 0xff;
619 
620   // Now if signal level above threshold we are "talking"
621   PBoolean haveSignal = level > levelThreshold;
622 
623   // If no change ie still talking or still silent, resent frame counter
624   if (inTalkBurst == haveSignal)
625     framesReceived = 0;
626   else {
627     framesReceived++;
628     // If have had enough consecutive frames talking/silent, swap modes.
629     if (framesReceived >= (inTalkBurst ? silenceDeadbandFrames : signalDeadbandFrames)) {
630       inTalkBurst = !inTalkBurst;
631       PTRACE(4, "Codec\tSilence detection transition: "
632              << (inTalkBurst ? "Talk" : "Silent")
633              << " level=" << level << " threshold=" << levelThreshold);
634 
635       // If we had talk/silence transition restart adaptive threshold measurements
636       signalMinimum = UINT_MAX;
637       silenceMaximum = 0;
638       signalFramesReceived = 0;
639       silenceFramesReceived = 0;
640     }
641   }
642 
643   if (silenceDetectMode == FixedSilenceDetection)
644     return !inTalkBurst;
645 
646   if (levelThreshold == 0) {
647     if (level > 1) {
648       // Bootstrap condition, use first frame level as silence level
649       levelThreshold = level/2;
650       PTRACE(4, "Codec\tSilence detection threshold initialised to: " << levelThreshold);
651     }
652     return TRUE; // inTalkBurst always FALSE here, so return silent
653   }
654 
655   // Count the number of silent and signal frames and calculate min/max
656   if (haveSignal) {
657     if (level < signalMinimum)
658       signalMinimum = level;
659     signalFramesReceived++;
660   }
661   else {
662     if (level > silenceMaximum)
663       silenceMaximum = level;
664     silenceFramesReceived++;
665   }
666 
667   // See if we have had enough frames to look at proportions of silence/signal
668   if ((signalFramesReceived + silenceFramesReceived) > adaptiveThresholdFrames) {
669 
670     /* Now we have had a period of time to look at some average values we can
671        make some adjustments to the threshold. There are four cases:
672      */
673     if (signalFramesReceived >= adaptiveThresholdFrames) {
674       /* If every frame was noisy, move threshold up. Don't want to move too
675          fast so only go a quarter of the way to minimum signal value over the
676          period. This avoids oscillations, and time will continue to make the
677          level go up if there really is a lot of background noise.
678        */
679       int delta = (signalMinimum - levelThreshold)/4;
680       if (delta != 0) {
681         levelThreshold += delta;
682         PTRACE(4, "Codec\tSilence detection threshold increased to: " << levelThreshold);
683       }
684     }
685     else if (silenceFramesReceived >= adaptiveThresholdFrames) {
686       /* If every frame was silent, move threshold down. Again do not want to
687          move too quickly, but we do want it to move faster down than up, so
688          move to halfway to maximum value of the quiet period. As a rule the
689          lower the threshold the better as it would improve response time to
690          the start of a talk burst.
691        */
692       unsigned newThreshold = (levelThreshold + silenceMaximum)/2 + 1;
693       if (levelThreshold != newThreshold) {
694         levelThreshold = newThreshold;
695         PTRACE(4, "Codec\tSilence detection threshold decreased to: " << levelThreshold);
696       }
697     }
698     else if (signalFramesReceived > silenceFramesReceived) {
699       /* We haven't got a definitive silent or signal period, but if we are
700          constantly hovering at the threshold and have more signal than
701          silence we should creep up a bit.
702        */
703       levelThreshold++;
704       PTRACE(4, "Codec\tSilence detection threshold incremented to: " << levelThreshold
705              << " signal=" << signalFramesReceived << ' ' << signalMinimum
706              << " silence=" << silenceFramesReceived << ' ' << silenceMaximum);
707     }
708 
709     signalMinimum = UINT_MAX;
710     silenceMaximum = 0;
711     signalFramesReceived = 0;
712     silenceFramesReceived = 0;
713   }
714 
715   return !inTalkBurst;
716 }
717 
718 
GetAverageSignalLevel()719 unsigned H323AudioCodec::GetAverageSignalLevel()
720 {
721   return UINT_MAX;
722 }
723 
SetRawDataHeld(PBoolean hold)724 PBoolean H323AudioCodec::SetRawDataHeld(PBoolean hold) {
725 
726   PTimedMutex m;
727 	m.Wait(50);    // wait for 50ms to avoid current locks
728 	IsRawDataHeld = hold;
729 	m.Wait(50); 	// wait for 50ms to avoid any further locks
730 	return TRUE;
731 }
732 
733 /////////////////////////////////////////////////////////////////////////////
734 
H323FramedAudioCodec(const OpalMediaFormat & fmt,Direction dir)735 H323FramedAudioCodec::H323FramedAudioCodec(const OpalMediaFormat & fmt, Direction dir)
736   : H323AudioCodec(fmt, dir),
737 #ifdef H323_AEC
738     aec(NULL),
739 #endif
740     sampleBuffer(samplesPerFrame), bytesPerFrame(mediaFormat.GetFrameSize()),
741     readBytes(samplesPerFrame*2), writeBytes(samplesPerFrame*2), cntBytes(0)
742 {
743 
744 }
745 
746 
Read(BYTE * buffer,unsigned & length,RTP_DataFrame &)747 PBoolean H323FramedAudioCodec::Read(BYTE * buffer, unsigned & length, RTP_DataFrame &)
748 {
749   PWaitAndSignal mutex(rawChannelMutex);
750 
751   if (direction != Encoder) {
752     PTRACE(1, "Codec\tAttempt to decode from encoder");
753     return FALSE;
754   }
755 
756   if (IsRawDataHeld) {	 // If connection is onHold
757     PThread::Sleep(5);  // Sleep to avoid CPU overload. <--Should be a better method but it works :)
758     length = 0;
759     return TRUE;
760   }
761 
762 #ifdef H323_MEDIAENCODED
763     bool lastPacket = true;
764     if (rawDataChannel->SourceEncoded(lastPacket,length))
765         return rawDataChannel->Read(buffer, length);
766 #endif
767 
768   if (!ReadRaw(sampleBuffer.GetPointer(samplesPerFrame), readBytes, cntBytes))
769     return FALSE;
770 
771 #ifdef H323_AEC
772     if (aec != NULL) {
773        PTRACE(6,"AEC\tSend " << readBytes);
774        aec->Send((BYTE*)sampleBuffer.GetPointer(samplesPerFrame),(unsigned &)readBytes);
775     }
776 #endif
777 
778   if (IsRawDataHeld) {
779     length = 0;
780     return TRUE;
781   }
782 
783   if (cntBytes != readBytes) {
784     PTRACE(1, "Codec\tRead truncated frame of raw data. Wanted " << readBytes << " and got "<< cntBytes);
785     return FALSE;
786   }
787   cntBytes = 0;
788 
789   if (DetectSilence()) {
790     length = 0;
791     return TRUE;
792   }
793 
794   // Default length is the frame size
795   length = bytesPerFrame;
796   return EncodeFrame(buffer, length);
797 }
798 
799 WORD lastSequence=0;
Write(const BYTE * buffer,unsigned length,const RTP_DataFrame & rtpFrame,unsigned & written)800 PBoolean H323FramedAudioCodec::Write(const BYTE * buffer,
801                                  unsigned length,
802                                  const RTP_DataFrame & rtpFrame,
803                                  unsigned & written
804                                  )
805 {
806   PWaitAndSignal mutex(rawChannelMutex);
807 
808   if (direction != Decoder) {
809     PTRACE(1, "Codec\tAttempt to encode from decoder");
810     return FALSE;
811   }
812 
813   // If length is zero then it indicates silence, do nothing.
814   written = 0;
815 
816   // Prepare AVSync Information
817   rtpInformation.m_frameLost = (lastSequence > 0) ? rtpFrame.GetSequenceNumber() -lastSequence-1 : 0;
818         lastSequence = rtpFrame.GetSequenceNumber();
819         rtpInformation.m_recvTime = PTimer::Tick().GetMilliSeconds();
820         rtpInformation.m_timeStamp = rtpFrame.GetTimestamp();
821         rtpInformation.m_clockRate = GetFrameRate();
822         CalculateRTPSendTime(rtpInformation.m_timeStamp, rtpInformation.m_clockRate, rtpInformation.m_sendTime);
823         rtpInformation.m_frame = &rtpFrame;
824 
825 
826 #ifdef H323_MEDIAENCODED
827   if (rawDataChannel->DisableDecode()) {
828       if (WriteRaw(rtpFrame.GetPayloadPtr(), rtpFrame.GetPayloadSize(), &rtpInformation))  {
829          written = length; // pretend we wrote the data, to avoid error message
830          return TRUE;
831       } else
832          return FALSE;
833   }
834 #endif
835 
836   if (length != 0) {
837     if (length > bytesPerFrame)
838       length = bytesPerFrame;
839     written = bytesPerFrame;
840 
841     // Decode the data
842     if (!DecodeFrame(buffer, length, written, writeBytes)) {
843       written = length;
844       length = 0;
845     }
846   }
847 
848   if (length == 0)
849     DecodeSilenceFrame(sampleBuffer.GetPointer(), writeBytes);
850 
851   // Write as 16bit PCM to sound channel
852   if (IsRawDataHeld) {		// If Connection om Hold
853     PThread::Sleep(5);	// Sleep to avoid CPU Overload <--- Must be a better way but need it to work.
854     return TRUE;
855   } else {
856 #ifdef H323_AEC
857       if (aec != NULL) {
858          PTRACE(6,"AEC\tReceive " << writeBytes);
859          aec->Receive((BYTE *)sampleBuffer.GetPointer(), writeBytes);
860       }
861 #endif
862       if (!WriteRaw(sampleBuffer.GetPointer(), writeBytes, &rtpInformation))
863           return FALSE;
864   }
865       return TRUE;
866 
867 
868 }
869 
870 
GetAverageSignalLevel()871 unsigned H323FramedAudioCodec::GetAverageSignalLevel()
872 {
873   if (!samplesPerFrame)
874       return 0;
875 
876   // Calculate the average signal level of this frame
877   int sum = 0;
878 
879   const short * pcm = sampleBuffer;
880   const short * end = pcm + samplesPerFrame;
881   while (pcm != end) {
882     if (*pcm < 0)
883       sum -= *pcm++;
884     else
885       sum += *pcm++;
886   }
887 
888   return sum/samplesPerFrame;
889 }
890 
891 
DecodeFrame(const BYTE * buffer,unsigned length,unsigned & written,unsigned &)892 PBoolean H323FramedAudioCodec::DecodeFrame(const BYTE * buffer,
893                                        unsigned length,
894                                        unsigned & written,
895                                        unsigned & /*decodedBytes*/)
896 {
897   return DecodeFrame(buffer, length, written);
898 }
899 
900 
DecodeFrame(const BYTE *,unsigned,unsigned &)901 PBoolean H323FramedAudioCodec::DecodeFrame(const BYTE * /*buffer*/,
902                                        unsigned /*length*/,
903                                        unsigned & /*written*/)
904 {
905   PAssertAlways(PUnimplementedFunction);
906   return FALSE;
907 }
908 
909 #ifdef H323_AEC
AttachAEC(H323Aec * _aec)910 void H323FramedAudioCodec::AttachAEC(H323Aec * _aec)
911 {
912   aec = _aec;
913 }
914 #endif
915 
916 /////////////////////////////////////////////////////////////////////////////
917 
H323StreamedAudioCodec(const OpalMediaFormat & fmt,Direction dir,unsigned samples,unsigned bits)918 H323StreamedAudioCodec::H323StreamedAudioCodec(const OpalMediaFormat & fmt,
919                                                Direction dir,
920                                                unsigned samples,
921                                                unsigned bits)
922   : H323FramedAudioCodec(fmt, dir)
923 {
924 
925   if (samplesPerFrame != samples) {
926     samplesPerFrame = samples;
927     readBytes = samplesPerFrame*2;
928     writeBytes = samplesPerFrame*2;
929     sampleBuffer.SetSize(samplesPerFrame*2);
930     mediaFormat.SetFrameTime(samples/bits*1000);
931     mediaFormat.SetFrameSize(samplesPerFrame*2);
932   }
933 
934   bytesPerFrame = (samples*bits+7)/8;
935   bitsPerSample = bits;
936 }
937 
938 
EncodeFrame(BYTE * buffer,unsigned &)939 PBoolean H323StreamedAudioCodec::EncodeFrame(BYTE * buffer, unsigned &)
940 {
941   PINDEX i;
942   unsigned short position = 0;
943   BYTE encoded;
944   switch (bitsPerSample) {
945     case 8 :
946       for (i = 0; i < (PINDEX)samplesPerFrame; i++)
947         *buffer++ = (BYTE)Encode(sampleBuffer[i]);
948       break;
949     case 5 : // g.726-40 payload encoding....
950       for (i = 0; i < (PINDEX)samplesPerFrame;i++)
951       {
952         // based on a 40 bits encoding, we have 8 words of 5 bits each
953         encoded = (BYTE)Encode(sampleBuffer[i]);
954         switch(position)
955         {
956           case 0: // 0 bits overflow
957             *buffer = encoded;
958             position++;
959             break;
960           case 1: // 2 bits overflow
961             *buffer++ |= (encoded << 5);
962             *buffer = (BYTE)(encoded >> 3);
963             position++;
964             break;
965           case 2:
966             *buffer |= (encoded << 2);
967             position++;
968             break;
969           case 3: // one bit left for word 4
970             *buffer++ |= (encoded << 7);
971             *buffer = (BYTE)(encoded >> 1);
972             position++;
973             break;
974           case 4:
975             *buffer++ |= (encoded << 4);
976             *buffer = (BYTE)(encoded >> 4);
977             position++;
978             break;
979           case 5:
980             *buffer |= (encoded << 1);
981             position++;
982             break;
983           case 6: //two bits left for the new encoded word
984             *buffer++ |= (encoded << 6);
985             *buffer =  (BYTE)(encoded >> 2);
986             position++;
987             break;
988           case 7: // now five bits left for the last word
989             *buffer++ |= (encoded << 3);
990             position = 0;
991             break;
992         }
993       }
994       break;
995 
996     case 4 :
997       for (i = 0; i < (PINDEX)samplesPerFrame; i++) {
998         if ((i&1) == 0)
999           *buffer = (BYTE)Encode(sampleBuffer[i]);
1000         else
1001           *buffer++ |= (BYTE)(Encode(sampleBuffer[i]) << 4);
1002       }
1003       break;
1004 
1005     case 3 :
1006       for (i = 0;i < (PINDEX)samplesPerFrame;i++)
1007       {
1008         encoded = (BYTE)Encode(sampleBuffer[i]);
1009         switch(position)
1010         {
1011           case 0: // 0 bits overflow
1012             *buffer = encoded;
1013             position++;
1014             break;
1015           case 1: // 2 bits overflow
1016             *buffer |= (encoded << 3);
1017             position++;
1018             break;
1019           case 2:
1020             *buffer++ |= (encoded << 6);
1021             *buffer = (BYTE)(encoded >> 2);
1022             position++;
1023             break;
1024           case 3: // one bit left for word 4
1025             *buffer |= (encoded << 1);
1026             position++;
1027             break;
1028           case 4:
1029             *buffer |= (encoded << 4);
1030             position++;
1031             break;
1032           case 5:
1033             *buffer++ |= (encoded << 7);
1034             *buffer = (BYTE)(encoded >> 1);
1035             position++;
1036             break;
1037           case 6: //two bits left for the new encoded word
1038             *buffer |= (encoded << 2);
1039             position++;
1040             break;
1041           case 7: // now five bits left for the last word
1042             *buffer++ |= (encoded << 5);
1043             position = 0;
1044             break;
1045         }
1046       }
1047       break;
1048 
1049     case 2:
1050       for (i = 0; i < (PINDEX)samplesPerFrame; i++)
1051       {
1052         switch(position)
1053         {
1054           case 0:
1055             *buffer = (BYTE)Encode(sampleBuffer[i]);
1056             position++;
1057             break;
1058           case 1:
1059             *buffer |= (BYTE)(Encode(sampleBuffer[i]) << 2);
1060             position++;
1061             break;
1062           case 2:
1063             *buffer |= (BYTE)(Encode(sampleBuffer[i]) << 4);
1064             position++;
1065             break;
1066           case 3:
1067             *buffer++ |= (BYTE)(Encode(sampleBuffer[i]) << 6);
1068             position = 0;
1069             break;
1070         }
1071       }
1072       break;
1073 
1074     default :
1075       PTRACE(1, "Codec\tUnsupported bit size");
1076       return FALSE;
1077   }
1078 
1079   return TRUE;
1080 }
1081 
1082 
DecodeFrame(const BYTE * buffer,unsigned length,unsigned & written,unsigned & decodedBytes)1083 PBoolean H323StreamedAudioCodec::DecodeFrame(const BYTE * buffer,
1084                                          unsigned length,
1085                                          unsigned & written,
1086                                          unsigned & decodedBytes)
1087 {
1088   unsigned i;
1089 
1090   short * sampleBufferPtr = sampleBuffer.GetPointer(samplesPerFrame);
1091   short * out = sampleBufferPtr;
1092   unsigned short position = 0;
1093   unsigned remaining = 0;
1094 
1095   switch (bitsPerSample) {
1096     case 8 :
1097       for (i = 0; i < length; i++)
1098         *out++ = Decode(*buffer++);
1099       break;
1100 
1101     // those case are for ADPCM G.726
1102     case 5 :
1103       for (i = 0; i < length; i++) {
1104         switch(position)
1105         {
1106           case 0:
1107             *out++ = Decode(*buffer & 31);
1108             remaining = *buffer >> 5; // get the three remaining bytes for the next word
1109             buffer++;
1110             position++;
1111             break;
1112           case 1: // we can decode more than one word in second buffer
1113             *out++ = Decode (((*buffer&3) << 3) | remaining);
1114             *out++ = Decode( (*buffer >> 2) & 31);
1115             remaining = *buffer >> 7;
1116             buffer++;
1117             position++;
1118             break;
1119           case 2:
1120             *out++ = Decode( remaining | ((*buffer&15) << 1));
1121             remaining = *buffer >> 4;
1122             buffer++;
1123             position++;
1124             break;
1125           case 3:
1126             *out++ = Decode( remaining | ((*buffer&1) << 4));
1127             *out++ = Decode( (*buffer >> 1) & 31);
1128             remaining = *buffer >> 6;
1129             buffer++;
1130             position++;
1131             break;
1132           case 4 :
1133             *out++ = Decode( remaining | ((*buffer&7) << 2));
1134             *out++ = Decode(*buffer >> 3);
1135             buffer++;
1136             position = 0;
1137             break;
1138         }
1139       }
1140       break;
1141 
1142     case 4 :
1143       for (i = 0; i < length; i++) {
1144         *out++ = Decode(*buffer & 15);
1145         *out++ = Decode(*buffer >> 4);
1146         buffer++;
1147       }
1148       break;
1149 
1150     case 3:
1151       for (i = 0; i < length; i++) {
1152         switch(position)
1153         {
1154         case 0:
1155           *out++ = Decode(*buffer & 7);
1156           *out++ = Decode((*buffer>>3)&7);
1157           remaining = *buffer >> 6;
1158           buffer++;
1159           position++;
1160           break;
1161         case 1:
1162           *out++ = Decode(remaining | ((*buffer&1) << 2));
1163           *out++ = Decode((*buffer >> 1) & 7);
1164           *out++ = Decode((*buffer >> 4)&7);
1165           remaining = *buffer >> 7;
1166           buffer++;
1167           position++;
1168           break;
1169         case 2:
1170           *out++ = Decode(remaining | ((*buffer&3) << 1));
1171           *out++ = Decode((*buffer >> 2) & 7);
1172           *out++ = Decode((*buffer >> 5) & 7);
1173           buffer++;
1174           position = 0;
1175           break;
1176         }
1177       }
1178       break;
1179 
1180     case 2:
1181       for (i = 0; i < length; i++)
1182       {
1183         *out++ = Decode(*buffer & 3);
1184         *out++ = Decode((*buffer >> 2) & 3);
1185         *out++ = Decode((*buffer >> 4) & 3);
1186         *out++ = Decode((*buffer >> 6) & 3);
1187         buffer++;
1188 
1189       }
1190       break;
1191 
1192     default :
1193       PTRACE(1, "Codec\tUnsupported bit size");
1194       return FALSE;
1195   }
1196 
1197   written = length;
1198   decodedBytes = (out - sampleBufferPtr)*2;
1199 
1200   return TRUE;
1201 }
1202 
1203 
1204 /////////////////////////////////////////////////////////////////////////////
1205 
H323_ALawCodec(Direction dir,PBoolean at56kbps,unsigned frameSize)1206 H323_ALawCodec::H323_ALawCodec(Direction dir,
1207                                PBoolean at56kbps,
1208                                unsigned frameSize)
1209   : H323StreamedAudioCodec(OpalG711ALaw, dir, frameSize, 8)
1210 {
1211   sevenBit = at56kbps;
1212 
1213   PTRACE(3, "Codec\tG711 ALaw " << (dir == Encoder ? "en" : "de")
1214          << "coder created for at "
1215          << (sevenBit ? "56k" : "64k") << ", " << frameSize << " samples");
1216 }
1217 
1218 
1219 
EncodeSample(short sample)1220 int H323_ALawCodec::EncodeSample(short sample)
1221 {
1222   return linear2alaw(sample);
1223 }
1224 
1225 
DecodeSample(int sample)1226 short H323_ALawCodec::DecodeSample(int sample)
1227 {
1228   return (short)alaw2linear((unsigned char)sample);
1229 }
1230 
1231 
1232 /////////////////////////////////////////////////////////////////////////////
1233 
H323_muLawCodec(Direction dir,PBoolean at56kbps,unsigned frameSize)1234 H323_muLawCodec::H323_muLawCodec(Direction dir,
1235                                  PBoolean at56kbps,
1236                                  unsigned frameSize)
1237   : H323StreamedAudioCodec(OpalG711uLaw, dir, frameSize, 8)
1238 {
1239   sevenBit = at56kbps;
1240 
1241   PTRACE(3, "Codec\tG711 uLaw " << (dir == Encoder ? "en" : "de")
1242          << "coder created for at "
1243          << (sevenBit ? "56k" : "64k") << ", frame of " << frameSize << " samples");
1244 }
1245 
1246 
EncodeSample(short sample)1247 int H323_muLawCodec::EncodeSample(short sample)
1248 {
1249   return linear2ulaw(sample);
1250 }
1251 
1252 
DecodeSample(int sample)1253 short H323_muLawCodec::DecodeSample(int sample)
1254 {
1255   return (short)ulaw2linear((unsigned char)sample);
1256 }
1257 
1258 
1259 /////////////////////////////////////////////////////////////////////////////
1260 
1261 #endif // NO_H323_AUDIO_CODECS
1262