streamNode.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "nodes/base/base.hpp"
  2. #include "nodes/stream/streamNode.hpp"
  3. namespace Node
  4. {
  5. void StreamNode::work()
  6. {
  7. printf("StreamNode %s\n", name_.c_str());
  8. printf("stram url: %s\n", stream_url_.c_str());
  9. printf("Decode type: %d\n", static_cast<int>(decode_type_));
  10. if (decode_type_ == DecodeType::CPU)
  11. {
  12. work_cpu();
  13. }
  14. else
  15. {
  16. work_gpu();
  17. }
  18. }
  19. void StreamNode::work_cpu()
  20. {
  21. while (running_)
  22. {
  23. cv::Mat frame;
  24. cap_->read(frame);
  25. frame_count_++;
  26. if (frame_count_ % skip_frame_ != 0)
  27. {
  28. // printf("Skip frame %d\n", frame_count_);
  29. continue;
  30. }
  31. if (frame.empty())
  32. {
  33. std::cerr << "Error: cannot read frame" << std::endl;
  34. break;
  35. }
  36. auto metaData = std::make_shared<meta::MetaData>();
  37. metaData->image = frame;
  38. metaData->from = name_;
  39. for (auto& output_buffer : output_buffers_)
  40. {
  41. output_buffer.second->push(metaData);
  42. // printf("Node %s push data to %s\n", name_.c_str(), output_buffer.first.c_str());
  43. }
  44. }
  45. }
  46. void StreamNode::work_gpu()
  47. {
  48. uint8_t* packet_data = nullptr;
  49. int packet_size = 0;
  50. int64_t pts = 0;
  51. demuxer_->get_extra_data(&packet_data, &packet_size);
  52. decoder_->decode(packet_data, packet_size);
  53. printf("packet_size = %d\n", packet_size);
  54. unsigned int frame_index = 0;
  55. while(running_)
  56. {
  57. demuxer_->demux(&packet_data, &packet_size, &pts);
  58. if (packet_size <= 0 || !running_)
  59. {
  60. break;
  61. }
  62. int ndecoded_frame = decoder_->decode(packet_data, packet_size, pts);
  63. for(int i = 0; i < ndecoded_frame; ++i){
  64. /* 因为decoder获取的frame内存,是YUV-NV12格式的。储存内存大小是 [height * 1.5] * width byte
  65. 因此构造一个height * 1.5, width 大小的空间
  66. 然后由opencv函数,把YUV-NV12转换到BGR,转换后的image则是正常的height, width, CV_8UC3
  67. */
  68. cv::Mat frame(decoder_->get_height(), decoder_->get_width(), CV_8UC3, decoder_->get_frame(&pts, &frame_index));
  69. //cv::cvtColor(image, image, cv::COLOR_YUV2BGR_NV12);
  70. frame_index = frame_index + 1;
  71. // INFO("write imgs/img_%05d.jpg %dx%d", frame_index, decoder->get_width(), decoder->get_height());
  72. frame_count_++;
  73. if (frame_count_ % skip_frame_ != 0)
  74. {
  75. // printf("Skip frame %d\n", frame_count_);
  76. continue;
  77. }
  78. auto metaData = std::make_shared<meta::MetaData>();
  79. metaData->image = frame;
  80. metaData->from = name_;
  81. for (auto& output_buffer : output_buffers_)
  82. {
  83. output_buffer.second->push(metaData);
  84. // printf("Node %s push data to %s\n", name_.c_str(), output_buffer.first.c_str());
  85. }
  86. }
  87. };
  88. printf("C++ Demo: %d frames\n", frame_index);
  89. }
  90. } // namespace Node