Implement rtsp pusher.
This commit is contained in:
128
Main/VideoInput.cpp
Normal file
128
Main/VideoInput.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "VideoInput.h"
|
||||
#include "BoostLog.h"
|
||||
#include "rw_mpp_api.h"
|
||||
#include <chrono>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user