[Libav-user] Reading OGV format from stdin using AVIOContext

Rado radokado at gmail.com
Wed Dec 21 14:26:49 EET 2016


I am writing a little C utility to extract frames from a video. I read the
input video file from stdin (requirement), so I use an AVIOContext to
handle reading / seeking.

It works for all formats I tried - mkv, mp4, mov, 3gp, mpg... - except for
OGV, for which calling avformat_open_input outputs warnings:
[ogg @ 0000000000fa8040] 60 bytes of comment header remain
[ogg @ 0000000000fa8040] truncated comment header, 2 comments not found
[ogg @ 0000000000fa8040] Headers mismatch for stream 1: expected 3 received
[ogg @ 0000000000fa8040] Headers mismatch for stream 2: expected 3 received

avformat_find_stream_info also returns 0, but outputs:
[theora @ 0000000000fa7b60] Corrupt extradata
[ogg @ 0000000000fa8040] Failed to open codec in av_find_stream_info
[vorbis @ 0000000000fab060] Extradata missing.
[ogg @ 0000000000fa8040] Failed to open codec in av_find_stream_info
[theora @ 0000000000fa7b60] Corrupt extradata
[ogg @ 0000000000fa8040] Broken file, keyframe not correctly marked.
[vorbis @ 0000000000fab060] Extradata missing.

and finally avcodec_open2 fails with:
[theora @ 0000000000fadce0] Corrupt extradata

I create avioContext like this:
  const int ioBufferSize = 4096;
  unsigned char *ioBuffer = (unsigned char *) av_malloc(ioBufferSize +
  avioCtx = avio_alloc_context(ioBuffer, ioBufferSize, 0, (void *) bd,
&readPacketFunction, NULL, &seekPacketFunction);
  formatContext = avformat_alloc_context();
  formatContext->pb = avioCtx;

where bd is a struct:
struct BufferData {
    uint8_t *start;
    uint8_t *pos;
    size_t totalSize;
    size_t sizeLeft;

and readPacketFunction and seekPacketFunction are defined as:
int64_t seekPacketFunction(void* opaque, int64_t offset, int whence) {
    struct BufferData *bd = (struct BufferData *) opaque;
    if (whence == AVSEEK_SIZE)
        return bd->totalSize;
    if (offset >= bd->totalSize || offset < 0)
        return -1;
    bd->pos = bd->start + offset;
    bd->sizeLeft = bd->totalSize - offset;
    return offset;

int readPacketFunction(void* opaque, uint8_t* buffer, int bufferSize) {
    struct BufferData *bd = (struct BufferData *) opaque;
    bufferSize = FFMIN(bufferSize, bd->sizeLeft);

    memcpy(buffer, bd->pos, bufferSize);
    bd->pos += bufferSize;
    bd->sizeLeft -= bufferSize;
    return bufferSize;

I create the BufferData struct like this (and read the file from stdin):
  bd = (struct BufferData*) malloc(sizeof (struct BufferData));
  bd->totalSize = sizeof (uint8_t) * cfg->inputFileSize;
  bd->start = (uint8_t*) malloc(bd->totalSize);
  bd->pos = bd->start;
  bd->sizeLeft = bd->totalSize;
  read(0, bd->start, cfg->inputFileSize);

(I've omitted the null checks/ malloc fails for brevity)

Does anyone have an idea why is ogg/theora failing while all other common
formats work ok?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20161221/4f8b0e0b/attachment.html>

More information about the Libav-user mailing list