1
This commit is contained in:
parent
9fc4858e52
commit
fe5d2ca701
@ -94,30 +94,37 @@ GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
|
||||
",height=" + std::to_string(h) +
|
||||
",framerate=" + std::to_string(cam.fps) + "/1";
|
||||
|
||||
// 修正后的管线:加 videoconvert,删掉 encoder 不支持的属性
|
||||
// 关键:tee 一路给 RTSP,一路给 fakesink,保持 v4l2src / mpph264enc 永远在跑
|
||||
//
|
||||
// 结构:
|
||||
// v4l2src -> caps -> tee name=t
|
||||
// tee src0: t. -> queue -> mpph264enc -> h264parse -> rtph264pay (给 RTSP)
|
||||
// tee src1: t. -> queue -> fakesink (假消费者,让 DMA 持续 dequeue)
|
||||
std::string launch_str =
|
||||
"( v4l2src device=" + cam.device +
|
||||
" io-mode=2 is-live=true do-timestamp=true"
|
||||
" ! " +
|
||||
caps +
|
||||
" ! videoconvert"
|
||||
" ! tee name=t "
|
||||
" ! queue leaky=downstream max-size-time=0 max-size-bytes=0 max-size-buffers=0"
|
||||
" ! mpph264enc name=enc rc-mode=cbr bps=" +
|
||||
std::to_string(cam.bitrate) +
|
||||
" gop=" + std::to_string(cam.fps) +
|
||||
" header-mode=1"
|
||||
" ! h264parse"
|
||||
" ! rtph264pay name=pay0 pt=96 config-interval=1 )";
|
||||
" ! rtph264pay name=pay0 pt=96 config-interval=1 "
|
||||
" t. ! queue max-size-buffers=1 max-size-time=0 max-size-bytes=0"
|
||||
" ! fakesink sync=false )";
|
||||
|
||||
LOG_INFO("[RTSP] Launch for " + cam.name + ": " + launch_str);
|
||||
|
||||
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();
|
||||
gst_rtsp_media_factory_set_launch(factory, launch_str.c_str());
|
||||
|
||||
// ★ 必改:先关掉 shared,避免 VLC 拉流不启动 pipeline
|
||||
// 先保持每个客户端独立 pipeline,逻辑简单可靠
|
||||
gst_rtsp_media_factory_set_shared(factory, FALSE);
|
||||
|
||||
// 客户端断开时不 reset pipeline(我们手动处理)
|
||||
// 客户端断开时不要乱 reset,交给我们自己处理 / 或干脆不动
|
||||
gst_rtsp_media_factory_set_suspend_mode(factory, GST_RTSP_SUSPEND_MODE_NONE);
|
||||
|
||||
g_signal_connect_data(factory,
|
||||
@ -189,6 +196,7 @@ void RTSPManager::on_media_created(GstRTSPMediaFactory *, GstRTSPMedia *media, g
|
||||
|
||||
LOG_INFO(std::string("[RTSP] media-configure for camera: ") + cam_name);
|
||||
|
||||
// 保存 media,用于之后 unmount 时统一管理
|
||||
g_object_ref(media);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(media_map_mutex);
|
||||
@ -203,20 +211,8 @@ void RTSPManager::on_media_created(GstRTSPMediaFactory *, GstRTSPMedia *media, g
|
||||
(GClosureNotify)g_free,
|
||||
(GConnectFlags)0);
|
||||
|
||||
GstElement *pipeline = gst_rtsp_media_get_element(media);
|
||||
if (!pipeline)
|
||||
{
|
||||
LOG_ERROR("[RTSP] Pipeline NULL for camera: " + std::string(cam_name));
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO("[RTSP] Forcing pipeline reset (READY → PLAYING) to generate IDR");
|
||||
|
||||
// 关键:强制重新启动 pipeline,让 v4l2src/mpph264enc 正式启动
|
||||
gst_element_set_state(pipeline, GST_STATE_READY);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
gst_object_unref(pipeline);
|
||||
// 不再手动改 pipeline 状态,交给 gst-rtsp-server 自己管理
|
||||
// 如果后面发现确实有卡在 PAUSED 的情况,再在这里加逻辑
|
||||
}
|
||||
|
||||
void RTSPManager::on_media_unprepared(GstRTSPMedia *media, gpointer user_data)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user