From e2493e2dfdb9cd7fe2254c1e5f5fc5f7d89fc3a3 Mon Sep 17 00:00:00 2001 From: Shaun Ren Date: Tue, 11 Oct 2022 16:42:28 -0400 Subject: [PATCH] media-converter: Set stream ID as the video hash. If a stream ID is not set, gstreamer will generate random stream IDs for the streams in downstream elements. This can cause decodebin to generate its source pads in a non-deterministic order, as decodebin takes into account the stream IDs when sorting the source pads. This patch includes some changes from Arek Hiler. CW-Bug-Id: #21192 --- media-converter/src/videoconv/imp.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/media-converter/src/videoconv/imp.rs b/media-converter/src/videoconv/imp.rs index a40f816d..0014146a 100644 --- a/media-converter/src/videoconv/imp.rs +++ b/media-converter/src/videoconv/imp.rs @@ -298,6 +298,8 @@ struct VideoConvState { our_duration: Option, transcoded_tag: u32, + + need_stream_start: bool, } impl VideoConvState { @@ -321,6 +323,8 @@ impl VideoConvState { our_duration: None, transcoded_tag: VIDEOCONV_FOZ_TAG_MKVDATA, + + need_stream_start: true, }) } @@ -802,15 +806,29 @@ impl VideoConv { .activate_mode(mode, active)?; if mode == gst::PadMode::Pull { - let mut state = self.state.lock().unwrap(); + let need_stream_start; + let hash; - let mut state = match &mut *state { - Some(s) => s, + /* push_event, below, can also grab state and cause a deadlock, so make sure it's + * released before calling */ + match &mut *self.state.lock().unwrap() { + Some(state) => { + self.init_transcode(state)?; + need_stream_start = state.need_stream_start; + hash = state.transcode_hash; + }, None => { return Err(loggable_error!(CAT, "VideoConv not yet in READY state?")); } }; - /* once we're initted in pull mode, we can start transcoding */ - self.init_transcode(&mut state)?; + if need_stream_start && active && hash.is_some() { + let stream_id = format!("{:032x}", hash.unwrap()); + self.srcpad.push_event(gst::event::StreamStart::new(&stream_id)); + + match &mut *self.state.lock().unwrap() { + Some(state) => { state.need_stream_start = false }, + None => { return Err(loggable_error!(CAT, "VideoConv not yet in READY state?")); } + }; + } } Ok(())