[Libav-user] Reading OGV format from stdin using AVIOContext
Rado
radokado at gmail.com
Wed Dec 21 14:26:49 EET 2016
hello,
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
2.
[ogg @ 0000000000fa8040] Headers mismatch for stream 2: expected 3 received
1.
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 +
AV_INPUT_BUFFER_PADDING_SIZE);
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?
thanks
Rado
-------------- 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