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

Reply via email to