record_desktop_wgc.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include "record_desktop_wgc.h"
  2. #include "utils_string.h"
  3. #include "error_define.h"
  4. #include "log_helper.h"
  5. #include "system_error.h"
  6. BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, HDC hdc, LPRECT lprc, LPARAM data)
  7. {
  8. MONITORINFOEX info_ex;
  9. info_ex.cbSize = sizeof(MONITORINFOEX);
  10. GetMonitorInfo(hmonitor, &info_ex);
  11. if (info_ex.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER)
  12. return true;
  13. if (info_ex.dwFlags & MONITORINFOF_PRIMARY) {
  14. *(HMONITOR *) data = hmonitor;
  15. }
  16. return true;
  17. }
  18. HMONITOR GetPrimaryMonitor()
  19. {
  20. HMONITOR hmonitor = nullptr;
  21. ::EnumDisplayMonitors(NULL, NULL, EnumMonitorProc, (LPARAM) &hmonitor);
  22. return hmonitor;
  23. }
  24. namespace am {
  25. record_desktop_wgc::record_desktop_wgc() {}
  26. record_desktop_wgc::~record_desktop_wgc()
  27. {
  28. stop();
  29. clean_up();
  30. }
  31. int record_desktop_wgc::init(const RECORD_DESKTOP_RECT &rect, const int fps)
  32. {
  33. int error = AE_NO;
  34. if (_inited == true)
  35. return error;
  36. _fps = fps;
  37. _rect = rect;
  38. _start_time = av_gettime_relative();
  39. _time_base = {1, AV_TIME_BASE};
  40. _pixel_fmt = AV_PIX_FMT_BGRA;
  41. do {
  42. if (!module_.is_supported()) {
  43. error = AE_UNSUPPORT;
  44. break;
  45. }
  46. session_ = module_.create_session();
  47. if (!session_) {
  48. error = AE_WGC_CREATE_CAPTURER_FAILED;
  49. break;
  50. }
  51. session_->register_observer(this);
  52. error = session_->initialize(GetPrimaryMonitor());
  53. _inited = true;
  54. } while (0);
  55. if (error != AE_NO) {
  56. al_debug("%s,last error:%s",
  57. err2str(error),
  58. system_error::error2str(GetLastError()).c_str());
  59. }
  60. return error;
  61. }
  62. int record_desktop_wgc::start()
  63. {
  64. if (_running == true) {
  65. al_warn("record desktop duplication is already running");
  66. return AE_NO;
  67. }
  68. if (_inited == false) {
  69. return AE_NEED_INIT;
  70. }
  71. _running = true;
  72. session_->start();
  73. return AE_NO;
  74. }
  75. int record_desktop_wgc::pause()
  76. {
  77. _paused = true;
  78. if (session_)
  79. session_->pause();
  80. return AE_NO;
  81. }
  82. int record_desktop_wgc::resume()
  83. {
  84. _paused = false;
  85. if (session_)
  86. session_->resume();
  87. return AE_NO;
  88. }
  89. int record_desktop_wgc::stop()
  90. {
  91. _running = false;
  92. if (session_)
  93. session_->stop();
  94. return AE_NO;
  95. }
  96. void record_desktop_wgc::on_frame(const wgc_session::wgc_session_frame &frame)
  97. {
  98. al_debug("wgc on frame");
  99. AVFrame *av_frame = av_frame_alloc();
  100. // 使用相对时间戳,与muxer的_base_time保持一致
  101. av_frame->pts = av_gettime_relative();
  102. av_frame->pkt_dts = av_frame->pts;
  103. // av_frame->pkt_pts = av_frame->pts;
  104. av_frame->width = frame.width;
  105. av_frame->height = frame.height;
  106. av_frame->format = AV_PIX_FMT_BGRA;
  107. av_frame->pict_type = AV_PICTURE_TYPE_NONE;
  108. av_frame->pkt_size = frame.width * frame.height * 4;
  109. av_image_fill_arrays(av_frame->data,
  110. av_frame->linesize,
  111. frame.data,
  112. AV_PIX_FMT_BGRA,
  113. frame.width,
  114. frame.height,
  115. 1);
  116. if (_on_data)
  117. _on_data(av_frame);
  118. av_frame_free(&av_frame);
  119. }
  120. void record_desktop_wgc::clean_up()
  121. {
  122. _inited = false;
  123. if (session_)
  124. session_->release();
  125. session_ = nullptr;
  126. }
  127. } // namespace am