You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1214 lines
40KB

  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #define COBJMACROS
  19. #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
  20. #undef _WIN32_WINNT
  21. #define _WIN32_WINNT 0x0602
  22. #endif
  23. #include "encode.h"
  24. #include "mf_utils.h"
  25. #include "libavutil/imgutils.h"
  26. #include "libavutil/opt.h"
  27. #include "libavutil/time.h"
  28. #include "internal.h"
  29. typedef struct MFContext {
  30. AVClass *av_class;
  31. AVFrame *frame;
  32. int is_video, is_audio;
  33. GUID main_subtype;
  34. IMFTransform *mft;
  35. IMFMediaEventGenerator *async_events;
  36. DWORD in_stream_id, out_stream_id;
  37. MFT_INPUT_STREAM_INFO in_info;
  38. MFT_OUTPUT_STREAM_INFO out_info;
  39. int out_stream_provides_samples;
  40. int draining, draining_done;
  41. int sample_sent;
  42. int async_need_input, async_have_output, async_marker;
  43. int64_t reorder_delay;
  44. ICodecAPI *codec_api;
  45. // set by AVOption
  46. int opt_enc_rc;
  47. int opt_enc_quality;
  48. int opt_enc_scenario;
  49. int opt_enc_hw;
  50. } MFContext;
  51. static int mf_choose_output_type(AVCodecContext *avctx);
  52. static int mf_setup_context(AVCodecContext *avctx);
  53. #define MF_TIMEBASE (AVRational){1, 10000000}
  54. // Sentinel value only used by us.
  55. #define MF_INVALID_TIME AV_NOPTS_VALUE
  56. static int mf_wait_events(AVCodecContext *avctx)
  57. {
  58. MFContext *c = avctx->priv_data;
  59. if (!c->async_events)
  60. return 0;
  61. while (!(c->async_need_input || c->async_have_output || c->draining_done || c->async_marker)) {
  62. IMFMediaEvent *ev = NULL;
  63. MediaEventType ev_id = 0;
  64. HRESULT hr = IMFMediaEventGenerator_GetEvent(c->async_events, 0, &ev);
  65. if (FAILED(hr)) {
  66. av_log(avctx, AV_LOG_ERROR, "IMFMediaEventGenerator_GetEvent() failed: %s\n",
  67. ff_hr_str(hr));
  68. return AVERROR_EXTERNAL;
  69. }
  70. IMFMediaEvent_GetType(ev, &ev_id);
  71. switch (ev_id) {
  72. case ff_METransformNeedInput:
  73. if (!c->draining)
  74. c->async_need_input = 1;
  75. break;
  76. case ff_METransformHaveOutput:
  77. c->async_have_output = 1;
  78. break;
  79. case ff_METransformDrainComplete:
  80. c->draining_done = 1;
  81. break;
  82. case ff_METransformMarker:
  83. c->async_marker = 1;
  84. break;
  85. default: ;
  86. }
  87. IMFMediaEvent_Release(ev);
  88. }
  89. return 0;
  90. }
  91. static AVRational mf_get_tb(AVCodecContext *avctx)
  92. {
  93. if (avctx->pkt_timebase.num > 0 && avctx->pkt_timebase.den > 0)
  94. return avctx->pkt_timebase;
  95. if (avctx->time_base.num > 0 && avctx->time_base.den > 0)
  96. return avctx->time_base;
  97. return MF_TIMEBASE;
  98. }
  99. static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
  100. {
  101. if (av_pts == AV_NOPTS_VALUE)
  102. return MF_INVALID_TIME;
  103. return av_rescale_q(av_pts, mf_get_tb(avctx), MF_TIMEBASE);
  104. }
  105. static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
  106. {
  107. LONGLONG stime = mf_to_mf_time(avctx, av_pts);
  108. if (stime != MF_INVALID_TIME)
  109. IMFSample_SetSampleTime(sample, stime);
  110. }
  111. static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
  112. {
  113. return av_rescale_q(stime, MF_TIMEBASE, mf_get_tb(avctx));
  114. }
  115. static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
  116. {
  117. LONGLONG pts;
  118. HRESULT hr = IMFSample_GetSampleTime(sample, &pts);
  119. if (FAILED(hr))
  120. return AV_NOPTS_VALUE;
  121. return mf_from_mf_time(avctx, pts);
  122. }
  123. static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
  124. {
  125. MFContext *c = avctx->priv_data;
  126. HRESULT hr;
  127. UINT32 sz;
  128. if (avctx->codec_id != AV_CODEC_ID_MP3 && avctx->codec_id != AV_CODEC_ID_AC3) {
  129. hr = IMFAttributes_GetBlobSize(type, &MF_MT_USER_DATA, &sz);
  130. if (!FAILED(hr) && sz > 0) {
  131. avctx->extradata = av_mallocz(sz + AV_INPUT_BUFFER_PADDING_SIZE);
  132. if (!avctx->extradata)
  133. return AVERROR(ENOMEM);
  134. avctx->extradata_size = sz;
  135. hr = IMFAttributes_GetBlob(type, &MF_MT_USER_DATA, avctx->extradata, sz, NULL);
  136. if (FAILED(hr))
  137. return AVERROR_EXTERNAL;
  138. if (avctx->codec_id == AV_CODEC_ID_AAC && avctx->extradata_size >= 12) {
  139. // Get rid of HEAACWAVEINFO (after wfx field, 12 bytes).
  140. avctx->extradata_size = avctx->extradata_size - 12;
  141. memmove(avctx->extradata, avctx->extradata + 12, avctx->extradata_size);
  142. }
  143. }
  144. }
  145. // I don't know where it's documented that we need this. It happens with the
  146. // MS mp3 encoder MFT. The idea for the workaround is taken from NAudio.
  147. // (Certainly any lossy codec will have frames much smaller than 1 second.)
  148. if (!c->out_info.cbSize && !c->out_stream_provides_samples) {
  149. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &sz);
  150. if (!FAILED(hr)) {
  151. av_log(avctx, AV_LOG_VERBOSE, "MFT_OUTPUT_STREAM_INFO.cbSize set to 0, "
  152. "assuming %d bytes instead.\n", (int)sz);
  153. c->out_info.cbSize = sz;
  154. }
  155. }
  156. return 0;
  157. }
  158. static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
  159. {
  160. HRESULT hr;
  161. UINT32 sz;
  162. hr = IMFAttributes_GetBlobSize(type, &MF_MT_MPEG_SEQUENCE_HEADER, &sz);
  163. if (!FAILED(hr) && sz > 0) {
  164. uint8_t *extradata = av_mallocz(sz + AV_INPUT_BUFFER_PADDING_SIZE);
  165. if (!extradata)
  166. return AVERROR(ENOMEM);
  167. hr = IMFAttributes_GetBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, extradata, sz, NULL);
  168. if (FAILED(hr)) {
  169. av_free(extradata);
  170. return AVERROR_EXTERNAL;
  171. }
  172. av_freep(&avctx->extradata);
  173. avctx->extradata = extradata;
  174. avctx->extradata_size = sz;
  175. }
  176. return 0;
  177. }
  178. static int mf_output_type_get(AVCodecContext *avctx)
  179. {
  180. MFContext *c = avctx->priv_data;
  181. HRESULT hr;
  182. IMFMediaType *type;
  183. int ret;
  184. hr = IMFTransform_GetOutputCurrentType(c->mft, c->out_stream_id, &type);
  185. if (FAILED(hr)) {
  186. av_log(avctx, AV_LOG_ERROR, "could not get output type\n");
  187. return AVERROR_EXTERNAL;
  188. }
  189. av_log(avctx, AV_LOG_VERBOSE, "final output type:\n");
  190. ff_media_type_dump(avctx, type);
  191. ret = 0;
  192. if (c->is_video) {
  193. ret = mf_encv_output_type_get(avctx, type);
  194. } else if (c->is_audio) {
  195. ret = mf_enca_output_type_get(avctx, type);
  196. }
  197. if (ret < 0)
  198. av_log(avctx, AV_LOG_ERROR, "output type not supported\n");
  199. IMFMediaType_Release(type);
  200. return ret;
  201. }
  202. static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
  203. {
  204. MFContext *c = avctx->priv_data;
  205. HRESULT hr;
  206. int ret;
  207. DWORD len;
  208. IMFMediaBuffer *buffer;
  209. BYTE *data;
  210. UINT64 t;
  211. UINT32 t32;
  212. hr = IMFSample_GetTotalLength(sample, &len);
  213. if (FAILED(hr))
  214. return AVERROR_EXTERNAL;
  215. if ((ret = ff_get_encode_buffer(avctx, avpkt, len, 0)) < 0)
  216. return ret;
  217. IMFSample_ConvertToContiguousBuffer(sample, &buffer);
  218. if (FAILED(hr))
  219. return AVERROR_EXTERNAL;
  220. hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
  221. if (FAILED(hr)) {
  222. IMFMediaBuffer_Release(buffer);
  223. return AVERROR_EXTERNAL;
  224. }
  225. memcpy(avpkt->data, data, len);
  226. IMFMediaBuffer_Unlock(buffer);
  227. IMFMediaBuffer_Release(buffer);
  228. avpkt->pts = avpkt->dts = mf_sample_get_pts(avctx, sample);
  229. hr = IMFAttributes_GetUINT32(sample, &MFSampleExtension_CleanPoint, &t32);
  230. if (c->is_audio || (!FAILED(hr) && t32 != 0))
  231. avpkt->flags |= AV_PKT_FLAG_KEY;
  232. hr = IMFAttributes_GetUINT64(sample, &MFSampleExtension_DecodeTimestamp, &t);
  233. if (!FAILED(hr)) {
  234. avpkt->dts = mf_from_mf_time(avctx, t);
  235. // At least on Qualcomm's HEVC encoder on SD 835, the output dts
  236. // starts from the input pts of the first frame, while the output pts
  237. // is shifted forward. Therefore, shift the output values back so that
  238. // the output pts matches the input.
  239. if (c->reorder_delay == AV_NOPTS_VALUE)
  240. c->reorder_delay = avpkt->pts - avpkt->dts;
  241. avpkt->dts -= c->reorder_delay;
  242. avpkt->pts -= c->reorder_delay;
  243. }
  244. return 0;
  245. }
  246. static IMFSample *mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
  247. {
  248. MFContext *c = avctx->priv_data;
  249. size_t len;
  250. size_t bps;
  251. IMFSample *sample;
  252. bps = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->channels;
  253. len = frame->nb_samples * bps;
  254. sample = ff_create_memory_sample(frame->data[0], len, c->in_info.cbAlignment);
  255. if (sample)
  256. IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->nb_samples));
  257. return sample;
  258. }
  259. static IMFSample *mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
  260. {
  261. MFContext *c = avctx->priv_data;
  262. IMFSample *sample;
  263. IMFMediaBuffer *buffer;
  264. BYTE *data;
  265. HRESULT hr;
  266. int ret;
  267. int size;
  268. size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
  269. if (size < 0)
  270. return NULL;
  271. sample = ff_create_memory_sample(NULL, size, c->in_info.cbAlignment);
  272. if (!sample)
  273. return NULL;
  274. hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
  275. if (FAILED(hr)) {
  276. IMFSample_Release(sample);
  277. return NULL;
  278. }
  279. hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
  280. if (FAILED(hr)) {
  281. IMFMediaBuffer_Release(buffer);
  282. IMFSample_Release(sample);
  283. return NULL;
  284. }
  285. ret = av_image_copy_to_buffer((uint8_t *)data, size, (void *)frame->data, frame->linesize,
  286. avctx->pix_fmt, avctx->width, avctx->height, 1);
  287. IMFMediaBuffer_SetCurrentLength(buffer, size);
  288. IMFMediaBuffer_Unlock(buffer);
  289. IMFMediaBuffer_Release(buffer);
  290. if (ret < 0) {
  291. IMFSample_Release(sample);
  292. return NULL;
  293. }
  294. IMFSample_SetSampleDuration(sample, mf_to_mf_time(avctx, frame->pkt_duration));
  295. return sample;
  296. }
  297. static IMFSample *mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
  298. {
  299. MFContext *c = avctx->priv_data;
  300. IMFSample *sample;
  301. if (c->is_audio) {
  302. sample = mf_a_avframe_to_sample(avctx, frame);
  303. } else {
  304. sample = mf_v_avframe_to_sample(avctx, frame);
  305. }
  306. if (sample)
  307. mf_sample_set_pts(avctx, sample, frame->pts);
  308. return sample;
  309. }
  310. static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
  311. {
  312. MFContext *c = avctx->priv_data;
  313. HRESULT hr;
  314. int ret;
  315. if (sample) {
  316. if (c->async_events) {
  317. if ((ret = mf_wait_events(avctx)) < 0)
  318. return ret;
  319. if (!c->async_need_input)
  320. return AVERROR(EAGAIN);
  321. }
  322. if (!c->sample_sent)
  323. IMFSample_SetUINT32(sample, &MFSampleExtension_Discontinuity, TRUE);
  324. c->sample_sent = 1;
  325. hr = IMFTransform_ProcessInput(c->mft, c->in_stream_id, sample, 0);
  326. if (hr == MF_E_NOTACCEPTING) {
  327. return AVERROR(EAGAIN);
  328. } else if (FAILED(hr)) {
  329. av_log(avctx, AV_LOG_ERROR, "failed processing input: %s\n", ff_hr_str(hr));
  330. return AVERROR_EXTERNAL;
  331. }
  332. c->async_need_input = 0;
  333. } else if (!c->draining) {
  334. hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_COMMAND_DRAIN, 0);
  335. if (FAILED(hr))
  336. av_log(avctx, AV_LOG_ERROR, "failed draining: %s\n", ff_hr_str(hr));
  337. // Some MFTs (AC3) will send a frame after each drain command (???), so
  338. // this is required to make draining actually terminate.
  339. c->draining = 1;
  340. c->async_need_input = 0;
  341. } else {
  342. return AVERROR_EOF;
  343. }
  344. return 0;
  345. }
  346. static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
  347. {
  348. MFContext *c = avctx->priv_data;
  349. HRESULT hr;
  350. DWORD st;
  351. MFT_OUTPUT_DATA_BUFFER out_buffers;
  352. IMFSample *sample;
  353. int ret = 0;
  354. while (1) {
  355. *out_sample = NULL;
  356. sample = NULL;
  357. if (c->async_events) {
  358. if ((ret = mf_wait_events(avctx)) < 0)
  359. return ret;
  360. if (!c->async_have_output || c->draining_done) {
  361. ret = 0;
  362. break;
  363. }
  364. }
  365. if (!c->out_stream_provides_samples) {
  366. sample = ff_create_memory_sample(NULL, c->out_info.cbSize, c->out_info.cbAlignment);
  367. if (!sample)
  368. return AVERROR(ENOMEM);
  369. }
  370. out_buffers = (MFT_OUTPUT_DATA_BUFFER) {
  371. .dwStreamID = c->out_stream_id,
  372. .pSample = sample,
  373. };
  374. st = 0;
  375. hr = IMFTransform_ProcessOutput(c->mft, 0, 1, &out_buffers, &st);
  376. if (out_buffers.pEvents)
  377. IMFCollection_Release(out_buffers.pEvents);
  378. if (!FAILED(hr)) {
  379. *out_sample = out_buffers.pSample;
  380. ret = 0;
  381. break;
  382. }
  383. if (out_buffers.pSample)
  384. IMFSample_Release(out_buffers.pSample);
  385. if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
  386. if (c->draining)
  387. c->draining_done = 1;
  388. ret = 0;
  389. } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
  390. av_log(avctx, AV_LOG_WARNING, "stream format change\n");
  391. ret = mf_choose_output_type(avctx);
  392. if (ret == 0) // we don't expect renegotiating the input type
  393. ret = AVERROR_EXTERNAL;
  394. if (ret > 0) {
  395. ret = mf_setup_context(avctx);
  396. if (ret >= 0) {
  397. c->async_have_output = 0;
  398. continue;
  399. }
  400. }
  401. } else {
  402. av_log(avctx, AV_LOG_ERROR, "failed processing output: %s\n", ff_hr_str(hr));
  403. ret = AVERROR_EXTERNAL;
  404. }
  405. break;
  406. }
  407. c->async_have_output = 0;
  408. if (ret >= 0 && !*out_sample)
  409. ret = c->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
  410. return ret;
  411. }
  412. static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
  413. {
  414. MFContext *c = avctx->priv_data;
  415. IMFSample *sample = NULL;
  416. int ret;
  417. if (!c->frame->buf[0]) {
  418. ret = ff_encode_get_frame(avctx, c->frame);
  419. if (ret < 0 && ret != AVERROR_EOF)
  420. return ret;
  421. }
  422. if (c->frame->buf[0]) {
  423. sample = mf_avframe_to_sample(avctx, c->frame);
  424. if (!sample) {
  425. av_frame_unref(c->frame);
  426. return AVERROR(ENOMEM);
  427. }
  428. if (c->is_video && c->codec_api) {
  429. if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent)
  430. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1));
  431. }
  432. }
  433. ret = mf_send_sample(avctx, sample);
  434. if (sample)
  435. IMFSample_Release(sample);
  436. if (ret != AVERROR(EAGAIN))
  437. av_frame_unref(c->frame);
  438. if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
  439. return ret;
  440. ret = mf_receive_sample(avctx, &sample);
  441. if (ret < 0)
  442. return ret;
  443. ret = mf_sample_to_avpacket(avctx, sample, avpkt);
  444. IMFSample_Release(sample);
  445. return ret;
  446. }
  447. // Most encoders seem to enumerate supported audio formats on the output types,
  448. // at least as far as channel configuration and sample rate is concerned. Pick
  449. // the one which seems to match best.
  450. static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
  451. {
  452. MFContext *c = avctx->priv_data;
  453. HRESULT hr;
  454. UINT32 t;
  455. GUID tg;
  456. int64_t score = 0;
  457. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
  458. if (!FAILED(hr) && t == avctx->sample_rate)
  459. score |= 1LL << 32;
  460. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
  461. if (!FAILED(hr) && t == avctx->channels)
  462. score |= 2LL << 32;
  463. hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
  464. if (!FAILED(hr)) {
  465. if (IsEqualGUID(&c->main_subtype, &tg))
  466. score |= 4LL << 32;
  467. }
  468. // Select the bitrate (lowest priority).
  469. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
  470. if (!FAILED(hr)) {
  471. int diff = (int)t - avctx->bit_rate / 8;
  472. if (diff >= 0) {
  473. score |= (1LL << 31) - diff; // prefer lower bitrate
  474. } else {
  475. score |= (1LL << 30) + diff; // prefer higher bitrate
  476. }
  477. }
  478. hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &t);
  479. if (!FAILED(hr) && t != 0)
  480. return -1;
  481. return score;
  482. }
  483. static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
  484. {
  485. // (some decoders allow adjusting this freely, but it can also cause failure
  486. // to set the output type - so it's commented for being too fragile)
  487. //IMFAttributes_SetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avctx->bit_rate / 8);
  488. //IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
  489. return 0;
  490. }
  491. static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
  492. {
  493. HRESULT hr;
  494. UINT32 t;
  495. int64_t score = 0;
  496. enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
  497. if (sformat == AV_SAMPLE_FMT_NONE)
  498. return -1; // can not use
  499. if (sformat == avctx->sample_fmt)
  500. score |= 1;
  501. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
  502. if (!FAILED(hr) && t == avctx->sample_rate)
  503. score |= 2;
  504. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
  505. if (!FAILED(hr) && t == avctx->channels)
  506. score |= 4;
  507. return score;
  508. }
  509. static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
  510. {
  511. HRESULT hr;
  512. UINT32 t;
  513. enum AVSampleFormat sformat = ff_media_type_to_sample_fmt((IMFAttributes *)type);
  514. if (sformat != avctx->sample_fmt) {
  515. av_log(avctx, AV_LOG_ERROR, "unsupported input sample format set\n");
  516. return AVERROR(EINVAL);
  517. }
  518. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
  519. if (FAILED(hr) || t != avctx->sample_rate) {
  520. av_log(avctx, AV_LOG_ERROR, "unsupported input sample rate set\n");
  521. return AVERROR(EINVAL);
  522. }
  523. hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
  524. if (FAILED(hr) || t != avctx->channels) {
  525. av_log(avctx, AV_LOG_ERROR, "unsupported input channel number set\n");
  526. return AVERROR(EINVAL);
  527. }
  528. return 0;
  529. }
  530. static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
  531. {
  532. MFContext *c = avctx->priv_data;
  533. GUID tg;
  534. HRESULT hr;
  535. int score = -1;
  536. hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
  537. if (!FAILED(hr)) {
  538. if (IsEqualGUID(&c->main_subtype, &tg))
  539. score = 1;
  540. }
  541. return score;
  542. }
  543. static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
  544. {
  545. MFContext *c = avctx->priv_data;
  546. AVRational framerate;
  547. ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
  548. IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
  549. if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
  550. framerate = avctx->framerate;
  551. } else {
  552. framerate = av_inv_q(avctx->time_base);
  553. framerate.den *= avctx->ticks_per_frame;
  554. }
  555. ff_MFSetAttributeRatio((IMFAttributes *)type, &MF_MT_FRAME_RATE, framerate.num, framerate.den);
  556. // (MS HEVC supports eAVEncH265VProfile_Main_420_8 only.)
  557. if (avctx->codec_id == AV_CODEC_ID_H264) {
  558. UINT32 profile = ff_eAVEncH264VProfile_Base;
  559. switch (avctx->profile) {
  560. case FF_PROFILE_H264_MAIN:
  561. profile = ff_eAVEncH264VProfile_Main;
  562. break;
  563. case FF_PROFILE_H264_HIGH:
  564. profile = ff_eAVEncH264VProfile_High;
  565. break;
  566. }
  567. IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
  568. }
  569. IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
  570. // Note that some of the ICodecAPI options must be set before SetOutputType.
  571. if (c->codec_api) {
  572. if (avctx->bit_rate)
  573. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonMeanBitRate, FF_VAL_VT_UI4(avctx->bit_rate));
  574. if (c->opt_enc_rc >= 0)
  575. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonRateControlMode, FF_VAL_VT_UI4(c->opt_enc_rc));
  576. if (c->opt_enc_quality >= 0)
  577. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncCommonQuality, FF_VAL_VT_UI4(c->opt_enc_quality));
  578. // Always set the number of b-frames. Qualcomm's HEVC encoder on SD835
  579. // defaults this to 1, and that setting is buggy with many of the
  580. // rate control modes. (0 or 2 b-frames works fine with most rate
  581. // control modes, but 2 seems buggy with the u_vbr mode.) Setting
  582. // "scenario" to "camera_record" sets it in CFR mode (where the default
  583. // is VFR), which makes the encoder avoid dropping frames.
  584. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncMPVDefaultBPictureCount, FF_VAL_VT_UI4(avctx->max_b_frames));
  585. avctx->has_b_frames = avctx->max_b_frames > 0;
  586. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncH264CABACEnable, FF_VAL_VT_BOOL(1));
  587. if (c->opt_enc_scenario >= 0)
  588. ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVScenarioInfo, FF_VAL_VT_UI4(c->opt_enc_scenario));
  589. }
  590. return 0;
  591. }
  592. static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
  593. {
  594. enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
  595. if (pix_fmt != avctx->pix_fmt)
  596. return -1; // can not use
  597. return 0;
  598. }
  599. static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
  600. {
  601. enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
  602. if (pix_fmt != avctx->pix_fmt) {
  603. av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
  604. return AVERROR(EINVAL);
  605. }
  606. //ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
  607. return 0;
  608. }
  609. static int mf_choose_output_type(AVCodecContext *avctx)
  610. {
  611. MFContext *c = avctx->priv_data;
  612. HRESULT hr;
  613. int ret;
  614. IMFMediaType *out_type = NULL;
  615. int64_t out_type_score = -1;
  616. int out_type_index = -1;
  617. int n;
  618. av_log(avctx, AV_LOG_VERBOSE, "output types:\n");
  619. for (n = 0; ; n++) {
  620. IMFMediaType *type;
  621. int64_t score = -1;
  622. hr = IMFTransform_GetOutputAvailableType(c->mft, c->out_stream_id, n, &type);
  623. if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
  624. break;
  625. if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
  626. av_log(avctx, AV_LOG_VERBOSE, "(need to set input type)\n");
  627. ret = 0;
  628. goto done;
  629. }
  630. if (FAILED(hr)) {
  631. av_log(avctx, AV_LOG_ERROR, "error getting output type: %s\n", ff_hr_str(hr));
  632. ret = AVERROR_EXTERNAL;
  633. goto done;
  634. }
  635. av_log(avctx, AV_LOG_VERBOSE, "output type %d:\n", n);
  636. ff_media_type_dump(avctx, type);
  637. if (c->is_video) {
  638. score = mf_encv_output_score(avctx, type);
  639. } else if (c->is_audio) {
  640. score = mf_enca_output_score(avctx, type);
  641. }
  642. if (score > out_type_score) {
  643. if (out_type)
  644. IMFMediaType_Release(out_type);
  645. out_type = type;
  646. out_type_score = score;
  647. out_type_index = n;
  648. IMFMediaType_AddRef(out_type);
  649. }
  650. IMFMediaType_Release(type);
  651. }
  652. if (out_type) {
  653. av_log(avctx, AV_LOG_VERBOSE, "picking output type %d.\n", out_type_index);
  654. } else {
  655. hr = MFCreateMediaType(&out_type);
  656. if (FAILED(hr)) {
  657. ret = AVERROR(ENOMEM);
  658. goto done;
  659. }
  660. }
  661. ret = 0;
  662. if (c->is_video) {
  663. ret = mf_encv_output_adjust(avctx, out_type);
  664. } else if (c->is_audio) {
  665. ret = mf_enca_output_adjust(avctx, out_type);
  666. }
  667. if (ret >= 0) {
  668. av_log(avctx, AV_LOG_VERBOSE, "setting output type:\n");
  669. ff_media_type_dump(avctx, out_type);
  670. hr = IMFTransform_SetOutputType(c->mft, c->out_stream_id, out_type, 0);
  671. if (!FAILED(hr)) {
  672. ret = 1;
  673. } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
  674. av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set input type\n");
  675. ret = 0;
  676. } else {
  677. av_log(avctx, AV_LOG_ERROR, "could not set output type (%s)\n", ff_hr_str(hr));
  678. ret = AVERROR_EXTERNAL;
  679. }
  680. }
  681. done:
  682. if (out_type)
  683. IMFMediaType_Release(out_type);
  684. return ret;
  685. }
  686. static int mf_choose_input_type(AVCodecContext *avctx)
  687. {
  688. MFContext *c = avctx->priv_data;
  689. HRESULT hr;
  690. int ret;
  691. IMFMediaType *in_type = NULL;
  692. int64_t in_type_score = -1;
  693. int in_type_index = -1;
  694. int n;
  695. av_log(avctx, AV_LOG_VERBOSE, "input types:\n");
  696. for (n = 0; ; n++) {
  697. IMFMediaType *type = NULL;
  698. int64_t score = -1;
  699. hr = IMFTransform_GetInputAvailableType(c->mft, c->in_stream_id, n, &type);
  700. if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
  701. break;
  702. if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
  703. av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 1)\n");
  704. ret = 0;
  705. goto done;
  706. }
  707. if (FAILED(hr)) {
  708. av_log(avctx, AV_LOG_ERROR, "error getting input type: %s\n", ff_hr_str(hr));
  709. ret = AVERROR_EXTERNAL;
  710. goto done;
  711. }
  712. av_log(avctx, AV_LOG_VERBOSE, "input type %d:\n", n);
  713. ff_media_type_dump(avctx, type);
  714. if (c->is_video) {
  715. score = mf_encv_input_score(avctx, type);
  716. } else if (c->is_audio) {
  717. score = mf_enca_input_score(avctx, type);
  718. }
  719. if (score > in_type_score) {
  720. if (in_type)
  721. IMFMediaType_Release(in_type);
  722. in_type = type;
  723. in_type_score = score;
  724. in_type_index = n;
  725. IMFMediaType_AddRef(in_type);
  726. }
  727. IMFMediaType_Release(type);
  728. }
  729. if (in_type) {
  730. av_log(avctx, AV_LOG_VERBOSE, "picking input type %d.\n", in_type_index);
  731. } else {
  732. // Some buggy MFTs (WMA encoder) fail to return MF_E_TRANSFORM_TYPE_NOT_SET.
  733. av_log(avctx, AV_LOG_VERBOSE, "(need to set output type 2)\n");
  734. ret = 0;
  735. goto done;
  736. }
  737. ret = 0;
  738. if (c->is_video) {
  739. ret = mf_encv_input_adjust(avctx, in_type);
  740. } else if (c->is_audio) {
  741. ret = mf_enca_input_adjust(avctx, in_type);
  742. }
  743. if (ret >= 0) {
  744. av_log(avctx, AV_LOG_VERBOSE, "setting input type:\n");
  745. ff_media_type_dump(avctx, in_type);
  746. hr = IMFTransform_SetInputType(c->mft, c->in_stream_id, in_type, 0);
  747. if (!FAILED(hr)) {
  748. ret = 1;
  749. } else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
  750. av_log(avctx, AV_LOG_VERBOSE, "rejected - need to set output type\n");
  751. ret = 0;
  752. } else {
  753. av_log(avctx, AV_LOG_ERROR, "could not set input type (%s)\n", ff_hr_str(hr));
  754. ret = AVERROR_EXTERNAL;
  755. }
  756. }
  757. done:
  758. if (in_type)
  759. IMFMediaType_Release(in_type);
  760. return ret;
  761. }
  762. static int mf_negotiate_types(AVCodecContext *avctx)
  763. {
  764. // This follows steps 1-5 on:
  765. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa965264(v=vs.85).aspx
  766. // If every MFT implementer does this correctly, this loop should at worst
  767. // be repeated once.
  768. int need_input = 1, need_output = 1;
  769. int n;
  770. for (n = 0; n < 2 && (need_input || need_output); n++) {
  771. int ret;
  772. ret = mf_choose_input_type(avctx);
  773. if (ret < 0)
  774. return ret;
  775. need_input = ret < 1;
  776. ret = mf_choose_output_type(avctx);
  777. if (ret < 0)
  778. return ret;
  779. need_output = ret < 1;
  780. }
  781. if (need_input || need_output) {
  782. av_log(avctx, AV_LOG_ERROR, "format negotiation failed (%d/%d)\n",
  783. need_input, need_output);
  784. return AVERROR_EXTERNAL;
  785. }
  786. return 0;
  787. }
  788. static int mf_setup_context(AVCodecContext *avctx)
  789. {
  790. MFContext *c = avctx->priv_data;
  791. HRESULT hr;
  792. int ret;
  793. hr = IMFTransform_GetInputStreamInfo(c->mft, c->in_stream_id, &c->in_info);
  794. if (FAILED(hr))
  795. return AVERROR_EXTERNAL;
  796. av_log(avctx, AV_LOG_VERBOSE, "in_info: size=%d, align=%d\n",
  797. (int)c->in_info.cbSize, (int)c->in_info.cbAlignment);
  798. hr = IMFTransform_GetOutputStreamInfo(c->mft, c->out_stream_id, &c->out_info);
  799. if (FAILED(hr))
  800. return AVERROR_EXTERNAL;
  801. c->out_stream_provides_samples =
  802. (c->out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
  803. (c->out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
  804. av_log(avctx, AV_LOG_VERBOSE, "out_info: size=%d, align=%d%s\n",
  805. (int)c->out_info.cbSize, (int)c->out_info.cbAlignment,
  806. c->out_stream_provides_samples ? " (provides samples)" : "");
  807. if ((ret = mf_output_type_get(avctx)) < 0)
  808. return ret;
  809. return 0;
  810. }
  811. static int mf_unlock_async(AVCodecContext *avctx)
  812. {
  813. MFContext *c = avctx->priv_data;
  814. HRESULT hr;
  815. IMFAttributes *attrs;
  816. UINT32 v;
  817. int res = AVERROR_EXTERNAL;
  818. // For hw encoding we unfortunately need to use async mode, otherwise
  819. // play it safe and avoid it.
  820. if (!(c->is_video && c->opt_enc_hw))
  821. return 0;
  822. hr = IMFTransform_GetAttributes(c->mft, &attrs);
  823. if (FAILED(hr)) {
  824. av_log(avctx, AV_LOG_ERROR, "error retrieving MFT attributes: %s\n", ff_hr_str(hr));
  825. goto err;
  826. }
  827. hr = IMFAttributes_GetUINT32(attrs, &MF_TRANSFORM_ASYNC, &v);
  828. if (FAILED(hr)) {
  829. av_log(avctx, AV_LOG_ERROR, "error querying async: %s\n", ff_hr_str(hr));
  830. goto err;
  831. }
  832. if (!v) {
  833. av_log(avctx, AV_LOG_ERROR, "hardware MFT is not async\n");
  834. goto err;
  835. }
  836. hr = IMFAttributes_SetUINT32(attrs, &MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
  837. if (FAILED(hr)) {
  838. av_log(avctx, AV_LOG_ERROR, "could not set async unlock: %s\n", ff_hr_str(hr));
  839. goto err;
  840. }
  841. hr = IMFTransform_QueryInterface(c->mft, &IID_IMFMediaEventGenerator, (void **)&c->async_events);
  842. if (FAILED(hr)) {
  843. av_log(avctx, AV_LOG_ERROR, "could not get async interface\n");
  844. goto err;
  845. }
  846. res = 0;
  847. err:
  848. IMFAttributes_Release(attrs);
  849. return res;
  850. }
  851. static int mf_create(void *log, IMFTransform **mft, const AVCodec *codec, int use_hw)
  852. {
  853. int is_audio = codec->type == AVMEDIA_TYPE_AUDIO;
  854. const CLSID *subtype = ff_codec_to_mf_subtype(codec->id);
  855. MFT_REGISTER_TYPE_INFO reg = {0};
  856. GUID category;
  857. int ret;
  858. *mft = NULL;
  859. if (!subtype)
  860. return AVERROR(ENOSYS);
  861. reg.guidSubtype = *subtype;
  862. if (is_audio) {
  863. reg.guidMajorType = MFMediaType_Audio;
  864. category = MFT_CATEGORY_AUDIO_ENCODER;
  865. } else {
  866. reg.guidMajorType = MFMediaType_Video;
  867. category = MFT_CATEGORY_VIDEO_ENCODER;
  868. }
  869. if ((ret = ff_instantiate_mf(log, category, NULL, &reg, use_hw, mft)) < 0)
  870. return ret;
  871. return 0;
  872. }
  873. static int mf_init(AVCodecContext *avctx)
  874. {
  875. MFContext *c = avctx->priv_data;
  876. HRESULT hr;
  877. int ret;
  878. const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id);
  879. int use_hw = 0;
  880. c->frame = av_frame_alloc();
  881. if (!c->frame)
  882. return AVERROR(ENOMEM);
  883. c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO;
  884. c->is_video = !c->is_audio;
  885. c->reorder_delay = AV_NOPTS_VALUE;
  886. if (c->is_video && c->opt_enc_hw)
  887. use_hw = 1;
  888. if (!subtype)
  889. return AVERROR(ENOSYS);
  890. c->main_subtype = *subtype;
  891. if ((ret = mf_create(avctx, &c->mft, avctx->codec, use_hw)) < 0)
  892. return ret;
  893. if ((ret = mf_unlock_async(avctx)) < 0)
  894. return ret;
  895. hr = IMFTransform_QueryInterface(c->mft, &IID_ICodecAPI, (void **)&c->codec_api);
  896. if (!FAILED(hr))
  897. av_log(avctx, AV_LOG_VERBOSE, "MFT supports ICodecAPI.\n");
  898. hr = IMFTransform_GetStreamIDs(c->mft, 1, &c->in_stream_id, 1, &c->out_stream_id);
  899. if (hr == E_NOTIMPL) {
  900. c->in_stream_id = c->out_stream_id = 0;
  901. } else if (FAILED(hr)) {
  902. av_log(avctx, AV_LOG_ERROR, "could not get stream IDs (%s)\n", ff_hr_str(hr));
  903. return AVERROR_EXTERNAL;
  904. }
  905. if ((ret = mf_negotiate_types(avctx)) < 0)
  906. return ret;
  907. if ((ret = mf_setup_context(avctx)) < 0)
  908. return ret;
  909. hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
  910. if (FAILED(hr)) {
  911. av_log(avctx, AV_LOG_ERROR, "could not start streaming (%s)\n", ff_hr_str(hr));
  912. return AVERROR_EXTERNAL;
  913. }
  914. hr = IMFTransform_ProcessMessage(c->mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
  915. if (FAILED(hr)) {
  916. av_log(avctx, AV_LOG_ERROR, "could not start stream (%s)\n", ff_hr_str(hr));
  917. return AVERROR_EXTERNAL;
  918. }
  919. if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER && c->async_events &&
  920. c->is_video && !avctx->extradata) {
  921. int sleep = 10000, total = 0;
  922. av_log(avctx, AV_LOG_VERBOSE, "Awaiting extradata\n");
  923. while (total < 70*1000) {
  924. // The Qualcomm H264 encoder on SD835 doesn't provide extradata
  925. // immediately, but it becomes available soon after init (without
  926. // any waitable event). In practice, it's available after less
  927. // than 10 ms, but wait for up to 70 ms before giving up.
  928. // Some encoders (Qualcomm's HEVC encoder on SD835, some versions
  929. // of the QSV H264 encoder at least) don't provide extradata this
  930. // way at all, not even after encoding a frame - it's only
  931. // available prepended to frames.
  932. av_usleep(sleep);
  933. total += sleep;
  934. mf_output_type_get(avctx);
  935. if (avctx->extradata)
  936. break;
  937. sleep *= 2;
  938. }
  939. av_log(avctx, AV_LOG_VERBOSE, "%s extradata in %d ms\n",
  940. avctx->extradata ? "Got" : "Didn't get", total / 1000);
  941. }
  942. return 0;
  943. }
  944. static int mf_close(AVCodecContext *avctx)
  945. {
  946. MFContext *c = avctx->priv_data;
  947. if (c->codec_api)
  948. ICodecAPI_Release(c->codec_api);
  949. if (c->async_events)
  950. IMFMediaEventGenerator_Release(c->async_events);
  951. ff_free_mf(&c->mft);
  952. av_frame_free(&c->frame);
  953. av_freep(&avctx->extradata);
  954. avctx->extradata_size = 0;
  955. return 0;
  956. }
  957. #define OFFSET(x) offsetof(MFContext, x)
  958. #define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA) \
  959. static const AVClass ff_ ## NAME ## _mf_encoder_class = { \
  960. .class_name = #NAME "_mf", \
  961. .item_name = av_default_item_name, \
  962. .option = OPTS, \
  963. .version = LIBAVUTIL_VERSION_INT, \
  964. }; \
  965. AVCodec ff_ ## NAME ## _mf_encoder = { \
  966. .priv_class = &ff_ ## NAME ## _mf_encoder_class, \
  967. .name = #NAME "_mf", \
  968. .long_name = NULL_IF_CONFIG_SMALL(#ID " via MediaFoundation"), \
  969. .type = AVMEDIA_TYPE_ ## MEDIATYPE, \
  970. .id = AV_CODEC_ID_ ## ID, \
  971. .priv_data_size = sizeof(MFContext), \
  972. .init = mf_init, \
  973. .close = mf_close, \
  974. .receive_packet = mf_receive_packet, \
  975. EXTRA \
  976. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
  977. AV_CODEC_CAP_DR1, \
  978. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | \
  979. FF_CODEC_CAP_INIT_CLEANUP, \
  980. };
  981. #define AFMTS \
  982. .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, \
  983. AV_SAMPLE_FMT_NONE },
  984. MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS);
  985. MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS);
  986. MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS);
  987. #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
  988. static const AVOption venc_opts[] = {
  989. {"rate_control", "Select rate control mode", OFFSET(opt_enc_rc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "rate_control"},
  990. { "default", "Default mode", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, "rate_control"},
  991. { "cbr", "CBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_CBR}, 0, 0, VE, "rate_control"},
  992. { "pc_vbr", "Peak constrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_PeakConstrainedVBR}, 0, 0, VE, "rate_control"},
  993. { "u_vbr", "Unconstrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_UnconstrainedVBR}, 0, 0, VE, "rate_control"},
  994. { "quality", "Quality mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_Quality}, 0, 0, VE, "rate_control" },
  995. // The following rate_control modes require Windows 8.
  996. { "ld_vbr", "Low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_LowDelayVBR}, 0, 0, VE, "rate_control"},
  997. { "g_vbr", "Global VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalVBR}, 0, 0, VE, "rate_control" },
  998. { "gld_vbr", "Global low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR}, 0, 0, VE, "rate_control"},
  999. {"scenario", "Select usage scenario", OFFSET(opt_enc_scenario), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "scenario"},
  1000. { "default", "Default scenario", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, "scenario"},
  1001. { "display_remoting", "Display remoting", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemoting}, 0, 0, VE, "scenario"},
  1002. { "video_conference", "Video conference", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_VideoConference}, 0, 0, VE, "scenario"},
  1003. { "archive", "Archive", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_Archive}, 0, 0, VE, "scenario"},
  1004. { "live_streaming", "Live streaming", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_LiveStreaming}, 0, 0, VE, "scenario"},
  1005. { "camera_record", "Camera record", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_CameraRecord}, 0, 0, VE, "scenario"},
  1006. { "display_remoting_with_feature_map", "Display remoting with feature map", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap}, 0, 0, VE, "scenario"},
  1007. {"quality", "Quality", OFFSET(opt_enc_quality), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
  1008. {"hw_encoding", "Force hardware encoding", OFFSET(opt_enc_hw), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE},
  1009. {NULL}
  1010. };
  1011. #define VFMTS \
  1012. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \
  1013. AV_PIX_FMT_YUV420P, \
  1014. AV_PIX_FMT_NONE },
  1015. MF_ENCODER(VIDEO, h264, H264, venc_opts, VFMTS);
  1016. MF_ENCODER(VIDEO, hevc, HEVC, venc_opts, VFMTS);