No app-sink callback when executing in docker container

Hi guys!

I’m trying to do something fairly simple (I would think) but it fails miserably in a docker container (but works otherwise…). I am using Rust and gstreamer-rs to interface GStreamer itself.

The goal of this task is to compute a thumbnail for a video (mkv, but it could be any format) that I receive over HTTP. Conveniently an example of something similar exists in the gstreamer-rs repo, so it’s derived from that.

The pipeline is the following: appsrc -> decodebin -> videoconvert -> appsink. I use an appsrc at the beginning because I want to provide the video from ram (I suspect I might not be doing that correctly? It feels wrong to have a giant buffer with the entire video, but it works?).

I don’t know how much code I can share yet, but for now I think it’s sufficient to show the following:

pipeline.state_state(State::Playing)?;
let buffer = Buffer::from_slice(entire_video_as_bytes);
app_source.push_buffer(buffer)?;

I then have a tokio channel wait for the video frame to be ready, and I have a timeout on the entire operation to avoid long processing. The callback setup is set as shown in the example from gstreamer-rs with tweaks to have a tokio oneshot channel send the frame over.

When I run locally, either in release or debug mode, this works exactly as intended. When I run inside a docker container, it seems the app_sink’s callback is never called and thus, the operation always times out.

The docker environment is pretty simple: it’s “ubuntu:latest” with all the required packages for gstreamer, plus ffmpeg and a few other things (curl, pkg-config, nothing special).

To start, here are my first two questions:

  1. Are there known interactions between GStreamer and docker containers?
  2. Can I pass a full video within a buffer like that an expect GStreamer to deal with it, or there’s a more elegant way (that’s quite convenient however)

So I’m not sure why this solved it, but adding a “send EOS” after the push buffer worked.

EOS will flush the pipeline.

Yes I’m aware, and that’s OK behavior in this particular case, but why the difference between dockerized and non-dockerized applications?

You did not say how you are running your container with Docker. What resources are allocated to it? I run GStreamer in Kube Pods and do not have any issues. This is with a ‘heavy weight’ pipeline as well (gstcefsrc).

Everything else equal things should behave the same inside a docker container and outside, but it’s possible that plugins such as hardware-accelerated video decoders/encoders or image/video sinks/source might not work out of the box in a docker environment, so might be worth checking if different elements are being used inside and outside your docker env and that’s what makes it work or not.

Also, if the appsink doesn’t fire the callback it probably didn’t get data, so to debug that you need to work backward inside the pipeline and see which element didn’t receive/output any data, until you find the one that behaves differently.

You did not say how you are running your container with Docker. What resources are allocated to it? I run GStreamer in Kube Pods and do not have any issues. This is with a ‘heavy weight’ pipeline as well (gstcefsrc).

This is just a regular docker image based on a default install of ubuntu, with all gstreamer packages installed. Basically what I would configure for a minimal local development environment of gstreamer stuff.

Everything else equal things should behave the same inside a docker container and outside

My thinking exactly,

but it’s possible that plugins such as hardware-accelerated video decoders/encoders or image/video sinks/

But it does with with an EOS now… So I’m quite confused. I also suspected the hardware interactions might have had a role.

I’m going to venture out a guess, and guess that the HW decoder for the mkv on my machine and the SW decoder in the docker do not behave the same, and until the EOS nothing was sent