<div dir="ltr"><div><div><div><div><div><div>hello,<br><br></div>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.<br><br></div><div>It works for all formats I tried - mkv, mp4, mov, 3gp, mpg... - except for OGV, for which calling avformat_open_input outputs warnings:<br>[ogg @ 0000000000fa8040] 60 bytes of comment header remain<br>[ogg @ 0000000000fa8040] truncated comment header, 2 comments not found<br>[ogg @ 0000000000fa8040] Headers mismatch for stream 1: expected 3 received 2.<br>[ogg @ 0000000000fa8040] Headers mismatch for stream 2: expected 3 received 1.<br><br></div><div>avformat_find_stream_info also returns 0, but outputs:<br>[theora @ 0000000000fa7b60] Corrupt extradata<br>[ogg @ 0000000000fa8040] Failed to open codec in av_find_stream_info<br>[vorbis @ 0000000000fab060] Extradata missing.<br>[ogg @ 0000000000fa8040] Failed to open codec in av_find_stream_info<br>[theora @ 0000000000fa7b60] Corrupt extradata<br>[ogg @ 0000000000fa8040] Broken file, keyframe not correctly marked.<br>[vorbis @ 0000000000fab060] Extradata missing.<br><br></div><div>and finally avcodec_open2 fails with:<br>[theora @ 0000000000fadce0] Corrupt extradata<br><br></div>I create avioContext like this:<br>  const int ioBufferSize = 4096;<br>  unsigned char *ioBuffer = (unsigned char *) av_malloc(ioBufferSize + AV_INPUT_BUFFER_PADDING_SIZE);<br>  avioCtx = avio_alloc_context(ioBuffer, ioBufferSize, 0, (void *) bd, &readPacketFunction, NULL, &seekPacketFunction);<br>  formatContext = avformat_alloc_context();<br>  formatContext->pb = avioCtx;<br><br></div>where bd is a struct:<br>struct BufferData {<br>    uint8_t *start;<br>    uint8_t *pos;<br>    size_t totalSize;<br>    size_t sizeLeft;<br>};<br></div><div><br></div>and readPacketFunction and seekPacketFunction are defined as:<br>int64_t seekPacketFunction(void* opaque, int64_t offset, int whence) {<br>    struct BufferData *bd = (struct BufferData *) opaque;<br>    if (whence == AVSEEK_SIZE)<br>        return bd->totalSize;<br>    if (offset >= bd->totalSize || offset < 0)<br>        return -1;<br>    bd->pos = bd->start + offset;<br>    bd->sizeLeft = bd->totalSize - offset;<br>    return offset;<br>}<br><br>int readPacketFunction(void* opaque, uint8_t* buffer, int bufferSize) {<br>    struct BufferData *bd = (struct BufferData *) opaque;<br>    bufferSize = FFMIN(bufferSize, bd->sizeLeft);<br><br>    memcpy(buffer, bd->pos, bufferSize);<br>    bd->pos += bufferSize;<br>    bd->sizeLeft -= bufferSize;<br>    return bufferSize;<br>}<br><br></div>I create the BufferData struct like this (and read the file from stdin):<br>  bd = (struct BufferData*) malloc(sizeof (struct BufferData));<br>  bd->totalSize = sizeof (uint8_t) * cfg->inputFileSize;<br>  bd->start = (uint8_t*) malloc(bd->totalSize);<br>  bd->pos = bd->start;<br>  bd->sizeLeft = bd->totalSize;<br>  read(0, bd->start, cfg->inputFileSize);<br><br></div>(I've omitted the null checks/ malloc fails for brevity)<br><div><div><div><div><div><div><div><div><br></div><div>Does anyone have an idea why is ogg/theora failing while all other common formats work ok?<br></div><div>thanks<br><br></div><div>Rado<br></div></div></div></div></div></div></div></div></div>