- fix octet-aligned mode parser
This commit is contained in:
parent
e90ae17212
commit
5ddd7bbeed
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../helper/HL_ByteBuffer.h"
|
#include "../helper/HL_ByteBuffer.h"
|
||||||
#include "../helper/HL_Log.h"
|
#include "../helper/HL_Log.h"
|
||||||
#include "../helper/HL_IuUP.h"
|
#include "../helper/HL_IuUP.h"
|
||||||
|
#include "../helper/HL_Exception.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -179,11 +180,18 @@ static AmrPayload parseAmrPayload(AmrPayloadInfo& input)
|
||||||
|
|
||||||
// Copy data of AMR frame
|
// Copy data of AMR frame
|
||||||
if (byteOffset + byteLength <= input.mPayloadLength)
|
if (byteOffset + byteLength <= input.mPayloadLength)
|
||||||
f.mData = std::make_shared<ByteBuffer>(input.mPayload + byteOffset, byteLength);
|
{
|
||||||
|
f.mData = std::make_shared<ByteBuffer>();
|
||||||
|
f.mData->resize(byteLength + 1); // payload + header
|
||||||
|
memcpy(f.mData->mutableData() + 1, input.mPayload + byteOffset, byteLength);
|
||||||
|
|
||||||
|
// Add header for decoder
|
||||||
|
f.mData->mutableData()[0] = (f.mFrameType << 3) | (1 << 2);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Problem parsing AMR header: octet-aligned is set, available " << input.mPayloadLength - byteOffset
|
ICELogError(<< "Problem parsing AMR header: octet-aligned is set, available " << input.mPayloadLength - byteOffset
|
||||||
<< " bytes but requested " << byteLength << std::endl;
|
<< " bytes but requested " << byteLength);
|
||||||
result.mDiscardPacket = true;
|
result.mDiscardPacket = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -209,11 +217,6 @@ static AmrPayload parseAmrPayload(AmrPayloadInfo& input)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static void predecodeAmrFrame(AmrFrame& frame, ByteBuffer& data)
|
|
||||||
{
|
|
||||||
// Data are already moved into
|
|
||||||
}*/
|
|
||||||
|
|
||||||
AmrNbCodec::CodecFactory::CodecFactory(const AmrCodecConfig& config)
|
AmrNbCodec::CodecFactory::CodecFactory(const AmrCodecConfig& config)
|
||||||
:mConfig(config)
|
:mConfig(config)
|
||||||
{
|
{
|
||||||
|
|
@ -445,7 +448,7 @@ int AmrNbCodec::plc(int lostFrames, void* output, int outputCapacity)
|
||||||
|
|
||||||
for (int i=0; i < lostFrames; i++)
|
for (int i=0; i < lostFrames; i++)
|
||||||
{
|
{
|
||||||
unsigned char buffer[32];
|
uint8_t buffer[32];
|
||||||
buffer[0] = (AMR_BITRATE_DTX << 3)|4;
|
buffer[0] = (AMR_BITRATE_DTX << 3)|4;
|
||||||
Decoder_Interface_Decode(mDecoderCtx, buffer, dataOut, 0); // Handle missing data
|
Decoder_Interface_Decode(mDecoderCtx, buffer, dataOut, 0); // Handle missing data
|
||||||
dataOut += L_FRAME;
|
dataOut += L_FRAME;
|
||||||
|
|
@ -507,7 +510,6 @@ AmrWbCodec::AmrWbCodec(const AmrCodecConfig& config)
|
||||||
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config),
|
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config),
|
||||||
mSwitchCounter(0), mPreviousPacketLength(0)
|
mSwitchCounter(0), mPreviousPacketLength(0)
|
||||||
{
|
{
|
||||||
//mEncoderCtx = E_IF_init();
|
|
||||||
mDecoderCtx = D_IF_init();
|
mDecoderCtx = D_IF_init();
|
||||||
mCurrentDecoderTimestamp = 0;
|
mCurrentDecoderTimestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -554,39 +556,16 @@ int AmrWbCodec::samplerate()
|
||||||
|
|
||||||
int AmrWbCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity)
|
int AmrWbCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity)
|
||||||
{
|
{
|
||||||
if (inputBytes % pcmLength())
|
throw Exception(ERR_NOT_IMPLEMENTED);
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Declare the data input pointer
|
|
||||||
// const short *dataIn = (const short *)input;
|
|
||||||
|
|
||||||
// Declare the data output pointer
|
|
||||||
// unsigned char *dataOut = (unsigned char *)output;
|
|
||||||
|
|
||||||
// Find how much RTP frames will be generated
|
|
||||||
unsigned int frames = inputBytes / pcmLength();
|
|
||||||
|
|
||||||
// Generate frames
|
|
||||||
for (unsigned int i = 0; i < frames; i++)
|
|
||||||
{
|
|
||||||
// dataOut += Encoder_Interface_Encode(mEncoderCtx, Mode::MRDTX, dataIn, dataOut, 1);
|
|
||||||
// dataIn += pcmLength() / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return frames * rtpLength();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define L_FRAME 160
|
#define L_FRAME 160
|
||||||
#define AMR_BITRATE_DTX 15
|
#define AMR_BITRATE_DTX 15
|
||||||
int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity)
|
|
||||||
{
|
|
||||||
// if (mConfig.mOctetAligned)
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
if (mConfig.mIuUP)
|
int AmrWbCodec::decodeIuup(std::span<const uint8_t> input, std::span<uint8_t> output)
|
||||||
{
|
{
|
||||||
IuUP::Frame frame;
|
IuUP::Frame frame;
|
||||||
if (!IuUP::parse2((const uint8_t*)input, inputBytes, frame))
|
if (!IuUP::parse2(input.data(), input.size(), frame))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!frame.mHeaderCrcOk || !frame.mPayloadCrcOk)
|
if (!frame.mHeaderCrcOk || !frame.mPayloadCrcOk)
|
||||||
|
|
@ -595,9 +574,6 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build first byte to help decoder
|
|
||||||
//ICELogDebug(<< "Decoding AMR frame length = " << frame.mPayloadSize);
|
|
||||||
|
|
||||||
// Reserve space
|
// Reserve space
|
||||||
ByteBuffer dataToDecode;
|
ByteBuffer dataToDecode;
|
||||||
dataToDecode.resize(1 + frame.mPayloadSize);
|
dataToDecode.resize(1 + frame.mPayloadSize);
|
||||||
|
|
@ -614,16 +590,17 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
|
||||||
|
|
||||||
dataToDecode.mutableData()[0] = (frameType << 3) | (1 << 2);
|
dataToDecode.mutableData()[0] = (frameType << 3) | (1 << 2);
|
||||||
|
|
||||||
D_IF_decode(mDecoderCtx, (const unsigned char*)dataToDecode.data(), (short*)output, 0);
|
D_IF_decode(mDecoderCtx, (const unsigned char*)dataToDecode.data(), (short*)output.data(), 0);
|
||||||
return pcmLength();
|
return pcmLength();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
int AmrWbCodec::decodePlain(std::span<const uint8_t> input, std::span<uint8_t> output)
|
||||||
|
{
|
||||||
AmrPayloadInfo info;
|
AmrPayloadInfo info;
|
||||||
info.mCurrentTimestamp = mCurrentDecoderTimestamp;
|
info.mCurrentTimestamp = mCurrentDecoderTimestamp;
|
||||||
info.mOctetAligned = mConfig.mOctetAligned;
|
info.mOctetAligned = mConfig.mOctetAligned;
|
||||||
info.mPayload = (const uint8_t*)input;
|
info.mPayload = input.data();
|
||||||
info.mPayloadLength = inputBytes;
|
info.mPayloadLength = input.size();
|
||||||
info.mWideband = true;
|
info.mWideband = true;
|
||||||
info.mInterleaving = false;
|
info.mInterleaving = false;
|
||||||
|
|
||||||
|
|
@ -647,11 +624,12 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
|
||||||
GAmrWbStatistics.mDiscarded++;
|
GAmrWbStatistics.mDiscarded++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for output buffer capacity
|
// Check for output buffer capacity
|
||||||
if (outputCapacity < (int)ap.mFrames.size() * pcmLength())
|
if (output.size() < (int)ap.mFrames.size() * pcmLength())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
short* dataOut = (short*)output;
|
short* dataOut = (short*)output.data();
|
||||||
for (AmrFrame& frame: ap.mFrames)
|
for (AmrFrame& frame: ap.mFrames)
|
||||||
{
|
{
|
||||||
memset(dataOut, 0, static_cast<size_t>(pcmLength()));
|
memset(dataOut, 0, static_cast<size_t>(pcmLength()));
|
||||||
|
|
@ -663,7 +641,17 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pcmLength() * ap.mFrames.size();
|
return pcmLength() * ap.mFrames.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity)
|
||||||
|
{
|
||||||
|
auto inputBuffer = std::span<const uint8_t>((uint8_t*)input, (size_t)inputBytes);
|
||||||
|
auto outputBuffer = std::span<uint8_t>((uint8_t*)output, (size_t)outputCapacity);
|
||||||
|
|
||||||
|
if (mConfig.mIuUP)
|
||||||
|
return decodeIuup(inputBuffer, outputBuffer);
|
||||||
|
else
|
||||||
|
return decodePlain(inputBuffer, outputBuffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "../engine_config.h"
|
#include "../engine_config.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
#include "MT_Codec.h"
|
#include "MT_Codec.h"
|
||||||
#include "../helper/HL_Pointer.h"
|
#include "../helper/HL_Pointer.h"
|
||||||
|
|
||||||
|
|
@ -83,6 +85,9 @@ protected:
|
||||||
int mSwitchCounter;
|
int mSwitchCounter;
|
||||||
int mPreviousPacketLength;
|
int mPreviousPacketLength;
|
||||||
|
|
||||||
|
int decodeIuup(std::span<const uint8_t> input, std::span<uint8_t> output);
|
||||||
|
int decodePlain(std::span<const uint8_t> input, std::span<uint8_t> output);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class CodecFactory: public Factory
|
class CodecFactory: public Factory
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue