mf-aac.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <obs-module.h>
  2. #include <memory>
  3. #include "mf-aac-encoder.hpp"
  4. #include <VersionHelpers.h>
  5. using namespace MFAAC;
  6. static const char *MFAAC_GetName(void*)
  7. {
  8. return obs_module_text("MFAACEnc");
  9. }
  10. static obs_properties_t *MFAAC_GetProperties(void *)
  11. {
  12. obs_properties_t *props = obs_properties_create();
  13. obs_properties_add_int(props, "bitrate",
  14. obs_module_text("Bitrate"), 96, 192, 32);
  15. return props;
  16. }
  17. static void MFAAC_GetDefaults(obs_data_t *settings)
  18. {
  19. obs_data_set_default_int(settings, "bitrate", 128);
  20. }
  21. static void *MFAAC_Create(obs_data_t *settings, obs_encoder_t *encoder)
  22. {
  23. UINT32 bitrate = (UINT32)obs_data_get_int(settings, "bitrate");
  24. if (!bitrate) {
  25. MF_LOG_ENCODER("AAC", encoder, LOG_ERROR,
  26. "Invalid bitrate specified");
  27. return NULL;
  28. }
  29. audio_t *audio = obs_encoder_audio(encoder);
  30. UINT32 channels = (UINT32)audio_output_get_channels(audio);
  31. UINT32 sampleRate = audio_output_get_sample_rate(audio);
  32. UINT32 bitsPerSample = 16;
  33. UINT32 recommendedSampleRate = FindBestSamplerateMatch(sampleRate);
  34. if (recommendedSampleRate != sampleRate) {
  35. MF_LOG_ENCODER("AAC", encoder, LOG_WARNING,
  36. "unsupported sample rate; "
  37. "resampling to best guess '%d' instead of '%d'",
  38. recommendedSampleRate, sampleRate);
  39. sampleRate = recommendedSampleRate;
  40. }
  41. UINT32 recommendedBitRate = FindBestBitrateMatch(bitrate);
  42. if (recommendedBitRate != bitrate) {
  43. MF_LOG_ENCODER("AAC", encoder, LOG_WARNING,
  44. "unsupported bitrate; "
  45. "resampling to best guess '%d' instead of '%d'",
  46. recommendedBitRate, bitrate);
  47. bitrate = recommendedBitRate;
  48. }
  49. std::unique_ptr<Encoder> enc(new Encoder(encoder,
  50. bitrate, channels, sampleRate, bitsPerSample));
  51. if (!enc->Initialize())
  52. return nullptr;
  53. return enc.release();
  54. }
  55. static void MFAAC_Destroy(void *data)
  56. {
  57. Encoder *enc = static_cast<Encoder *>(data);
  58. delete enc;
  59. }
  60. static bool MFAAC_Encode(void *data, struct encoder_frame *frame,
  61. struct encoder_packet *packet, bool *received_packet)
  62. {
  63. Encoder *enc = static_cast<Encoder *>(data);
  64. Status status;
  65. if (!enc->ProcessInput(frame->data[0], frame->linesize[0], frame->pts,
  66. &status))
  67. return false;
  68. // This shouldn't happen since we drain right after
  69. // we process input
  70. if (status == NOT_ACCEPTING)
  71. return false;
  72. UINT8 *outputData;
  73. UINT32 outputDataLength;
  74. UINT64 outputPts;
  75. if (!enc->ProcessOutput(&outputData, &outputDataLength, &outputPts,
  76. &status))
  77. return false;
  78. // Needs more input, not a failure case
  79. if (status == NEED_MORE_INPUT)
  80. return true;
  81. packet->pts = outputPts;
  82. packet->dts = outputPts;
  83. packet->data = outputData;
  84. packet->size = outputDataLength;
  85. packet->type = OBS_ENCODER_AUDIO;
  86. packet->timebase_num = 1;
  87. packet->timebase_den = enc->SampleRate();
  88. return *received_packet = true;
  89. }
  90. static bool MFAAC_GetExtraData(void *data, uint8_t **extra_data, size_t *size)
  91. {
  92. Encoder *enc = static_cast<Encoder *>(data);
  93. UINT32 length;
  94. if (enc->ExtraData(extra_data, &length)) {
  95. *size = length;
  96. return true;
  97. }
  98. return false;
  99. }
  100. static void MFAAC_GetAudioInfo(void *, struct audio_convert_info *info)
  101. {
  102. info->format = AUDIO_FORMAT_16BIT;
  103. info->samples_per_sec = FindBestSamplerateMatch(info->samples_per_sec);
  104. }
  105. static size_t MFAAC_GetFrameSize(void *)
  106. {
  107. return Encoder::FrameSize;
  108. }
  109. extern "C" void RegisterMFAACEncoder()
  110. {
  111. if (!IsWindows8OrGreater()) {
  112. MF_LOG(LOG_WARNING, "plugin is disabled for performance "
  113. "reasons on Windows versions prior to 8");
  114. return;
  115. }
  116. obs_encoder_info info = {};
  117. info.id = "mf_aac";
  118. info.type = OBS_ENCODER_AUDIO;
  119. info.codec = "AAC";
  120. info.get_name = MFAAC_GetName;
  121. info.create = MFAAC_Create;
  122. info.destroy = MFAAC_Destroy;
  123. info.encode = MFAAC_Encode;
  124. info.get_frame_size = MFAAC_GetFrameSize;
  125. info.get_defaults = MFAAC_GetDefaults;
  126. info.get_properties = MFAAC_GetProperties;
  127. info.get_extra_data = MFAAC_GetExtraData;
  128. info.get_audio_info = MFAAC_GetAudioInfo;
  129. MF_LOG(LOG_DEBUG, "Adding Media Foundation AAC Encoder");
  130. obs_register_encoder(&info);
  131. }