#include "VideoInput.h" #include "BoostLog.h" #include "rw_mpp_api.h" #include VideoInput::VideoInput(int32_t width, int32_t height) : m_width(width), m_height(height) { } VideoInput::~VideoInput() { if (isStarted()) { stop(); } } bool VideoInput::start() { if (!m_exit) { LOG(warning) << "camera already started..."; return false; } S_video_cfg vcfg; vcfg.sns_w = -1; vcfg.sns_h = -1; vcfg.img_w = m_width; vcfg.img_h = m_height; m_vid = 0; m_exit = false; int status = rw_mpp__video_start(m_vid, &vcfg); if (status != 0) { LOG(error) << "rw_mpp__video_start() failed, status: " << status; m_vid = -1; } else { m_thread = std::thread(&VideoInput::run, this); } return status == 0; } void VideoInput::stop() { m_exit = true; if (m_encodeThread.joinable()) { m_encodeThread.join(); } if (m_thread.joinable()) { m_thread.join(); } rw_mpp__video_stop(m_vid); rw_mpp__venc_stop(m_encodeChannel); m_vid = -1; m_encodeChannel = -1; } bool VideoInput::isStarted() const { return !m_exit; } bool VideoInput::startEncode() { m_encodeChannel = 0; S_venc_config config; memset(&config, 0, sizeof(S_venc_config)); config.codec = CODEC_H264; config.profile = H264_main; config.raw_max_width = 2960; config.raw_max_height = 1664; config.width = 1280; config.height = 720; config.gop = 15; config.framerate = 15; config.rc_type = RC_VBR; S_venc_rc_vbr vbr; memset(&vbr, 0, sizeof(S_venc_rc_vbr)); vbr.max_bitrate = 1024; vbr.stats_time = 1; config.rc_param = &vbr; int status = rw_mpp__venc_start(m_encodeChannel, &config, -1); if (status != 0) { LOG(error) << "rw_mpp__venc_start() failed, status: " << status; } else { m_encodeThread = std::thread(&VideoInput::encodeRun, this); } return status == 0; } void VideoInput::setPacketHandler(const PacketHandler &hanlder) { m_handler = hanlder; } void VideoInput::run() { using namespace std::chrono_literals; S_mpp_img img; while (!m_exit) { int status = rw_mpp__video_recv(m_vid, &img, 2000); if (status != 0) { LOG(error) << "rw_mpp__video_recv() failed, status: " << status; std::this_thread::sleep_for(500ms); continue; } // LOG(info) << "camera frame size: " << img.width << "x" << img.height; if (m_encodeChannel >= 0) { rw_mpp__venc_send(m_encodeChannel, &img); } status = rw_mpp__video_free(m_vid, &img); if (status != 0) { LOG(error) << "rw_mpp__video_free() failed, status: " << status; } } } void VideoInput::encodeRun() { using namespace std::chrono_literals; S_mpp_venc_frame frame; while (!m_exit) { int status = rw_mpp__venc_recv(m_encodeChannel, &frame, 1000); if (status != 0) { std::this_thread::sleep_for(500ms); LOG(error) << "rw_mpp__venc_recv() failed, status: " << status; continue; } LOG(info) << "encode frame data size: " << frame.len << ", is key frame: " << frame.is_key_frame; if (m_handler) { m_handler(frame.data, frame.len); } status = rw_mpp__venc_free(m_encodeChannel, &frame); if (status != 0) { LOG(error) << "rw_mpp__venc_free() failed, status: " << status; } } }