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