恢复管线
This commit is contained in:
parent
23d3d82b55
commit
430e44d9fa
@ -63,109 +63,36 @@ void RTMPManager::init()
|
|||||||
std::string RTMPManager::make_key(const std::string& name) { return name + "_main"; }
|
std::string RTMPManager::make_key(const std::string& name) { return name + "_main"; }
|
||||||
|
|
||||||
// ========== 创建推流管线 ==========
|
// ========== 创建推流管线 ==========
|
||||||
// GstElement* RTMPManager::create_pipeline(const Camera& cam)
|
|
||||||
// {
|
|
||||||
// const int width = cam.width;
|
|
||||||
// const int height = cam.height;
|
|
||||||
// const int fps = cam.fps;
|
|
||||||
// const int bitrate = cam.bitrate;
|
|
||||||
|
|
||||||
// // MediaMTX 中的 stream key
|
|
||||||
// const std::string stream_name = cam.name;
|
|
||||||
|
|
||||||
// // RTMP 推送到 MediaMTX
|
|
||||||
// // mediamtx.yml 中 paths 会自动创建
|
|
||||||
// const std::string rtmp_url = "rtmp://127.0.0.1:1935/" + stream_name;
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// * Pipeline 说明:
|
|
||||||
// * v4l2src -> mpph264enc -> h264parse -> flvmux -> rtmpsink
|
|
||||||
// *
|
|
||||||
// * - 不使用 tee(降低死锁概率)
|
|
||||||
// * - 不引入音频(MediaMTX 不强制要求)
|
|
||||||
// * - 纯视频、纯 RTMP、纯 TCP
|
|
||||||
// */
|
|
||||||
// std::string pipeline_str = "v4l2src name=src device=" + cam.device +
|
|
||||||
// " ! video/x-raw,format=NV12,width=" + std::to_string(width) +
|
|
||||||
// ",height=" + std::to_string(height) + ",framerate=" + std::to_string(fps) +
|
|
||||||
// "/1 "
|
|
||||||
// " ! mpph264enc bps=" +
|
|
||||||
// std::to_string(bitrate) + " gop=" + std::to_string(fps) +
|
|
||||||
// " rc-mode=cbr "
|
|
||||||
// " ! h264parse name=parse "
|
|
||||||
// " ! flvmux streamable=true "
|
|
||||||
// " ! rtmpsink location=\"" +
|
|
||||||
// rtmp_url +
|
|
||||||
// "\" "
|
|
||||||
// " sync=false async=false";
|
|
||||||
|
|
||||||
// GError* error = nullptr;
|
|
||||||
// GstElement* pipeline = gst_parse_launch(pipeline_str.c_str(), &error);
|
|
||||||
// if (error)
|
|
||||||
// {
|
|
||||||
// LOG_ERROR(std::string("[RTMP] Pipeline creation failed: ") + error->message);
|
|
||||||
// g_error_free(error);
|
|
||||||
// return nullptr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return pipeline;
|
|
||||||
// }
|
|
||||||
|
|
||||||
GstElement* RTMPManager::create_pipeline(const Camera& cam)
|
GstElement* RTMPManager::create_pipeline(const Camera& cam)
|
||||||
{
|
{
|
||||||
const int out_width = cam.width; // 推流分辨率(如 1280 / 960 / 720)
|
const int width = cam.width;
|
||||||
const int out_height = cam.height;
|
const int height = cam.height;
|
||||||
const int fps = cam.fps;
|
const int fps = cam.fps;
|
||||||
const int bitrate = cam.bitrate;
|
const int bitrate = cam.bitrate;
|
||||||
|
|
||||||
// MediaMTX stream key
|
// MediaMTX 中的 stream key
|
||||||
const std::string stream_name = cam.name;
|
const std::string stream_name = cam.name;
|
||||||
|
|
||||||
|
// RTMP 推送到 MediaMTX
|
||||||
|
// mediamtx.yml 中 paths 会自动创建
|
||||||
const std::string rtmp_url = "rtmp://127.0.0.1:1935/" + stream_name;
|
const std::string rtmp_url = "rtmp://127.0.0.1:1935/" + stream_name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A 方案 Pipeline:
|
* Pipeline 说明:
|
||||||
|
* v4l2src -> mpph264enc -> h264parse -> flvmux -> rtmpsink
|
||||||
*
|
*
|
||||||
* v4l2src (原生 1280x960)
|
* - 不使用 tee(降低死锁概率)
|
||||||
* -> videoscale + caps(编码前缩放)
|
* - 不引入音频(MediaMTX 不强制要求)
|
||||||
* -> queue(低延迟)
|
* - 纯视频、纯 RTMP、纯 TCP
|
||||||
* -> mpph264enc(CBR)
|
|
||||||
* -> h264parse
|
|
||||||
* -> flvmux
|
|
||||||
* -> rtmpsink
|
|
||||||
*/
|
*/
|
||||||
std::string pipeline_str = "v4l2src name=src device=" + cam.device +
|
std::string pipeline_str = "v4l2src name=src device=" + cam.device +
|
||||||
" io-mode=dmabuf "
|
" ! video/x-raw,format=NV12,width=" + std::to_string(width) +
|
||||||
|
",height=" + std::to_string(height) + ",framerate=" + std::to_string(fps) +
|
||||||
// ⭐ 相机真实输出:原生 1280x960
|
|
||||||
"! video/x-raw,format=NV12,"
|
|
||||||
"width=1280,height=960,"
|
|
||||||
"framerate=" +
|
|
||||||
std::to_string(fps) +
|
|
||||||
"/1 "
|
"/1 "
|
||||||
|
" ! mpph264enc bps=" +
|
||||||
// ⭐ 编码前缩放(关键)
|
std::to_string(bitrate) + " gop=" + std::to_string(fps) +
|
||||||
"! videoscale "
|
|
||||||
"! video/x-raw,"
|
|
||||||
"width=" +
|
|
||||||
std::to_string(out_width) + ",height=" + std::to_string(out_height) +
|
|
||||||
" "
|
|
||||||
|
|
||||||
// ⭐ 低延迟队列,防止下游阻塞反噬 v4l2
|
|
||||||
"! queue max-size-buffers=2 max-size-time=0 leaky=downstream "
|
|
||||||
|
|
||||||
// ⭐ 硬件编码,SIM 卡友好
|
|
||||||
"! mpph264enc "
|
|
||||||
" rc-mode=cbr "
|
" rc-mode=cbr "
|
||||||
"bps=" +
|
" ! h264parse name=parse "
|
||||||
std::to_string(bitrate) +
|
|
||||||
" "
|
|
||||||
"gop=" +
|
|
||||||
std::to_string(fps) +
|
|
||||||
" "
|
|
||||||
"header-mode=each-idr "
|
|
||||||
"profile=baseline "
|
|
||||||
|
|
||||||
"! h264parse config-interval=1 "
|
|
||||||
" ! flvmux streamable=true "
|
" ! flvmux streamable=true "
|
||||||
" ! rtmpsink location=\"" +
|
" ! rtmpsink location=\"" +
|
||||||
rtmp_url +
|
rtmp_url +
|
||||||
@ -184,6 +111,79 @@ GstElement* RTMPManager::create_pipeline(const Camera& cam)
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GstElement* RTMPManager::create_pipeline(const Camera& cam)
|
||||||
|
// {
|
||||||
|
// const int out_width = cam.width; // 推流分辨率(如 1280 / 960 / 720)
|
||||||
|
// const int out_height = cam.height;
|
||||||
|
// const int fps = cam.fps;
|
||||||
|
// const int bitrate = cam.bitrate;
|
||||||
|
|
||||||
|
// // MediaMTX stream key
|
||||||
|
// const std::string stream_name = cam.name;
|
||||||
|
// const std::string rtmp_url = "rtmp://127.0.0.1:1935/" + stream_name;
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// * A 方案 Pipeline:
|
||||||
|
// *
|
||||||
|
// * v4l2src (原生 1280x960)
|
||||||
|
// * -> videoscale + caps(编码前缩放)
|
||||||
|
// * -> queue(低延迟)
|
||||||
|
// * -> mpph264enc(CBR)
|
||||||
|
// * -> h264parse
|
||||||
|
// * -> flvmux
|
||||||
|
// * -> rtmpsink
|
||||||
|
// */
|
||||||
|
// std::string pipeline_str = "v4l2src name=src device=" + cam.device +
|
||||||
|
// " io-mode=dmabuf "
|
||||||
|
|
||||||
|
// // ⭐ 相机真实输出:原生 1280x960
|
||||||
|
// "! video/x-raw,format=NV12,"
|
||||||
|
// "width=1280,height=960,"
|
||||||
|
// "framerate=" +
|
||||||
|
// std::to_string(fps) +
|
||||||
|
// "/1 "
|
||||||
|
|
||||||
|
// // ⭐ 编码前缩放(关键)
|
||||||
|
// "! videoscale "
|
||||||
|
// "! video/x-raw,"
|
||||||
|
// "width=" +
|
||||||
|
// std::to_string(out_width) + ",height=" + std::to_string(out_height) +
|
||||||
|
// " "
|
||||||
|
|
||||||
|
// // ⭐ 低延迟队列,防止下游阻塞反噬 v4l2
|
||||||
|
// "! queue max-size-buffers=2 max-size-time=0 leaky=downstream "
|
||||||
|
|
||||||
|
// // ⭐ 硬件编码,SIM 卡友好
|
||||||
|
// "! mpph264enc "
|
||||||
|
// "rc-mode=cbr "
|
||||||
|
// "bps=" +
|
||||||
|
// std::to_string(bitrate) +
|
||||||
|
// " "
|
||||||
|
// "gop=" +
|
||||||
|
// std::to_string(fps) +
|
||||||
|
// " "
|
||||||
|
// "header-mode=each-idr "
|
||||||
|
// "profile=baseline "
|
||||||
|
|
||||||
|
// "! h264parse config-interval=1 "
|
||||||
|
// "! flvmux streamable=true "
|
||||||
|
// "! rtmpsink location=\"" +
|
||||||
|
// rtmp_url +
|
||||||
|
// "\" "
|
||||||
|
// "sync=false async=false";
|
||||||
|
|
||||||
|
// GError* error = nullptr;
|
||||||
|
// GstElement* pipeline = gst_parse_launch(pipeline_str.c_str(), &error);
|
||||||
|
// if (error)
|
||||||
|
// {
|
||||||
|
// LOG_ERROR(std::string("[RTMP] Pipeline creation failed: ") + error->message);
|
||||||
|
// g_error_free(error);
|
||||||
|
// return nullptr;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return pipeline;
|
||||||
|
// }
|
||||||
|
|
||||||
// ========== 主推流循环 ==========
|
// ========== 主推流循环 ==========
|
||||||
void RTMPManager::stream_loop(Camera cam, StreamContext* ctx)
|
void RTMPManager::stream_loop(Camera cam, StreamContext* ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user