1

I've been trying to debug this for hours now, and cannot seem to understand why it doesn't work.

I want to overlay a png onto all frames of a gif, and since writing all the files to disk is slow, i wanted to use pipes.

I created a named pipe using mkfifo imgstream1 and then launch ffmpeg:

ffmpeg -report -hide_banner -v 9 -loglevel 99 -y -f gif -i imgstream1 out1.gif

(This isn't actually useful as it just spits out the same gif again but it's simpler for debugging)

After ffmpeg launches it waits for data from the pipe, so i write an actual gif file to the pipe using this kotlin code

val backgroundFifo = File("imgstream1")
val inputOne = File("background.gif").readBytes()
println("background.gif -> ${inputOne.size} bytes")
val output = backgroundFifo.outputStream()
output.write(inputOne)
output.flush()
output.close()

It prints: background.gif -> 7233247 bytes

Now ffmpeg should read the bytes and spit out a gif, but it always seems to fail doing so.

Opening an input file: imgstream1.
[gif @ 0x7714180] Opening 'imgstream1' for reading
[file @ 0x7714980] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0x7724dc0] Statistics: 7233247 bytes read, 0 seeks
imgstream1: Input/output error

Sadly this does not give any further information, i'm already on the highest log level...

I've tried multiple things:

  • -f image2pipe -> Works, but only loads the first 2 frames of the gif
  • Renaming the pipe to imgstream1.gif so ffmpeg thinks it's a gif file, no change.
  • Different ffmpeg versions
  • Using the actual gif as an ffmpeg input works

At this point i have no idea what the problem might be, as ffmpeg seems to load all bytes. It's worth noting that doing cat imgstream1 > file.gif produces the desired gif.

Any help would be appreciated!

Xirado
  • 11
  • 2
  • should be `-i -` not `-i imgstream1` – kesh Oct 23 '22 at 19:29
  • 1
    @kesh `-i -` is for stdin pipes, `imgstream1` is an actual "file" in that directory that's created by `mkfifo` – Xirado Oct 23 '22 at 19:34
  • Ok my bad. (learning something new everyday.) btw, what's your FFmpeg version? (I searched for "Input/output error" in the FFmpeg repo and came out empty. If it is an older release, maybe try a current release?) – kesh Oct 23 '22 at 20:29
  • Can you run `ffmpeg` inside of `strace` to see exactly which syscall is failing with `EIO (Input/output error)`? – Joseph Sible-Reinstate Monica Oct 23 '22 at 23:08
  • @kesh I've tried both the latest stable version 4.2.7 and the current git master branch – Xirado Oct 24 '22 at 05:51
  • @JosephSible-ReinstateMonica This is the result https://hastebin.de/avizutobuw.txt – Xirado Oct 24 '22 at 05:51
  • 1
    Seems like ffmpeg is using `lseek()`, which is obviously not working on pipes, so it's expecting a file... Don't know why it needs to seek though – Xirado Oct 24 '22 at 06:02
  • That was what I was wondering as it is the same reason MP4 format cannot be piped and that's why `image2pipe` demuxer exists. Too bad it doesn't work with animated gifs. Are you retrieving gif over http? If so, have you tried to use the url as the input to ffmpeg? – kesh Oct 24 '22 at 18:43

0 Answers0