video_recorder.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "video_recorder.h"
  2. bool VideoRecorder::Open(HWND srcHwnd,
  3. Encoder<MediaType::VIDEO>::Param& param,
  4. VideoCapturer::Method type)
  5. {
  6. Close();
  7. __CheckBool(_capturer.Open(srcHwnd, type));
  8. __CheckBool(_Open(param));
  9. return true;
  10. }
  11. bool VideoRecorder::Open(int monitorIdx,
  12. Encoder<MediaType::VIDEO>::Param& param,
  13. VideoCapturer::Method type)
  14. {
  15. Close();
  16. __CheckBool(_capturer.Open(monitorIdx, type));
  17. __CheckBool(_Open(param));
  18. return true;
  19. }
  20. bool VideoRecorder::_Open(Encoder<MediaType::VIDEO>::Param& param)
  21. {
  22. __CheckBool(_encodeFrame = Frame<MediaType::VIDEO>::Alloc(AV_PIX_FMT_NV12,
  23. _capturer.GetWidth(),
  24. _capturer.GetHeight()));
  25. {
  26. std::lock_guard<std::mutex> renderLk(_renderMtx);
  27. __CheckBool(_renderFrame = Frame<MediaType::VIDEO>::Alloc(AV_PIX_FMT_NV12,
  28. _capturer.GetWidth(),
  29. _capturer.GetHeight()));
  30. }
  31. // 开始捕获画面
  32. _captureTimer.Start(param.fps, [this] {
  33. auto srcFrame = _capturer.GetFrame();
  34. if (srcFrame != nullptr) {
  35. std::lock_guard<std::mutex> muxLk(__mtx);
  36. if (srcFrame->format != _encodeFrame->format) {
  37. std::lock_guard<std::mutex> renderLk(_renderMtx);
  38. Free(_encodeFrame, [this] { av_frame_free(&_encodeFrame); });
  39. __CheckNo(
  40. _encodeFrame = Frame<MediaType::VIDEO>::Alloc(AVPixelFormat(srcFrame->format),
  41. _capturer.GetWidth(),
  42. _capturer.GetHeight()));
  43. }
  44. av_frame_copy(_encodeFrame, srcFrame);
  45. }
  46. });
  47. param.width = _capturer.GetWidth();
  48. param.height = _capturer.GetHeight();
  49. _param = param;
  50. return true;
  51. }
  52. AVFrame* VideoRecorder::GetRenderFrame()
  53. {
  54. std::lock_guard<std::mutex> renderLk(_renderMtx);
  55. if (_encodeFrame == nullptr) {
  56. return nullptr;
  57. }
  58. if (_renderFrame->format != _encodeFrame->format) {
  59. Free(_renderFrame, [this] { av_frame_free(&_renderFrame); });
  60. __CheckNullptr(
  61. _renderFrame = Frame<MediaType::VIDEO>::Alloc(AVPixelFormat(_encodeFrame->format),
  62. _capturer.GetWidth(),
  63. _capturer.GetHeight()));
  64. }
  65. av_frame_copy(_renderFrame, _encodeFrame);
  66. return _renderFrame;
  67. }
  68. bool VideoRecorder::LoadMuxer(AvMuxer& muxer)
  69. {
  70. _muxer = &muxer;
  71. __CheckBool((_streamIndex = muxer.AddVideoStream(_param)) != -1);
  72. return true;
  73. }
  74. bool VideoRecorder::StartRecord()
  75. {
  76. _totalPts = 0;
  77. _lossPts = 0;
  78. _muxTimer.Start(_param.fps, [this] {
  79. ++_totalPts;
  80. if (!_muxer->Write(_encodeFrame, _streamIndex)) {
  81. ++_lossPts;
  82. }
  83. });
  84. _isRecord = true;
  85. return true;
  86. }
  87. void VideoRecorder::StopRecord()
  88. {
  89. _isRecord = false;
  90. _muxTimer.Stop();
  91. }
  92. void VideoRecorder::Close()
  93. {
  94. StopRecord();
  95. _captureTimer.Stop();
  96. _capturer.Close();
  97. Free(_encodeFrame, [this] { av_frame_free(&_encodeFrame); });
  98. Free(_renderFrame, [this] { av_frame_free(&_renderFrame); });
  99. }