- fix octet-aligned mode parser

This commit is contained in:
Dmytro Bogovych 2025-07-30 13:47:17 +03:00
parent e90ae17212
commit 5ddd7bbeed
2 changed files with 104 additions and 111 deletions

View File

@ -5,6 +5,7 @@
#include "../helper/HL_ByteBuffer.h"
#include "../helper/HL_Log.h"
#include "../helper/HL_IuUP.h"
#include "../helper/HL_Exception.h"
#include <iostream>
@ -179,11 +180,18 @@ static AmrPayload parseAmrPayload(AmrPayloadInfo& input)
// Copy data of AMR frame
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
{
std::cerr << "Problem parsing AMR header: octet-aligned is set, available " << input.mPayloadLength - byteOffset
<< " bytes but requested " << byteLength << std::endl;
ICELogError(<< "Problem parsing AMR header: octet-aligned is set, available " << input.mPayloadLength - byteOffset
<< " bytes but requested " << byteLength);
result.mDiscardPacket = true;
continue;
}
@ -209,11 +217,6 @@ static AmrPayload parseAmrPayload(AmrPayloadInfo& input)
return result;
}
/*static void predecodeAmrFrame(AmrFrame& frame, ByteBuffer& data)
{
// Data are already moved into
}*/
AmrNbCodec::CodecFactory::CodecFactory(const AmrCodecConfig& config)
:mConfig(config)
{
@ -445,7 +448,7 @@ int AmrNbCodec::plc(int lostFrames, void* output, int outputCapacity)
for (int i=0; i < lostFrames; i++)
{
unsigned char buffer[32];
uint8_t buffer[32];
buffer[0] = (AMR_BITRATE_DTX << 3)|4;
Decoder_Interface_Decode(mDecoderCtx, buffer, dataOut, 0); // Handle missing data
dataOut += L_FRAME;
@ -507,7 +510,6 @@ AmrWbCodec::AmrWbCodec(const AmrCodecConfig& config)
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config),
mSwitchCounter(0), mPreviousPacketLength(0)
{
//mEncoderCtx = E_IF_init();
mDecoderCtx = D_IF_init();
mCurrentDecoderTimestamp = 0;
}
@ -554,39 +556,16 @@ int AmrWbCodec::samplerate()
int AmrWbCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity)
{
if (inputBytes % pcmLength())
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();
throw Exception(ERR_NOT_IMPLEMENTED);
}
#define L_FRAME 160
#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;
if (!IuUP::parse2((const uint8_t*)input, inputBytes, frame))
if (!IuUP::parse2(input.data(), input.size(), frame))
return 0;
if (!frame.mHeaderCrcOk || !frame.mPayloadCrcOk)
@ -595,9 +574,6 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
return 0;
}
// Build first byte to help decoder
//ICELogDebug(<< "Decoding AMR frame length = " << frame.mPayloadSize);
// Reserve space
ByteBuffer dataToDecode;
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);
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();
}
else
{
}
int AmrWbCodec::decodePlain(std::span<const uint8_t> input, std::span<uint8_t> output)
{
AmrPayloadInfo info;
info.mCurrentTimestamp = mCurrentDecoderTimestamp;
info.mOctetAligned = mConfig.mOctetAligned;
info.mPayload = (const uint8_t*)input;
info.mPayloadLength = inputBytes;
info.mPayload = input.data();
info.mPayloadLength = input.size();
info.mWideband = true;
info.mInterleaving = false;
@ -647,11 +624,12 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
GAmrWbStatistics.mDiscarded++;
return 0;
}
// Check for output buffer capacity
if (outputCapacity < (int)ap.mFrames.size() * pcmLength())
if (output.size() < (int)ap.mFrames.size() * pcmLength())
return 0;
short* dataOut = (short*)output;
short* dataOut = (short*)output.data();
for (AmrFrame& frame: ap.mFrames)
{
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();
}
}
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;
}

View File

@ -3,6 +3,8 @@
#include "../engine_config.h"
#include <map>
#include <span>
#include "MT_Codec.h"
#include "../helper/HL_Pointer.h"
@ -83,6 +85,9 @@ protected:
int mSwitchCounter;
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:
class CodecFactory: public Factory
{