FFmpeg Custom IO

There are a few articles on the internet about this topic, but they are kind of outdated so I'm writing a new one.

First I urge you to read the documentation on avio_alloc_context().

Sample code is here for the impatient.

The idea is simple, just define your own callback methods and buffers, then tell ffmpeg to use them. In the sample code, I wrapped up the variables into a class to make them accessible when ffmpeg calls our methods.

ioCtx = avio_alloc_context(
  buffer, bufferSize, // internal buffer and its size
  0, // write flag (1=true, 0=false) 
  (void*)this, // user data, will be passed to our callback functions
  IOReadFunc, 
  0, // no writing
  IOSeekFunc
);

There are a few things to pay attention to. Use av_malloc() and av_free() to allocate and free your buffer, ffmpeg aligns the memory it allocates which should speed things up. Free the buffer first then free AVIOContext, and make sure to use your original pointer. It's also necessary to discover the input format yourself, either probe it or set it. And even if you do your own IO, don't count on calling avformat_open_input() from multiple threads at the same time.

Below is how to open a file using the class I wrote. Note that an empty filename is passed into avformat_open_input().

MyIOContext *ioCtx = new MyIOContext("random_file");
AVFormatContext *avFormatCtx = avformat_alloc_context();
ioCtx->initAVFormatContext(avFormatCtx);
if (avformat_open_input(&avFormatCtx, "", NULL, NULL) != 0) {
    // handle error
}
// ...
avformat_close_input(&avFormatCtx);

References: