October3d55/Matain/SocketIOClient/Source/CoreUtility/Public/CUOpusCoder.h

89 lines
2.6 KiB
C
Raw Normal View History

2025-03-10 09:43:27 +08:00
// Copyright 2019-current Getnamo. All Rights Reserved
#pragma once
#include "CoreMinimal.h"
#ifndef WITH_OPUS
#define WITH_OPUS (PLATFORM_WINDOWS || PLATFORM_UNIX || PLATFORM_ANDROID)
#endif
#if WITH_OPUS
#include "ThirdParty/libOpus/opus-1.1/include/opus.h"
//#include "ogg/ogg.h"
#endif
//Bare minimum struct for transferring opus bytes.
struct FCUOpusMinimalStream
{
TArray<int16> PacketSizes; // Maximum packet size is 32768 (much larger than typical packet)
TArray<uint8> CompressedBytes;
};
/**
Symmetric coder for e.g. voip written from raw libopus due to how hidden the opus
coder is in the engine (this one doesn't require an online subsystem)
*/
class FCUOpusCoder
{
public:
FCUOpusCoder();
~FCUOpusCoder();
/** Set Encoder and Decoder Samples per sec */
void SetSampleRate(int32 InSampleRate);
void SetChannels(int32 Channels);
void SetBitrate(int32 Bitrate);
void SetFrameSizeMs(int32 FrameSizeInMs);
/** Expects raw PCM data, outputs compressed raw opus data along with compressed frame sizes*/
bool EncodeStream(const TArray<uint8>& InPCMBytes, FCUOpusMinimalStream& OutStream);
bool DecodeStream(const FCUOpusMinimalStream& InStream, TArray<uint8>& OutPCMFrame);
//Format: PacketCount, PacketSizes, CompressedOpusBytes. Expects settings set in a different stream
bool SerializeMinimal(const FCUOpusMinimalStream& InStream, TArray<uint8>& OutSerializedBytes);
bool DeserializeMinimal(const TArray<uint8>& InSerializedMinimalBytes, FCUOpusMinimalStream& OutStream);
//Handle a single frame
int32 EncodeFrame(const TArray<uint8>& InPCMFrame, TArray<uint8>& OutCompressed);
int32 DecodeFrame(const TArray<uint8>& InCompressedFrame, TArray<uint8>& OutPCMFrame);
//Todo: add ogg file format wrapper for raw opus bytes
//Intended to be Read-only
int32 Channels;
int32 SampleRate;
//Whether we should reset the coder per stream to keep byte size small. Costs ~0.01ms
bool bResetBetweenEncoding;
bool bApplicationVoip;
bool bLowestPossibleLatency; //trade-off is compression size; ~3ms/sec of audio if on, ~10ms/sec if off. For ~ 33% more bytes.
void ResetCoderIfInitialized();
protected:
//Call this if some settings need to be reflected (all setters all this)
bool InitEncoderIfNeeded();
bool InitDecoderIfNeeded();
private:
#if WITH_OPUS
OpusEncoder* Encoder;
OpusDecoder* Decoder;
#endif
int32 BitRate;
int32 MaxPacketSize;
int32 FrameSizeMs;
int32 FrameSize;
int32 MaxFrameSize;
//Debug utilities
void DebugLogEncoder();
void DebugLogDecoder();
void DebugLogFrame(const uint8* PacketData, uint32 PacketLength, uint32 SampleRate, bool bEncode);
};