1
This commit is contained in:
parent
300c98e426
commit
9fc4858e52
@ -35,7 +35,7 @@ bool set_v4l2_format(const std::string &dev, int width, int height)
|
|||||||
memset(&fmt, 0, sizeof(fmt));
|
memset(&fmt, 0, sizeof(fmt));
|
||||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||||
|
|
||||||
// 先读当前格式,避免每次都硬 S_FMT
|
// 读格式,若相同则略过
|
||||||
if (ioctl(fd, VIDIOC_G_FMT, &fmt) == 0)
|
if (ioctl(fd, VIDIOC_G_FMT, &fmt) == 0)
|
||||||
{
|
{
|
||||||
bool match = true;
|
bool match = true;
|
||||||
@ -69,7 +69,6 @@ bool set_v4l2_format(const std::string &dev, int width, int height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("[RTSP] Set V4L2 format to NV12 " + std::to_string(width) + "x" + std::to_string(height) + " for " + dev);
|
LOG_INFO("[RTSP] Set V4L2 format to NV12 " + std::to_string(width) + "x" + std::to_string(height) + " for " + dev);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -95,24 +94,17 @@ GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
|
|||||||
",height=" + std::to_string(h) +
|
",height=" + std::to_string(h) +
|
||||||
",framerate=" + std::to_string(cam.fps) + "/1";
|
",framerate=" + std::to_string(cam.fps) + "/1";
|
||||||
|
|
||||||
// 注意几点:
|
// 修正后的管线:加 videoconvert,删掉 encoder 不支持的属性
|
||||||
// 1) 给 mpph264enc 起一个名字 name=enc,方便后面在 on_media_created 里拿到
|
|
||||||
// 2) option-force-idr / option-idr-interval 依然在这里设置一遍,保证周期 IDR
|
|
||||||
// 3) config-interval=1 一定要写在 rtph264pay 上
|
|
||||||
std::string launch_str =
|
std::string launch_str =
|
||||||
"( v4l2src device=" + cam.device +
|
"( v4l2src device=" + cam.device +
|
||||||
" io-mode=2 is-live=true do-timestamp=true"
|
" io-mode=2 is-live=true do-timestamp=true"
|
||||||
" ! " +
|
" ! " +
|
||||||
caps +
|
caps +
|
||||||
|
" ! videoconvert"
|
||||||
" ! queue leaky=downstream max-size-time=0 max-size-bytes=0 max-size-buffers=0"
|
" ! queue leaky=downstream max-size-time=0 max-size-bytes=0 max-size-buffers=0"
|
||||||
" ! mpph264enc name=enc"
|
" ! mpph264enc name=enc rc-mode=cbr bps=" +
|
||||||
" rc-mode=cbr"
|
|
||||||
" bps=" +
|
|
||||||
std::to_string(cam.bitrate) +
|
std::to_string(cam.bitrate) +
|
||||||
" gop=" + std::to_string(cam.fps) +
|
" gop=" + std::to_string(cam.fps) +
|
||||||
" option-force-idr=true"
|
|
||||||
" option-idr-interval=" +
|
|
||||||
std::to_string(cam.fps) +
|
|
||||||
" header-mode=1"
|
" header-mode=1"
|
||||||
" ! h264parse"
|
" ! h264parse"
|
||||||
" ! rtph264pay name=pay0 pt=96 config-interval=1 )";
|
" ! rtph264pay name=pay0 pt=96 config-interval=1 )";
|
||||||
@ -122,10 +114,10 @@ GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
|
|||||||
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();
|
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();
|
||||||
gst_rtsp_media_factory_set_launch(factory, launch_str.c_str());
|
gst_rtsp_media_factory_set_launch(factory, launch_str.c_str());
|
||||||
|
|
||||||
// 先保持 shared=TRUE,节省资源
|
// ★ 必改:先关掉 shared,避免 VLC 拉流不启动 pipeline
|
||||||
gst_rtsp_media_factory_set_shared(factory, TRUE);
|
gst_rtsp_media_factory_set_shared(factory, FALSE);
|
||||||
|
|
||||||
// 客户端断开时不重置 pipeline,防止反复 s_stream(0/1)
|
// 客户端断开时不 reset pipeline(我们手动处理)
|
||||||
gst_rtsp_media_factory_set_suspend_mode(factory, GST_RTSP_SUSPEND_MODE_NONE);
|
gst_rtsp_media_factory_set_suspend_mode(factory, GST_RTSP_SUSPEND_MODE_NONE);
|
||||||
|
|
||||||
g_signal_connect_data(factory,
|
g_signal_connect_data(factory,
|
||||||
@ -218,8 +210,9 @@ void RTSPManager::on_media_created(GstRTSPMediaFactory *, GstRTSPMedia *media, g
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("[RTSP] Forcing pipeline reset to generate IDR");
|
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_READY);
|
||||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user