video_recorder.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "video_recorder.h"
  2. #include "avrecorder/capturer/video/VideoCaptureManager.h"
  3. #include <Windows.h>
  4. #include <capturer/finder.h>
  5. using namespace avrecorder::video;
  6. bool VideoRecorder::Open(HWND srcHwnd, Encoder<MediaType::VIDEO>::Param& param, CaptureMethod method) {
  7. CaptureTarget target;
  8. target.type = CaptureTargetType::Window;
  9. target.hwnd = srcHwnd;
  10. RECT clientRect;
  11. if (!GetClientRect(srcHwnd, &clientRect)) return false;
  12. int width = clientRect.right - clientRect.left;
  13. int height = clientRect.bottom - clientRect.top;
  14. _capturer.open(target, method, width, height);
  15. return _Open(param);
  16. }
  17. bool VideoRecorder::Open(int monitorIdx, Encoder<MediaType::VIDEO>::Param& param, CaptureMethod method) {
  18. CaptureTarget target;
  19. target.type = CaptureTargetType::Monitor;
  20. target.monitorIdx = monitorIdx;
  21. auto monitorInfo = MonitorFinder::GetList()[monitorIdx];
  22. RECT rect = monitorInfo.rect;
  23. int width = rect.right - rect.left;
  24. int height = rect.bottom - rect.top;
  25. _capturer.open(target, method, width, height);
  26. return _Open(param);
  27. }
  28. bool VideoRecorder::_Open(Encoder<MediaType::VIDEO>::Param& param)
  29. {
  30. __CheckBool(_encodeFrame = Frame<MediaType::VIDEO>::Alloc(AV_PIX_FMT_NV12,
  31. _capturer.getFrame() ? _capturer.getFrame()->width : param.width,
  32. _capturer.getFrame() ? _capturer.getFrame()->height : param.height));
  33. {
  34. std::lock_guard<std::mutex> renderLk(_renderMtx);
  35. __CheckBool(_renderFrame = Frame<MediaType::VIDEO>::Alloc(AV_PIX_FMT_NV12,
  36. _capturer.getFrame() ? _capturer.getFrame()->width : param.width,
  37. _capturer.getFrame() ? _capturer.getFrame()->height : param.height));
  38. }
  39. // 捕获定时器和帧获取逻辑
  40. _captureTimer.Start(param.fps, [this] {
  41. auto srcFrame = _capturer.getFrame();
  42. if (srcFrame != nullptr) {
  43. std::lock_guard<std::mutex> muxLk(__mtx);
  44. if (srcFrame->format != _encodeFrame->format) {
  45. std::lock_guard<std::mutex> renderLk(_renderMtx);
  46. Free(_encodeFrame, [this] { av_frame_free(&_encodeFrame); });
  47. __CheckNo(
  48. _encodeFrame = Frame<MediaType::VIDEO>::Alloc(AVPixelFormat(srcFrame->format),
  49. srcFrame->width,
  50. srcFrame->height));
  51. }
  52. av_frame_copy(_encodeFrame, srcFrame);
  53. }
  54. });
  55. param.width = _capturer.getFrame() ? _capturer.getFrame()->width : param.width;
  56. param.height = _capturer.getFrame() ? _capturer.getFrame()->height : param.height;
  57. _param = param;
  58. return true;
  59. }
  60. AVFrame* VideoRecorder::GetRenderFrame()
  61. {
  62. std::lock_guard<std::mutex> renderLk(_renderMtx);
  63. if (_encodeFrame == nullptr) {
  64. return nullptr;
  65. }
  66. if (_renderFrame->format != _encodeFrame->format) {
  67. Free(_renderFrame, [this] { av_frame_free(&_renderFrame); });
  68. _renderFrame = Frame<MediaType::VIDEO>::Alloc(AVPixelFormat(_encodeFrame->format), _encodeFrame->width, _encodeFrame->height);
  69. }
  70. av_frame_copy(_renderFrame, _encodeFrame);
  71. return _renderFrame;
  72. }
  73. bool VideoRecorder::LoadMuxer(AvMuxer& muxer)
  74. {
  75. _muxer = &muxer;
  76. __CheckBool((_streamIndex = muxer.AddVideoStream(_param)) != -1);
  77. return true;
  78. }
  79. bool VideoRecorder::StartRecord()
  80. {
  81. _totalPts = 0;
  82. _lossPts = 0;
  83. _lossHistory.clear();
  84. _muxTimer.Start(_param.fps, [this] {
  85. ++_totalPts;
  86. bool loss = !_muxer->Write(_encodeFrame, _streamIndex);
  87. if (loss) ++_lossPts;
  88. _lossHistory.push_back(loss);
  89. if (_lossHistory.size() > LOSS_WINDOW) _lossHistory.pop_front();
  90. });
  91. _isRecord = true;
  92. return true;
  93. }
  94. void VideoRecorder::StopRecord()
  95. {
  96. _isRecord = false;
  97. _muxTimer.Stop();
  98. }
  99. double VideoRecorder::GetLossRate()
  100. {
  101. if (_lossHistory.size() < LOSS_WINDOW) return -1.0; // 统计中
  102. int lossCount = std::count(_lossHistory.begin(), _lossHistory.end(), true);
  103. return double(lossCount) / _lossHistory.size();
  104. }
  105. void VideoRecorder::Close()
  106. {
  107. StopRecord();
  108. _captureTimer.Stop();
  109. _capturer.close();
  110. Free(_encodeFrame, [this] { av_frame_free(&_encodeFrame); });
  111. Free(_renderFrame, [this] { av_frame_free(&_renderFrame); });
  112. }