win-mf: Add Media Foundation AAC Encoder
Adds Microsoft Media Foundation AAC Encoder that supports 96k to 192k bitrates. This plugin is only enabled on Microsoft Windows 8+ due to performance issues found on Windows 7.
This commit is contained in:
91
plugins/win-mf/mf-aac-encoder.hpp
Normal file
91
plugins/win-mf/mf-aac-encoder.hpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_MEAN_AND_LEAN
|
||||
#include <Windows.h>
|
||||
#undef WIN32_MEAN_AND_LEAN
|
||||
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include <util/windows/ComPtr.hpp>
|
||||
|
||||
#define MF_LOG(level, format, ...) \
|
||||
blog(level, "[Media Foundation encoder]: " format, ##__VA_ARGS__)
|
||||
#define MF_LOG_ENCODER(format_name, encoder, level, format, ...) \
|
||||
blog(level, "[Media Foundation %s: '%s']: " format, \
|
||||
format_name, obs_encoder_get_name(encoder), \
|
||||
##__VA_ARGS__)
|
||||
|
||||
namespace MFAAC {
|
||||
|
||||
enum Status {
|
||||
FAILURE,
|
||||
SUCCESS,
|
||||
NOT_ACCEPTING,
|
||||
NEED_MORE_INPUT
|
||||
};
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
Encoder(const obs_encoder_t *encoder, UINT32 bitrate, UINT32 channels,
|
||||
UINT32 sampleRate, UINT32 bitsPerSample)
|
||||
: encoder(encoder),
|
||||
bitrate(bitrate),
|
||||
channels(channels),
|
||||
sampleRate(sampleRate),
|
||||
bitsPerSample(bitsPerSample)
|
||||
{}
|
||||
|
||||
Encoder& operator=(Encoder const&) = delete;
|
||||
|
||||
bool Initialize();
|
||||
bool ProcessInput(UINT8 *data, UINT32 dataLength,
|
||||
UINT64 pts, MFAAC::Status *status);
|
||||
bool ProcessOutput(UINT8 **data, UINT32 *dataLength,
|
||||
UINT64 *pts, MFAAC::Status *status);
|
||||
bool ExtraData(UINT8 **extraData, UINT32 *extraDataLength);
|
||||
|
||||
const obs_encoder_t *ObsEncoder() { return encoder; }
|
||||
UINT32 Bitrate() { return bitrate; }
|
||||
UINT32 Channels() { return channels; }
|
||||
UINT32 SampleRate() { return sampleRate; }
|
||||
UINT32 BitsPerSample() { return bitsPerSample; }
|
||||
|
||||
static const UINT32 FrameSize = 1024;
|
||||
|
||||
private:
|
||||
void InitializeExtraData();
|
||||
HRESULT CreateMediaTypes(ComPtr<IMFMediaType> &inputType,
|
||||
ComPtr<IMFMediaType> &outputType);
|
||||
HRESULT EnsureCapacity(ComPtr<IMFSample> &sample, DWORD length);
|
||||
HRESULT CreateEmptySample(ComPtr<IMFSample> &sample,
|
||||
ComPtr<IMFMediaBuffer> &buffer, DWORD length);
|
||||
|
||||
private:
|
||||
const obs_encoder_t *encoder;
|
||||
const UINT32 bitrate;
|
||||
const UINT32 channels;
|
||||
const UINT32 sampleRate;
|
||||
const UINT32 bitsPerSample;
|
||||
|
||||
ComPtr<IMFTransform> transform;
|
||||
ComPtr<IMFSample> outputSample;
|
||||
std::vector<BYTE> packetBuffer;
|
||||
UINT8 extraData[5];
|
||||
};
|
||||
|
||||
static const UINT32 FrameSize = 1024;
|
||||
|
||||
UINT32 FindBestBitrateMatch(UINT32 value);
|
||||
UINT32 FindBestChannelsMatch(UINT32 value);
|
||||
UINT32 FindBestBitsPerSampleMatch(UINT32 value);
|
||||
UINT32 FindBestSamplerateMatch(UINT32 value);
|
||||
bool BitrateValid(UINT32 value);
|
||||
bool ChannelsValid(UINT32 value);
|
||||
bool BitsPerSampleValid(UINT32 value);
|
||||
bool SamplerateValid(UINT32 value);
|
||||
|
||||
}
|
Reference in New Issue
Block a user