Skip to content

Commit ef5a746

Browse files
committed
[GStreamer][LibWebRTC] Keep size in decoder caps synchronized with encoded image dimensions
https://bugs.webkit.org/show_bug.cgi?id=277630 Reviewed by Xabier Rodriguez-Calvar. Update the caps of the decoder when the encoded image dimensions change. Those caps are also used by GStreamerVideoFrameLibWebRTC and later by LibWebRTCStatsCollector. Without this change, resolution in inbound-rtp statistics is never updated. Based on patch from Jacek Manko <jacek.manko@consult.red>. #1380 * Source/WebCore/platform/mediastream/libwebrtc/gstreamer/GStreamerVideoDecoderFactory.cpp: (WebCore::GStreamerWebRTCVideoDecoder::updateCapsFromImageSize): (WebCore::GStreamerWebRTCVideoDecoder::GetCapsForFrame): Deleted. Canonical link: https://commits.webkit.org/282115@main
1 parent 030740e commit ef5a746

1 file changed

Lines changed: 26 additions & 22 deletions

File tree

Source/WebCore/platform/mediastream/libwebrtc/gstreamer/GStreamerVideoDecoderFactory.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ class GStreamerWebRTCVideoDecoder : public webrtc::VideoDecoder {
102102
auto capsfilter = CreateFilter();
103103
auto decoder = makeElement("decodebin");
104104

105-
m_width = codecSettings.max_render_resolution().Width();
106-
m_height = codecSettings.max_render_resolution().Height();
105+
updateCapsFromImageSize(codecSettings.max_render_resolution().Width(), codecSettings.max_render_resolution().Height());
107106

108107
m_pipeline = makeElement("pipeline");
109108
connectSimpleBusMessageCallback(m_pipeline.get());
@@ -212,13 +211,22 @@ class GStreamerWebRTCVideoDecoder : public webrtc::VideoDecoder {
212211
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
213212
}
214213

214+
if (inputImage._encodedWidth && inputImage._encodedHeight)
215+
updateCapsFromImageSize(inputImage._encodedWidth, inputImage._encodedHeight);
216+
217+
if (UNLIKELY(!m_caps)) {
218+
GST_ERROR("Encoded image caps not set");
219+
ASSERT_NOT_REACHED();
220+
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
221+
}
222+
215223
// FIXME: Use a GstBufferPool.
216224
GST_TRACE_OBJECT(pipeline(), "Pushing encoded image with RTP timestamp %u", inputImage.RtpTimestamp());
217225
auto buffer = adoptGRef(gstBufferNewWrappedFast(fastMemDup(inputImage.data(), inputImage.size()), inputImage.size()));
218226

219227
gst_buffer_add_reference_timestamp_meta(buffer.get(), m_rtpTimestampCaps.get(), inputImage.RtpTimestamp(), GST_CLOCK_TIME_NONE);
220228

221-
auto sample = adoptGRef(gst_sample_new(buffer.get(), GetCapsForFrame(inputImage), nullptr, nullptr));
229+
auto sample = adoptGRef(gst_sample_new(buffer.get(), m_caps.get(), nullptr, nullptr));
222230
switch (gst_app_src_push_sample(GST_APP_SRC(m_src), sample.get())) {
223231
case GST_FLOW_OK:
224232
break;
@@ -247,16 +255,14 @@ class GStreamerWebRTCVideoDecoder : public webrtc::VideoDecoder {
247255
return WEBRTC_VIDEO_CODEC_OK;
248256
}
249257

250-
virtual GstCaps* GetCapsForFrame(const webrtc::EncodedImage& image)
258+
virtual void updateCapsFromImageSize(int width, int height)
251259
{
252-
if (!m_caps) {
253-
m_caps = adoptGRef(gst_caps_new_simple(Caps(),
254-
"width", G_TYPE_INT, image._encodedWidth ? image._encodedWidth : m_width,
255-
"height", G_TYPE_INT, image._encodedHeight ? image._encodedHeight : m_height,
256-
nullptr));
257-
}
260+
if (m_width == width && m_height == height)
261+
return;
258262

259-
return m_caps.get();
263+
m_width = width;
264+
m_height = height;
265+
m_caps = adoptGRef(gst_caps_new_simple(Caps(), "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, nullptr));
260266
}
261267

262268
void AddDecoderIfSupported(std::vector<webrtc::SdpVideoFormat>& codecList)
@@ -289,8 +295,8 @@ class GStreamerWebRTCVideoDecoder : public webrtc::VideoDecoder {
289295

290296
protected:
291297
GRefPtr<GstCaps> m_caps;
292-
gint m_width;
293-
gint m_height;
298+
int m_width;
299+
int m_height;
294300
bool m_requireParse = false;
295301
bool m_needsKeyframe;
296302

@@ -323,17 +329,15 @@ class H264Decoder : public GStreamerWebRTCVideoDecoder {
323329
return GStreamerWebRTCVideoDecoder::Configure(codecSettings);
324330
}
325331

326-
GstCaps* GetCapsForFrame(const webrtc::EncodedImage& image) final
332+
void updateCapsFromImageSize(int width, int height) final
327333
{
328-
if (!m_caps) {
329-
m_caps = adoptGRef(gst_caps_new_simple(Caps(),
330-
"width", G_TYPE_INT, image._encodedWidth ? image._encodedWidth : m_width,
331-
"height", G_TYPE_INT, image._encodedHeight ? image._encodedHeight : m_height,
332-
"alignment", G_TYPE_STRING, "au",
333-
nullptr));
334-
}
334+
if (m_width == width && m_height == height)
335+
return;
335336

336-
return m_caps.get();
337+
m_width = width;
338+
m_height = height;
339+
m_caps = adoptGRef(gst_caps_new_simple(Caps(), "width", G_TYPE_INT, width, "height", G_TYPE_INT, height,
340+
"alignment", G_TYPE_STRING, "au", nullptr));
337341
}
338342
const gchar* Caps() final { return "video/x-h264"; }
339343
const gchar* Name() final { return cricket::kH264CodecName; }

0 commit comments

Comments
 (0)