This commit is contained in:
cxh 2025-11-25 09:15:52 +08:00
parent 53f496ca7e
commit 300c98e426

View File

@ -197,7 +197,6 @@ 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);
@ -212,43 +211,18 @@ void RTSPManager::on_media_created(GstRTSPMediaFactory *, GstRTSPMedia *media, g
(GClosureNotify)g_free,
(GConnectFlags)0);
// 获取底层 pipeline
GstElement *pipeline = gst_rtsp_media_get_element(media);
if (!pipeline)
{
LOG_ERROR(std::string("[RTSP] Pipeline is NULL for camera: ") + cam_name);
LOG_ERROR("[RTSP] Pipeline NULL for camera: " + std::string(cam_name));
return;
}
// ★★★ 关键:拿到 encoder 元素,强制打一发 IDR保证 VLC 第一次连接就能拿到关键帧
GstElement *enc = gst_bin_get_by_name(GST_BIN(pipeline), "enc");
if (enc)
{
LOG_INFO(std::string("[RTSP] Forcing IDR for camera: ") + cam_name);
// 这里用和 launch 里同名的属性,确保 Rockchip mpph264enc 能识别
g_object_set(enc, "option-force-idr", TRUE, NULL);
// 如果你想更狠一点,也可以顺便再 set 一次 idr-interval
// g_object_set(enc, "option-idr-interval", cam.fps, NULL); // 这里需要你把 fps 传进来才行
LOG_INFO("[RTSP] Forcing pipeline reset to generate IDR");
gst_object_unref(enc);
}
else
{
LOG_WARN(std::string("[RTSP] Encoder 'enc' not found in pipeline for camera: ") + cam_name);
}
gst_element_set_state(pipeline, GST_STATE_READY);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
// 强制 pipeline 进入 PLAYING避免停在 PAUSED/preroll
GstStateChangeReturn ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
LOG_ERROR(std::string("[RTSP] Failed to set pipeline PLAYING for camera: ") + cam_name);
}
else
{
LOG_INFO(std::string("[RTSP] Force pipeline PLAYING for camera: ") + cam_name);
}
// gst_rtsp_media_get_element() 返回的是加过 ref 的对象,需要 unref 一次
gst_object_unref(pipeline);
}