obs之libfaac编码

xiaoxiao2021-02-28  57

obs源码之libaac编码。

#include "Main.h" #include "../libfaac/include/faac.h" //AAC is pretty good, I changed my mind class AACEncoder : public AudioEncoder { UINT curBitRate; bool bFirstPacket; faacEncHandle faac; DWORD numReadSamples; DWORD outputSize; List<float> inputBuffer; List<BYTE> aacBuffer; List<BYTE> header; List<DWORD> bufferedTimestamps; DWORD curEncodeTimestamp; bool bFirstFrame; public: AACEncoder(UINT bitRate) { curBitRate = bitRate; faac = faacEncOpen(44100, 2, &numReadSamples, &outputSize); //Log(TEXT("numReadSamples: %d"), numReadSamples); aacBuffer.SetSize(outputSize+2); aacBuffer[0] = 0xaf; aacBuffer[1] = 0x1; faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(faac); config->bitRate = (bitRate*1000)/2; config->quantqual = 100; config->inputFormat = FAAC_INPUT_FLOAT; config->mpegVersion = MPEG4; config->aacObjectType = LOW; config->useLfe = 0; config->outputFormat = 0; int ret = faacEncSetConfiguration(faac, config); if(!ret) CrashError(TEXT("aac configuration failed")); BYTE *tempHeader; DWORD len; header.SetSize(2); header[0] = 0xaf; header[1] = 0x00; faacEncGetDecoderSpecificInfo(faac, &tempHeader, &len); header.AppendArray(tempHeader, len); free(tempHeader); bFirstPacket = true; bFirstFrame = true; Log(TEXT("------------------------------------------")); Log(TEXT("%s"), GetInfoString().Array()); } ~AACEncoder() { faacEncClose(faac); } bool Encode(float *input, UINT numInputFrames, DataPacket &packet, DWORD ×tamp) { if(bFirstFrame) { curEncodeTimestamp = timestamp; bFirstFrame = false; } //------------------------------------------------ DWORD curTimestamp = timestamp; UINT lastSampleSize = inputBuffer.Num(); UINT numInputSamples = numInputFrames*2; inputBuffer.AppendArray(input, numInputSamples); int ret = 0; if(inputBuffer.Num() >= numReadSamples) { //now we have to upscale the floats. fortunately we almost always have SSE UINT floatsLeft = numReadSamples; float *inputTemp = inputBuffer.Array(); if(App->SSE2Available() && (UPARAM(inputTemp) & 0xF) == 0) { UINT alignedFloats = floatsLeft & 0xFFFFFFFC; for(UINT i=0; i<alignedFloats; i += 4) { float *pos = inputTemp+i; _mm_store_ps(pos, _mm_mul_ps(_mm_load_ps(pos), _mm_set_ps1(32767.0f))); } floatsLeft &= 0x3; inputTemp += alignedFloats; } if(floatsLeft) { for(UINT i=0; i<floatsLeft; i++) inputTemp[i] *= 32767.0f; } ret = faacEncEncode(faac, (int32_t*)inputBuffer.Array(), numReadSamples, aacBuffer.Array()+2, outputSize); if(ret > 0) { if(bFirstPacket) { bFirstPacket = false; ret = 0; } else { packet.lpPacket = aacBuffer.Array(); packet.size = ret+2; timestamp = bufferedTimestamps[0]; bufferedTimestamps.Remove(0); } } else if(ret < 0) AppWarning(TEXT("aac encode error")); inputBuffer.RemoveRange(0, numReadSamples); bufferedTimestamps << curEncodeTimestamp; curEncodeTimestamp = curTimestamp + (((numReadSamples-lastSampleSize)/2)*10/441); } return ret > 0; } UINT GetFrameSize() const { return 1024; } void GetHeaders(DataPacket &packet) { packet.lpPacket = header.Array(); packet.size = header.Num(); } int GetBitRate() const {return curBitRate;} CTSTR GetCodec() const {return TEXT("AAC");} String GetInfoString() const { String strInfo; strInfo << TEXT("Audio Encoding: AAC") << TEXT("\r\n bitrate: ") << IntString(curBitRate); return strInfo; } }; AudioEncoder* CreateAACEncoder(UINT bitRate) { return new AACEncoder(bitRate); }

转载请注明原文地址: https://www.6miu.com/read-80725.html

最新回复(0)