00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 #include <ptlib.h>
00362
00363 #ifdef __GNUC__
00364 #pragma implementation "codecs.h"
00365 #endif
00366
00367 #include "codecs.h"
00368
00369 #include "channels.h"
00370 #include "h323pdu.h"
00371 #include "h323con.h"
00372
00373 #ifdef H323_AEC
00374 #include <ptclib/paec.h>
00375
00376 #ifdef _DEBUG
00377 #pragma comment(lib,"paecd.lib")
00378 #else
00379 #pragma comment(lib,"paec.lib")
00380 #endif
00381
00382 #endif
00383
00384 #define new PNEW
00385
00386
00387 extern "C" {
00388 unsigned char linear2ulaw(int pcm_val);
00389 int ulaw2linear(unsigned char u_val);
00390 unsigned char linear2alaw(int pcm_val);
00391 int alaw2linear(unsigned char u_val);
00392 };
00393
00394
00396
00397 H323Codec::H323Codec(const OpalMediaFormat & fmt, Direction dir)
00398 : mediaFormat(fmt)
00399 {
00400 logicalChannel = NULL;
00401 direction = dir;
00402
00403 lastSequenceNumber = 1;
00404 rawDataChannel = NULL;
00405 deleteChannel = FALSE;
00406 }
00407
00408
00409 BOOL H323Codec::Open(H323Connection & )
00410 {
00411 return TRUE;
00412 }
00413
00414
00415 unsigned H323Codec::GetFrameRate() const
00416 {
00417 return mediaFormat.GetFrameTime();
00418 }
00419
00420
00421 void H323Codec::OnFlowControl(long PTRACE_PARAM(bitRateRestriction))
00422 {
00423 PTRACE(3, "Codec\tOnFlowControl: " << bitRateRestriction);
00424 }
00425
00426
00427 void H323Codec::OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & PTRACE_PARAM(type))
00428 {
00429 PTRACE(3, "Codec\tOnMiscellaneousCommand: " << type.GetTagName());
00430 }
00431
00432
00433 void H323Codec::OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & PTRACE_PARAM(type))
00434 {
00435 PTRACE(3, "Codec\tOnMiscellaneousIndication: " << type.GetTagName());
00436 }
00437
00438
00439 BOOL H323Codec::AttachChannel(PChannel * channel, BOOL autoDelete)
00440 {
00441 PWaitAndSignal mutex(rawChannelMutex);
00442
00443 CloseRawDataChannel();
00444
00445 rawDataChannel = channel;
00446 deleteChannel = autoDelete;
00447
00448 if (channel == NULL){
00449 PTRACE(3, "Codec\tError attaching channel. channel is NULL");
00450 return FALSE;
00451 }
00452
00453 return channel->IsOpen();
00454 }
00455
00456 PChannel * H323Codec::SwapChannel(PChannel * newChannel, BOOL autoDelete)
00457 {
00458 PWaitAndSignal mutex(rawChannelMutex);
00459
00460 PChannel * oldChannel = rawDataChannel;
00461
00462 rawDataChannel = newChannel;
00463 deleteChannel = autoDelete;
00464
00465 return oldChannel;
00466 }
00467
00468
00469 BOOL H323Codec::CloseRawDataChannel()
00470 {
00471 if (rawDataChannel == NULL)
00472 return FALSE;
00473
00474 BOOL closeOK = rawDataChannel->Close();
00475
00476 if (deleteChannel) {
00477 delete rawDataChannel;
00478 rawDataChannel = NULL;
00479 }
00480
00481 return closeOK;
00482 }
00483
00484
00485 BOOL H323Codec::IsRawDataChannelNative() const
00486 {
00487 return FALSE;
00488 }
00489
00490
00491 BOOL H323Codec::ReadRaw(void * data, PINDEX size, PINDEX & length)
00492 {
00493 if (rawDataChannel == NULL) {
00494 PTRACE(1, "Codec\tNo audio channel for read");
00495 return FALSE;
00496 }
00497
00498 if (!rawDataChannel->Read(data, size)) {
00499 PTRACE(1, "Codec\tAudio read failed: " << rawDataChannel->GetErrorText(PChannel::LastReadError));
00500 return FALSE;
00501 }
00502
00503 length = rawDataChannel->GetLastReadCount();
00504
00505 for (PINDEX i = 0; i < filters.GetSize(); i++) {
00506 FilterInfo info(*this, data, size, length);
00507 filters[i](info, 0);
00508 length = info.bufferLength;
00509 }
00510
00511 return TRUE;
00512 }
00513
00514
00515 BOOL H323Codec::WriteRaw(void * data, PINDEX length)
00516 {
00517 if (rawDataChannel == NULL) {
00518 PTRACE(1, "Codec\tNo audio channel for write");
00519 return FALSE;
00520 }
00521
00522 for (PINDEX i = 0; i < filters.GetSize(); i++) {
00523 FilterInfo info(*this, data, length, length);
00524 filters[i](info, 0);
00525 length = info.bufferLength;
00526 }
00527
00528 if (rawDataChannel->Write(data, length))
00529 return TRUE;
00530
00531 PTRACE(1, "Codec\tWrite failed: " << rawDataChannel->GetErrorText(PChannel::LastWriteError));
00532 return FALSE;
00533 }
00534
00535
00536 BOOL H323Codec::AttachLogicalChannel(H323Channel *channel)
00537 {
00538 logicalChannel = channel;
00539
00540 return TRUE;
00541 }
00542
00543
00544 void H323Codec::AddFilter(const PNotifier & notifier)
00545 {
00546 rawChannelMutex.Wait();
00547 filters.Append(new PNotifier(notifier));
00548 rawChannelMutex.Signal();
00549 }
00550
00551 BOOL H323Codec::SetRawDataHeld(BOOL )
00552 {
00553 return FALSE;
00554 }
00555
00557
00558 #ifdef H323_VIDEO
00559
00560 H323VideoCodec::H323VideoCodec(const OpalMediaFormat & fmt, Direction dir)
00561 : H323Codec(fmt, dir)
00562 {
00563 frameWidth = frameHeight = 0;
00564 targetFrameTimeMs = 0;
00565 videoBitRateControlModes = None;
00566
00567 oldLength = 0;
00568 oldTime = 0;
00569 newTime = 0;
00570 }
00571
00572
00573 H323VideoCodec::~H323VideoCodec()
00574 {
00575 Close();
00576 }
00577
00578
00579 BOOL H323VideoCodec::Open(H323Connection & connection)
00580 {
00581 #ifdef H323_H239
00582 if (logicalChannel->GetSessionID() == OpalMediaFormat::DefaultExtVideoSessionID)
00583 return connection.OpenExtendedVideoChannel(direction == Encoder, *this);
00584 else
00585 #endif
00586 return connection.OpenVideoChannel(direction == Encoder, *this);
00587 }
00588
00589
00590 void H323VideoCodec::OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & type)
00591 {
00592 switch (type.GetTag()) {
00593 case H245_MiscellaneousCommand_type::e_videoFreezePicture :
00594 OnFreezePicture();
00595 break;
00596
00597 case H245_MiscellaneousCommand_type::e_videoFastUpdatePicture :
00598 OnFastUpdatePicture();
00599 break;
00600
00601 case H245_MiscellaneousCommand_type::e_videoFastUpdateGOB :
00602 {
00603 const H245_MiscellaneousCommand_type_videoFastUpdateGOB & fuGOB = type;
00604 OnFastUpdateGOB(fuGOB.m_firstGOB, fuGOB.m_numberOfGOBs);
00605 break;
00606 }
00607
00608 case H245_MiscellaneousCommand_type::e_videoFastUpdateMB :
00609 {
00610 const H245_MiscellaneousCommand_type_videoFastUpdateMB & fuMB = type;
00611 OnFastUpdateMB(fuMB.HasOptionalField(H245_MiscellaneousCommand_type_videoFastUpdateMB::e_firstGOB) ? (int)fuMB.m_firstGOB : -1,
00612 fuMB.HasOptionalField(H245_MiscellaneousCommand_type_videoFastUpdateMB::e_firstMB) ? (int)fuMB.m_firstMB : -1,
00613 fuMB.m_numberOfMBs);
00614 break;
00615 }
00616
00617 case H245_MiscellaneousCommand_type::e_lostPartialPicture :
00618 OnLostPartialPicture();
00619 break;
00620
00621 case H245_MiscellaneousCommand_type::e_lostPicture :
00622 OnLostPicture();
00623 break;
00624
00625 case H245_MiscellaneousCommand_type::e_videoTemporalSpatialTradeOff :
00626 {
00627 const PASN_Integer & newQuality = type;
00628 OnVideoTemporalSpatialTradeOffCommand(newQuality);
00629 break;
00630 }
00631 }
00632
00633 H323Codec::OnMiscellaneousCommand(type);
00634 }
00635
00636
00637 void H323VideoCodec::OnFreezePicture()
00638 {
00639 PTRACE(3, "Codec\tOnFreezePicture()");
00640 }
00641
00642
00643 void H323VideoCodec::OnFastUpdatePicture()
00644 {
00645 PTRACE(3, "Codec\tOnFastUpdatePicture()");
00646 }
00647
00648
00649 void H323VideoCodec::OnFastUpdateGOB(unsigned PTRACE_PARAM(firstGOB),
00650 unsigned PTRACE_PARAM(numberOfGOBs))
00651 {
00652 PTRACE(3, "Codecs\tOnFastUpdateGOB(" << firstGOB << ',' << numberOfGOBs << ')');
00653 }
00654
00655
00656 void H323VideoCodec::OnFastUpdateMB(int PTRACE_PARAM(firstGOB),
00657 int PTRACE_PARAM(firstMB),
00658 unsigned PTRACE_PARAM(numberOfMBs))
00659 {
00660 PTRACE(3, "Codecs\tOnFastUpdateMB(" << firstGOB << ',' << firstMB << ',' << numberOfMBs << ')');
00661 }
00662
00663
00664 void H323VideoCodec::OnLostPartialPicture()
00665 {
00666 PTRACE(3, "Codec\tOnLostPartialPicture()");
00667 }
00668
00669
00670 void H323VideoCodec::OnLostPicture()
00671 {
00672 PTRACE(3, "Codec\tOnLostPicture()");
00673 }
00674
00675
00676 void H323VideoCodec::OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & type)
00677 {
00678 switch (type.GetTag()) {
00679 case H245_MiscellaneousIndication_type::e_videoIndicateReadyToActivate :
00680 OnVideoIndicateReadyToActivate();
00681 break;
00682
00683 case H245_MiscellaneousIndication_type::e_videoTemporalSpatialTradeOff :
00684 {
00685 const PASN_Integer & newQuality = type;
00686 OnVideoTemporalSpatialTradeOffIndication(newQuality);
00687 break;
00688 }
00689
00690 case H245_MiscellaneousIndication_type::e_videoNotDecodedMBs :
00691 {
00692 const H245_MiscellaneousIndication_type_videoNotDecodedMBs & vndMB = type;
00693 OnVideoNotDecodedMBs(vndMB.m_firstMB, vndMB.m_numberOfMBs, vndMB.m_temporalReference);
00694 break;
00695 }
00696 }
00697
00698 H323Codec::OnMiscellaneousIndication(type);
00699 }
00700
00701
00702 void H323VideoCodec::OnVideoIndicateReadyToActivate()
00703 {
00704 PTRACE(3, "Codec\tOnVideoIndicateReadyToActivate()");
00705 }
00706
00707
00708 void H323VideoCodec::OnVideoTemporalSpatialTradeOffCommand(int PTRACE_PARAM(newQuality))
00709 {
00710 PTRACE(3, "Codecs\tOnVideoTemporalSpatialTradeOffCommand(" << newQuality << ')');
00711 }
00712
00713
00714 void H323VideoCodec::OnVideoTemporalSpatialTradeOffIndication(int PTRACE_PARAM(newQuality))
00715 {
00716 PTRACE(3, "Codecs\tOnVideoTemporalSpatialTradeOffIndication(" << newQuality << ')');
00717 }
00718
00719
00720 void H323VideoCodec::OnVideoNotDecodedMBs(unsigned PTRACE_PARAM(firstMB),
00721 unsigned PTRACE_PARAM(numberOfMBs),
00722 unsigned PTRACE_PARAM(temporalReference))
00723 {
00724 PTRACE(3, "Codecs\tOnVideoNotDecodedMBs(" << firstMB << ',' << numberOfMBs << ',' << temporalReference << ')');
00725 }
00726
00727
00728 void H323VideoCodec::Close()
00729 {
00730 PWaitAndSignal mutex1(videoHandlerActive);
00731
00732 CloseRawDataChannel();
00733 }
00734
00735
00736 BOOL H323VideoCodec::SetMaxBitRate(unsigned bitRate)
00737 {
00738 PTRACE(1,"Set bitRateHighLimit for video to " << bitRate << " bps");
00739
00740 bitRateHighLimit = bitRate;
00741
00742 if (0 == bitRateHighLimit)
00743 videoBitRateControlModes &= ~AdaptivePacketDelay;
00744 return TRUE;
00745 }
00746
00747 BOOL H323VideoCodec::SetTargetFrameTimeMs(unsigned ms)
00748 {
00749 PTRACE(1,"Set targetFrameTimeMs for video to " << ms << " milliseconds");
00750
00751 targetFrameTimeMs = ms;
00752
00753 if (0 == targetFrameTimeMs)
00754 videoBitRateControlModes &= ~DynamicVideoQuality;
00755 return TRUE;
00756 }
00757
00758 void H323VideoCodec::SetGeneralCodecOption(const char * , int )
00759 {
00760 }
00761
00762
00763 void H323VideoCodec::SendMiscCommand(unsigned command)
00764 {
00765 if (logicalChannel != NULL)
00766 logicalChannel->SendMiscCommand(command);
00767 }
00768
00769
00770 #endif // NO_H323_VIDEO
00771
00772
00774
00775 #ifndef NO_H323_AUDIO_CODECS
00776
00777 H323AudioCodec::H323AudioCodec(const OpalMediaFormat & fmt, Direction dir)
00778 : H323Codec(fmt, dir)
00779 {
00780 samplesPerFrame = (mediaFormat.GetFrameTime() * mediaFormat.GetTimeUnits()) / 8;
00781 if (samplesPerFrame == 0)
00782 samplesPerFrame = 8;
00783
00784
00785 inTalkBurst = FALSE;
00786
00787 IsRawDataHeld = FALSE;
00788
00789
00790 SetSilenceDetectionMode(AdaptiveSilenceDetection);
00791 }
00792
00793
00794 H323AudioCodec::~H323AudioCodec()
00795 {
00796 Close();
00797
00798 CloseRawDataChannel();
00799 }
00800
00801
00802 BOOL H323AudioCodec::Open(H323Connection & connection)
00803 {
00804 return connection.OpenAudioChannel(direction == Encoder, samplesPerFrame*2, *this);
00805 }
00806
00807
00808 void H323AudioCodec::Close()
00809 {
00810 PWaitAndSignal mutex(rawChannelMutex);
00811
00812 if (rawDataChannel != NULL)
00813 rawDataChannel->Close();
00814 }
00815
00816
00817 unsigned H323AudioCodec::GetFrameRate() const
00818 {
00819 return samplesPerFrame;
00820 }
00821
00822
00823 H323AudioCodec::SilenceDetectionMode H323AudioCodec::GetSilenceDetectionMode(
00824 BOOL * isInTalkBurst, unsigned * currentThreshold) const
00825 {
00826 if (isInTalkBurst != NULL)
00827 *isInTalkBurst = inTalkBurst;
00828
00829 if (currentThreshold != NULL)
00830 *currentThreshold = ulaw2linear((BYTE)(levelThreshold ^ 0xff));
00831
00832 return silenceDetectMode;
00833 }
00834
00835
00836 void H323AudioCodec::SetSilenceDetectionMode(SilenceDetectionMode mode,
00837 unsigned threshold,
00838 unsigned signalDeadband,
00839 unsigned silenceDeadband,
00840 unsigned adaptivePeriod)
00841 {
00842 silenceDetectMode = mode;
00843
00844
00845
00846 signalDeadbandFrames = (signalDeadband+samplesPerFrame-1)/samplesPerFrame;
00847 silenceDeadbandFrames = (silenceDeadband+samplesPerFrame-1)/samplesPerFrame;
00848
00849
00850 adaptiveThresholdFrames = (adaptivePeriod+samplesPerFrame-1)/samplesPerFrame;
00851
00852 if (mode != AdaptiveSilenceDetection) {
00853 levelThreshold = threshold;
00854 return;
00855 }
00856
00857
00858 levelThreshold = 0;
00859
00860
00861 signalMinimum = UINT_MAX;
00862 silenceMaximum = 0;
00863 signalFramesReceived = 0;
00864 silenceFramesReceived = 0;
00865
00866
00867 inTalkBurst = FALSE;
00868 }
00869
00870
00871 BOOL H323AudioCodec::DetectSilence()
00872 {
00873
00874 if (silenceDetectMode == NoSilenceDetection)
00875 return FALSE;
00876
00877
00878
00879 unsigned level = GetAverageSignalLevel();
00880 if (level == UINT_MAX)
00881 return FALSE;
00882
00883
00884 level = linear2ulaw(level) ^ 0xff;
00885
00886
00887 BOOL haveSignal = level > levelThreshold;
00888
00889
00890 if (inTalkBurst == haveSignal)
00891 framesReceived = 0;
00892 else {
00893 framesReceived++;
00894
00895 if (framesReceived >= (inTalkBurst ? silenceDeadbandFrames : signalDeadbandFrames)) {
00896 inTalkBurst = !inTalkBurst;
00897 PTRACE(4, "Codec\tSilence detection transition: "
00898 << (inTalkBurst ? "Talk" : "Silent")
00899 << " level=" << level << " threshold=" << levelThreshold);
00900
00901
00902 signalMinimum = UINT_MAX;
00903 silenceMaximum = 0;
00904 signalFramesReceived = 0;
00905 silenceFramesReceived = 0;
00906 }
00907 }
00908
00909 if (silenceDetectMode == FixedSilenceDetection)
00910 return !inTalkBurst;
00911
00912 if (levelThreshold == 0) {
00913 if (level > 1) {
00914
00915 levelThreshold = level/2;
00916 PTRACE(4, "Codec\tSilence detection threshold initialised to: " << levelThreshold);
00917 }
00918 return TRUE;
00919 }
00920
00921
00922 if (haveSignal) {
00923 if (level < signalMinimum)
00924 signalMinimum = level;
00925 signalFramesReceived++;
00926 }
00927 else {
00928 if (level > silenceMaximum)
00929 silenceMaximum = level;
00930 silenceFramesReceived++;
00931 }
00932
00933
00934 if ((signalFramesReceived + silenceFramesReceived) > adaptiveThresholdFrames) {
00935
00936
00937
00938
00939 if (signalFramesReceived >= adaptiveThresholdFrames) {
00940
00941
00942
00943
00944
00945 int delta = (signalMinimum - levelThreshold)/4;
00946 if (delta != 0) {
00947 levelThreshold += delta;
00948 PTRACE(4, "Codec\tSilence detection threshold increased to: " << levelThreshold);
00949 }
00950 }
00951 else if (silenceFramesReceived >= adaptiveThresholdFrames) {
00952
00953
00954
00955
00956
00957
00958 unsigned newThreshold = (levelThreshold + silenceMaximum)/2 + 1;
00959 if (levelThreshold != newThreshold) {
00960 levelThreshold = newThreshold;
00961 PTRACE(4, "Codec\tSilence detection threshold decreased to: " << levelThreshold);
00962 }
00963 }
00964 else if (signalFramesReceived > silenceFramesReceived) {
00965
00966
00967
00968
00969 levelThreshold++;
00970 PTRACE(4, "Codec\tSilence detection threshold incremented to: " << levelThreshold
00971 << " signal=" << signalFramesReceived << ' ' << signalMinimum
00972 << " silence=" << silenceFramesReceived << ' ' << silenceMaximum);
00973 }
00974
00975 signalMinimum = UINT_MAX;
00976 silenceMaximum = 0;
00977 signalFramesReceived = 0;
00978 silenceFramesReceived = 0;
00979 }
00980
00981 return !inTalkBurst;
00982 }
00983
00984
00985 unsigned H323AudioCodec::GetAverageSignalLevel()
00986 {
00987 return UINT_MAX;
00988 }
00989
00990 BOOL H323AudioCodec::SetRawDataHeld(BOOL hold) {
00991
00992 PTimedMutex m;
00993 m.Wait(50);
00994 IsRawDataHeld = hold;
00995 m.Wait(50);
00996 return TRUE;
00997 }
00998
01000
01001 H323FramedAudioCodec::H323FramedAudioCodec(const OpalMediaFormat & fmt, Direction dir)
01002 : H323AudioCodec(fmt, dir),
01003 sampleBuffer(samplesPerFrame)
01004 {
01005 bytesPerFrame = mediaFormat.GetFrameSize();
01006 }
01007
01008
01009 BOOL H323FramedAudioCodec::Read(BYTE * buffer, unsigned & length, RTP_DataFrame &)
01010 {
01011 PWaitAndSignal mutex(rawChannelMutex);
01012
01013 if (direction != Encoder) {
01014 PTRACE(1, "Codec\tAttempt to decode from encoder");
01015 return FALSE;
01016 }
01017
01018 if (IsRawDataHeld) {
01019 PProcess::Sleep(5);
01020 length = 0;
01021 return TRUE;
01022 }
01023
01024 PINDEX numBytes = samplesPerFrame*2;
01025 PINDEX count;
01026 if (!ReadRaw(sampleBuffer.GetPointer(samplesPerFrame), numBytes, count))
01027 return FALSE;
01028
01029 #ifdef H323_AEC
01030 if (aec != NULL) {
01031 PTRACE(6,"AEC\tSend " << numBytes);
01032 aec->Send((BYTE*)sampleBuffer.GetPointer(samplesPerFrame),(unsigned &)numBytes);
01033 }
01034 #endif
01035
01036 if (IsRawDataHeld) {
01037 length = 0;
01038 return TRUE;
01039 }
01040
01041 if (count != numBytes) {
01042 PTRACE(1, "Codec\tRead truncated frame of raw data. Wanted " << numBytes << " and got "<<count);
01043 return FALSE;
01044 }
01045
01046 if (DetectSilence()) {
01047 length = 0;
01048 return TRUE;
01049 }
01050
01051
01052 length = bytesPerFrame;
01053 return EncodeFrame(buffer, length);
01054 }
01055
01056
01057 BOOL H323FramedAudioCodec::Write(const BYTE * buffer,
01058 unsigned length,
01059 const RTP_DataFrame & ,
01060 unsigned & written)
01061 {
01062 PWaitAndSignal mutex(rawChannelMutex);
01063
01064 if (direction != Decoder) {
01065 PTRACE(1, "Codec\tAttempt to encode from decoder");
01066 return FALSE;
01067 }
01068
01069
01070 written = 0;
01071
01072 unsigned bytesDecoded = samplesPerFrame*2;
01073
01074 if (length != 0) {
01075 if (length > bytesPerFrame)
01076 length = bytesPerFrame;
01077 written = bytesPerFrame;
01078
01079
01080 if (!DecodeFrame(buffer, length, written, bytesDecoded)) {
01081 written = length;
01082 length = 0;
01083 }
01084 }
01085
01086
01087 if (length == 0)
01088 DecodeSilenceFrame(sampleBuffer.GetPointer(bytesDecoded), bytesDecoded);
01089
01090
01091 if (IsRawDataHeld) {
01092 PProcess::Sleep(5);
01093 return TRUE;
01094 } else {
01095 #ifdef H323_AEC
01096 if (aec != NULL) {
01097 PTRACE(6,"AEC\tReceive " << bytesDecoded);
01098 aec->Receive((BYTE *)sampleBuffer.GetPointer(), bytesDecoded);
01099 }
01100 #endif
01101 if (!WriteRaw(sampleBuffer.GetPointer(), bytesDecoded))
01102 return FALSE;
01103 }
01104 return TRUE;
01105
01106
01107 }
01108
01109
01110 unsigned H323FramedAudioCodec::GetAverageSignalLevel()
01111 {
01112
01113 int sum = 0;
01114
01115 const short * pcm = sampleBuffer;
01116 const short * end = pcm + samplesPerFrame;
01117 while (pcm != end) {
01118 if (*pcm < 0)
01119 sum -= *pcm++;
01120 else
01121 sum += *pcm++;
01122 }
01123
01124 return sum/samplesPerFrame;
01125 }
01126
01127
01128 BOOL H323FramedAudioCodec::DecodeFrame(const BYTE * buffer,
01129 unsigned length,
01130 unsigned & written,
01131 unsigned & )
01132 {
01133 return DecodeFrame(buffer, length, written);
01134 }
01135
01136
01137 BOOL H323FramedAudioCodec::DecodeFrame(const BYTE * ,
01138 unsigned ,
01139 unsigned & )
01140 {
01141 PAssertAlways(PUnimplementedFunction);
01142 return FALSE;
01143 }
01144
01145 #ifdef H323_AEC
01146 void H323FramedAudioCodec::AttachAEC(PAec * _aec)
01147 {
01148 aec = _aec;
01149 }
01150 #endif
01151
01153
01154 H323StreamedAudioCodec::H323StreamedAudioCodec(const OpalMediaFormat & fmt,
01155 Direction dir,
01156 unsigned samples,
01157 unsigned bits)
01158 : H323FramedAudioCodec(fmt, dir)
01159 {
01160 samplesPerFrame = samples;
01161 bytesPerFrame = (samples*bits+7)/8;
01162 bitsPerSample = bits;
01163 }
01164
01165
01166 BOOL H323StreamedAudioCodec::EncodeFrame(BYTE * buffer, unsigned &)
01167 {
01168 PINDEX i;
01169 unsigned short position = 0;
01170 BYTE encoded;
01171 switch (bitsPerSample) {
01172 case 8 :
01173 for (i = 0; i < (PINDEX)samplesPerFrame; i++)
01174 *buffer++ = (BYTE)Encode(sampleBuffer[i]);
01175 break;
01176 case 5 :
01177 for (i = 0; i < (PINDEX)samplesPerFrame;i++)
01178 {
01179
01180 encoded = (BYTE)Encode(sampleBuffer[i]);
01181 switch(position)
01182 {
01183 case 0:
01184 *buffer = encoded;
01185 position++;
01186 break;
01187 case 1:
01188 *buffer++ |= (encoded << 5);
01189 *buffer = (BYTE)(encoded >> 3);
01190 position++;
01191 break;
01192 case 2:
01193 *buffer |= (encoded << 2);
01194 position++;
01195 break;
01196 case 3:
01197 *buffer++ |= (encoded << 7);
01198 *buffer = (BYTE)(encoded >> 1);
01199 position++;
01200 break;
01201 case 4:
01202 *buffer++ |= (encoded << 4);
01203 *buffer = (BYTE)(encoded >> 4);
01204 position++;
01205 break;
01206 case 5:
01207 *buffer |= (encoded << 1);
01208 position++;
01209 break;
01210 case 6:
01211 *buffer++ |= (encoded << 6);
01212 *buffer = (BYTE)(encoded >> 2);
01213 position++;
01214 break;
01215 case 7:
01216 *buffer++ |= (encoded << 3);
01217 position = 0;
01218 break;
01219 }
01220 }
01221 break;
01222
01223 case 4 :
01224 for (i = 0; i < (PINDEX)samplesPerFrame; i++) {
01225 if ((i&1) == 0)
01226 *buffer = (BYTE)Encode(sampleBuffer[i]);
01227 else
01228 *buffer++ |= (BYTE)(Encode(sampleBuffer[i]) << 4);
01229 }
01230 break;
01231
01232 case 3 :
01233 for (i = 0;i < (PINDEX)samplesPerFrame;i++)
01234 {
01235 encoded = (BYTE)Encode(sampleBuffer[i]);
01236 switch(position)
01237 {
01238 case 0:
01239 *buffer = encoded;
01240 position++;
01241 break;
01242 case 1:
01243 *buffer |= (encoded << 3);
01244 position++;
01245 break;
01246 case 2:
01247 *buffer++ |= (encoded << 6);
01248 *buffer = (BYTE)(encoded >> 2);
01249 position++;
01250 break;
01251 case 3:
01252 *buffer |= (encoded << 1);
01253 position++;
01254 break;
01255 case 4:
01256 *buffer |= (encoded << 4);
01257 position++;
01258 break;
01259 case 5:
01260 *buffer++ |= (encoded << 7);
01261 *buffer = (BYTE)(encoded >> 1);
01262 position++;
01263 break;
01264 case 6:
01265 *buffer |= (encoded << 2);
01266 position++;
01267 break;
01268 case 7:
01269 *buffer++ |= (encoded << 5);
01270 position = 0;
01271 break;
01272 }
01273 }
01274 break;
01275
01276 case 2:
01277 for (i = 0; i < (PINDEX)samplesPerFrame; i++)
01278 {
01279 switch(position)
01280 {
01281 case 0:
01282 *buffer = (BYTE)Encode(sampleBuffer[i]);
01283 position++;
01284 break;
01285 case 1:
01286 *buffer |= (BYTE)(Encode(sampleBuffer[i]) << 2);
01287 position++;
01288 break;
01289 case 2:
01290 *buffer |= (BYTE)(Encode(sampleBuffer[i]) << 4);
01291 position++;
01292 break;
01293 case 3:
01294 *buffer++ |= (BYTE)(Encode(sampleBuffer[i]) << 6);
01295 position = 0;
01296 break;
01297 }
01298 }
01299 break;
01300
01301 default :
01302 PAssertAlways("Unsupported bit size");
01303 return FALSE;
01304 }
01305
01306 return TRUE;
01307 }
01308
01309
01310 BOOL H323StreamedAudioCodec::DecodeFrame(const BYTE * buffer,
01311 unsigned length,
01312 unsigned & written,
01313 unsigned & decodedBytes)
01314 {
01315 unsigned i;
01316
01317 short * sampleBufferPtr = sampleBuffer.GetPointer(samplesPerFrame);
01318 short * out = sampleBufferPtr;
01319 unsigned short position = 0;
01320 unsigned remaining = 0;
01321
01322 switch (bitsPerSample) {
01323 case 8 :
01324 for (i = 0; i < length; i++)
01325 *out++ = Decode(*buffer++);
01326 break;
01327
01328
01329 case 5 :
01330 for (i = 0; i < length; i++) {
01331 switch(position)
01332 {
01333 case 0:
01334 *out++ = Decode(*buffer & 31);
01335 remaining = *buffer >> 5;
01336 buffer++;
01337 position++;
01338 break;
01339 case 1:
01340 *out++ = Decode (((*buffer&3) << 3) | remaining);
01341 *out++ = Decode( (*buffer >> 2) & 31);
01342 remaining = *buffer >> 7;
01343 buffer++;
01344 position++;
01345 break;
01346 case 2:
01347 *out++ = Decode( remaining | ((*buffer&15) << 1));
01348 remaining = *buffer >> 4;
01349 buffer++;
01350 position++;
01351 break;
01352 case 3:
01353 *out++ = Decode( remaining | ((*buffer&1) << 4));
01354 *out++ = Decode( (*buffer >> 1) & 31);
01355 remaining = *buffer >> 6;
01356 buffer++;
01357 position++;
01358 break;
01359 case 4 :
01360 *out++ = Decode( remaining | ((*buffer&7) << 2));
01361 *out++ = Decode(*buffer >> 3);
01362 buffer++;
01363 position = 0;
01364 break;
01365 }
01366 }
01367 break;
01368
01369 case 4 :
01370 for (i = 0; i < length; i++) {
01371 *out++ = Decode(*buffer & 15);
01372 *out++ = Decode(*buffer >> 4);
01373 buffer++;
01374 }
01375 break;
01376
01377 case 3:
01378 for (i = 0; i < length; i++) {
01379 switch(position)
01380 {
01381 case 0:
01382 *out++ = Decode(*buffer & 7);
01383 *out++ = Decode((*buffer>>3)&7);
01384 remaining = *buffer >> 6;
01385 buffer++;
01386 position++;
01387 break;
01388 case 1:
01389 *out++ = Decode(remaining | ((*buffer&1) << 2));
01390 *out++ = Decode((*buffer >> 1) & 7);
01391 *out++ = Decode((*buffer >> 4)&7);
01392 remaining = *buffer >> 7;
01393 buffer++;
01394 position++;
01395 break;
01396 case 2:
01397 *out++ = Decode(remaining | ((*buffer&3) << 1));
01398 *out++ = Decode((*buffer >> 2) & 7);
01399 *out++ = Decode((*buffer >> 5) & 7);
01400 buffer++;
01401 position = 0;
01402 break;
01403 }
01404 }
01405 break;
01406
01407 case 2:
01408 for (i = 0; i < length; i++)
01409 {
01410 *out++ = Decode(*buffer & 3);
01411 *out++ = Decode((*buffer >> 2) & 3);
01412 *out++ = Decode((*buffer >> 4) & 3);
01413 *out++ = Decode((*buffer >> 6) & 3);
01414 buffer++;
01415
01416 }
01417 break;
01418
01419 default :
01420 PAssertAlways("Unsupported bit size");
01421 return FALSE;
01422 }
01423
01424 written = length;
01425 decodedBytes = (out - sampleBufferPtr)*2;
01426
01427 return TRUE;
01428 }
01429
01430
01432
01433 H323_ALawCodec::H323_ALawCodec(Direction dir,
01434 BOOL at56kbps,
01435 unsigned frameSize)
01436 : H323StreamedAudioCodec(OpalG711ALaw, dir, frameSize, 8)
01437 {
01438 sevenBit = at56kbps;
01439
01440 PTRACE(3, "Codec\tG711 ALaw " << (dir == Encoder ? "en" : "de")
01441 << "coder created for at "
01442 << (sevenBit ? "56k" : "64k") << ", " << frameSize << " samples");
01443 }
01444
01445
01446
01447 int H323_ALawCodec::EncodeSample(short sample)
01448 {
01449 return linear2alaw(sample);
01450 }
01451
01452
01453 short H323_ALawCodec::DecodeSample(int sample)
01454 {
01455 return (short)alaw2linear((unsigned char)sample);
01456 }
01457
01458
01460
01461 H323_muLawCodec::H323_muLawCodec(Direction dir,
01462 BOOL at56kbps,
01463 unsigned frameSize)
01464 : H323StreamedAudioCodec(OpalG711uLaw, dir, frameSize, 8)
01465 {
01466 sevenBit = at56kbps;
01467
01468 PTRACE(3, "Codec\tG711 uLaw " << (dir == Encoder ? "en" : "de")
01469 << "coder created for at "
01470 << (sevenBit ? "56k" : "64k") << ", frame of " << frameSize << " samples");
01471 }
01472
01473
01474 int H323_muLawCodec::EncodeSample(short sample)
01475 {
01476 return linear2ulaw(sample);
01477 }
01478
01479
01480 short H323_muLawCodec::DecodeSample(int sample)
01481 {
01482 return (short)ulaw2linear((unsigned char)sample);
01483 }
01484
01485
01487
01488 #endif // NO_H323_AUDIO_CODECS