Hi,
On 2009-08-04 at 14:47:06 [+0200], Sven Alisch <[email protected]> wrote:
> Time went by and I spend some time in developing my app further. Some
> months ago Victor sent me this code snippet here:
>
> > struct NALMsg {
> > uint8_t* data;
> > int size;
> > char header;
> > NalMsg* next;
> > }
> > int my_read(void* opaq, uint8_t* buf, int size)
> > {
> > NalMsg msg;
> > ... parse buffer 'buf' into list of NAL units in NALMsg return size;
> > }
> > main()
> > {
> > ...
> > ByteIOContext ByteIOCtx;
> > init_put_byte(&ByteIOCtx, pDataBuffer, lSize, 0, this, &my_read, NULL,
> > NULL); ...
> > }
> >
> > av_read_frame will call your 'my_read' function to "do your thing" Let
> > me know if you find other methods.
>
> I have some understanding problems with this. Its clear that my_read is a
> callback function. But what I don't understand is, is my_read called
> every time by an av_read_frame invocation? Then my_read is also called if
> an audio frame is read? Could it be? I only want to parse the video
> stream from an ts-file. How can I do that?
It depends. When you iterate over the streams in your AVFormatContext, you
can set any stream to be ignored, like so:
// Discard all other streams
for (unsigned i = 0; i < YourAVFormatContext->nb_streams; i++) {
if (i != TheStreamIndexYouAreInterestedIn)
YourAVFormatContext->streams[i]->discard =
AVDISCARD_ALL;
}
And that does make sure that you never get any packages for the other
streams from av_read_frame().
However, you did not provide a seek() hook function to the ByteIOContext.
So I believe your read() function will definitely have to read the packets
for other streams (even if you don't see them in av_read_frame()).
Depending on your situation (i.e. if you are not streaming over the
network), you could implement the seek() hook, and then libavformat will
probably make sure to skip packets for streams that are to be ignored.
Implementing the seek() hook is very simple, just look at one of the
existing URLProtocol implementations, like file.c.
> BTW: If I use your code:
> > main()
> > {
> > ...
> > ByteIOContext ByteIOCtx;
> > init_put_byte(&ByteIOCtx, pDataBuffer, lSize, 0, this, &my_read, NULL,
> > NULL); ...
> > }
>
> It does not work. It only works if I use an existing bytecontext from an
> AVFormatContext like:
>
> init_put_byte(mPFormatCtx->pb, mPFormatCtx->pb->buffer,
> mPFormatCtx->pb->buffer_size, 0, this, &my_read, NULL, NULL);
>
> Is that right? Or?
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);
Hope this helps & best regards,
-Stephan
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user