GstRtspServer::RTSPContext::response_ usually fails with an assertion
When you program GStreamer's RTSP server, GstRtspServer::RTSPContext
is passed to many methods that process various requests. For example, I can have a method that processes SET_PARAMETER
request:
namespace GstRtspServer = gi::repository::GstRtspServer;
namespace GstRtsp = gi::repository::GstRtsp;
GstRtsp::RTSPResult MyRTSPClient::params_set_(GstRtspServer::RTSPContext ctx) noexcept {
}
Inside this function, what you usually do after processing the request, you prepare a response. However, in the function above, ctx.response_()
will unexpectedly fail with an assertion:
GstRtsp::RTSPResult MyRTSPClient::params_set_(GstRtspServer::RTSPContext ctx) noexcept {
// ...
// This will print "GStreamer-RTSP-CRITICAL **: 09:59:53.048: key_value_foreach: assertion 'array != NULL' failed"
ctx.response_().init_response(
GstRtsp::RTSPStatusCode::OK_
, GstRtsp::rtsp_status_as_text(GstRtsp::RTSPStatusCode::OK_)
, ctx.request_());
return GstRtsp::RTSPResult::OK_;
}
It happens during the call of gi::wrap
here:
GstRtsp::RTSPMessage base::RTSPContextBase::response_ () const noexcept
{
typedef ::GstRTSPMessage* (*call_wrap_t) (const ::GstRTSPContext* obj);
call_wrap_t call_wrap_v = (call_wrap_t) _field_response_get;
auto _temp_ret = call_wrap_v ((const ::GstRTSPContext*) (gobj_()));
return gi::wrap (_temp_ret, gi::transfer_none, gi::direction_out);
}
The aforementioned gi::wrap
calls g_boxed_copy
, which calls gst_rtsp_message_copy
, which issues an assertion here:
key_value_foreach (msg->hdr_fields, (GFunc) key_value_append, cp->hdr_fields);
An assertion technically is not a big deal, the bigger issue is, to one's utter surprise, a field accessor ctx.response_()
returns a copy of the field. This makes this code useless:
ctx.response_().init_response(
GstRtsp::RTSPStatusCode::OK_
, GstRtsp::rtsp_status_as_text(GstRtsp::RTSPStatusCode::OK_)
, ctx.request_());
It won't change anything inside ctx
, it changes a temporary copy.