- 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_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()));
@ -665,6 +643,16 @@ 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;
} }

View File

@ -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
{ {