Hi,
On 2009-08-04 at 17:06:33 [+0200], Sven Alisch <[email protected]> wrote:
> > This is wrong, you need to open the stream like this, by passing your
> > IO context to av_open_input_stream():
> >
> > ByteIOContext ByteIOCtx;
> > init_put_byte(&ByteIOCtx, pDataBuffer, lSize, 0, this, &my_read,
> > NULL,
> > NULL); ...
> >
> > av_open_input_stream(&YourAVFormatContext, &ByteIOCtx, "",
> > TheAVInputFormat, TheAVFormatParametersOrNULL);
>
> Ok too. Then I have further questions:
>
> 1) pDataBuffer and lSize are variables that you declare yourself? And how
> big should pDataBuffer be?
That is a very valid question. In the example I read, I saw "BUFSIZ" (some
POSIX define) being used. But I found that 64K was a good buffer size, for
the initial probing. 4K would probably have been sufficient. What I just
wrote actually makes only sense, because I was using the same buffer and
read function to read the initial probing data. This may not even apply to
you.
What happens, and that is important for your next question as well, is that
this is a very simple, low-level, raw data reading function. libavformat
will buffer the data your returned internally as it needs. If your buffer
is smaller, than there will be more calls to your read() hook, if it is
larger, there will be less. So it depends a bit on what you need. If you
read larger chunks at once by supplying a bigger buffer, it may be a bit
faster (more buffering), there will be a sweet spot.
> 2) What is my influence to av_read_frame if I use such a callback
> function
> my_read? Is it right that I can make av_read_frame to deliver a complete
> frame consists of several NAL-Packets?
I can see where this is going, but I guess it heavily depends on the
demuxer that you are using. If it expects packtes at certain offsets, then
you can't just filter the data as you like and shuffle packets around
inside the buffer you return. I guess with a non-seekable streaming format,
you should have more freedom to do this, since the demuxer cannot know in
advance what kind of packet will come next (?) so as long as you assemble
valid stream chunks, it should be fine.
> 3) My Callbackfunction my_read looks like:
>
> int my_read(void* opaq, uint8_t* buf, int size)
> {
> ...
>
> return size;
> }
>
> Depends the content of an AVPacket readed by av_read_frame by the size I
> return in my_read?
Ahm, no, your read() hook is used before AVPackets even enter the picture.
Unless you are piping two AVFormatContext instances, which would be weird.
Maybe an example is due. Suppse I am reading an AVI file via my own read()
hook. Maybe I supplied a 4K buffer. libavformat will probably read all of
4K, even if this has nothing to do with the chunk data inside those 4K.
Suppose there is a 3500 byte video chunk inside the data I returned, and a
200 byte audio data chunk. When I later call av_read_frame(), it may return
the video chunk encapsulated in an AVPacket. A second call to
av_read_frame() will return the audio chunk. Then the AVI demuxer knows the
next video chunk is 3000 bytes. Then it will assemble the remaining 300
bytes from the previes read() invokation, and invoke the next read() to
fetch another 4K, which will contain the remaining 2700 bytes of the video
chunk. Do you see how this works? Providing your own read() hook is at the
lowest level of feeding data into libavformat. AVPackets and demuxing comes
at the next level, read() has little to do with it.
> My goal is to cut an transportstream consisting of h.264-content and
> audiocontent. The only obstacle is that av_read_frame give me corrupted
> h.264 frames. MPEG2 is much easier. :-( Therefore I need a correct
> working av_read_frame in connection with h.264-bitstream.
If you need to filter out some packets from the stream, so that libavformat
never sees them, then you would have to demux the stream yourself and skip
unwanted packets. I suppose you could even do this using another
AVFormatContext, but are you sure that this is the cause for your problems?
At this point, I am afraid that I know too little of what you are doing,
combined with my relative incompetence with regards to the FFmpeg libs,
that I cannot help you with good advice. I did have to write my own
read()/seek()/write() hooks and am using a ByteIOContext, so I can tell you
my findings with that. An alternative for using a ByteIOContext is writing
your own URLProtocol, but so far it seemed to me like it is more code for
the same thing.
Best regards,
-Stephan
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user