mf-aac-encoder.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #pragma once
  2. #define WIN32_MEAN_AND_LEAN
  3. #include <Windows.h>
  4. #undef WIN32_MEAN_AND_LEAN
  5. #include <mfapi.h>
  6. #include <mfidl.h>
  7. #include <stdint.h>
  8. #include <vector>
  9. #include <util/windows/ComPtr.hpp>
  10. #define MF_LOG(level, format, ...) \
  11. blog(level, "[Media Foundation encoder]: " format, ##__VA_ARGS__)
  12. #define MF_LOG_ENCODER(format_name, encoder, level, format, ...) \
  13. blog(level, "[Media Foundation %s: '%s']: " format, \
  14. format_name, obs_encoder_get_name(encoder), \
  15. ##__VA_ARGS__)
  16. namespace MFAAC {
  17. enum Status {
  18. FAILURE,
  19. SUCCESS,
  20. NOT_ACCEPTING,
  21. NEED_MORE_INPUT
  22. };
  23. class Encoder {
  24. public:
  25. Encoder(const obs_encoder_t *encoder, UINT32 bitrate, UINT32 channels,
  26. UINT32 sampleRate, UINT32 bitsPerSample)
  27. : encoder(encoder),
  28. bitrate(bitrate),
  29. channels(channels),
  30. sampleRate(sampleRate),
  31. bitsPerSample(bitsPerSample)
  32. {}
  33. Encoder& operator=(Encoder const&) = delete;
  34. bool Initialize();
  35. bool ProcessInput(UINT8 *data, UINT32 dataLength,
  36. UINT64 pts, MFAAC::Status *status);
  37. bool ProcessOutput(UINT8 **data, UINT32 *dataLength,
  38. UINT64 *pts, MFAAC::Status *status);
  39. bool ExtraData(UINT8 **extraData, UINT32 *extraDataLength);
  40. const obs_encoder_t *ObsEncoder() { return encoder; }
  41. UINT32 Bitrate() { return bitrate; }
  42. UINT32 Channels() { return channels; }
  43. UINT32 SampleRate() { return sampleRate; }
  44. UINT32 BitsPerSample() { return bitsPerSample; }
  45. static const UINT32 FrameSize = 1024;
  46. private:
  47. void InitializeExtraData();
  48. HRESULT CreateMediaTypes(ComPtr<IMFMediaType> &inputType,
  49. ComPtr<IMFMediaType> &outputType);
  50. HRESULT EnsureCapacity(ComPtr<IMFSample> &sample, DWORD length);
  51. HRESULT CreateEmptySample(ComPtr<IMFSample> &sample,
  52. ComPtr<IMFMediaBuffer> &buffer, DWORD length);
  53. private:
  54. const obs_encoder_t *encoder;
  55. const UINT32 bitrate;
  56. const UINT32 channels;
  57. const UINT32 sampleRate;
  58. const UINT32 bitsPerSample;
  59. ComPtr<IMFTransform> transform;
  60. ComPtr<IMFSample> outputSample;
  61. std::vector<BYTE> packetBuffer;
  62. UINT8 extraData[5];
  63. };
  64. static const UINT32 FrameSize = 1024;
  65. UINT32 FindBestBitrateMatch(UINT32 value);
  66. UINT32 FindBestChannelsMatch(UINT32 value);
  67. UINT32 FindBestBitsPerSampleMatch(UINT32 value);
  68. UINT32 FindBestSamplerateMatch(UINT32 value);
  69. bool BitrateValid(UINT32 value);
  70. bool ChannelsValid(UINT32 value);
  71. bool BitsPerSampleValid(UINT32 value);
  72. bool SamplerateValid(UINT32 value);
  73. }