How can I "roll-back" DTS/PTS calculations, performed in av_read_frame()

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How can I "roll-back" DTS/PTS calculations, performed in av_read_frame()

wl2776
Administrator
I'm writing an application, which connects to the remote server, storing video data, and downloads them, creating a playable movie file.
I've chosen the mov container, as it allows storing many various codecs, and my application can simply remux received video data.
Sometimes connection to the server terminates, and my application restores it and requests data from the beginning of the frame, where disconnection occurred.

My application uses custom AVIOContext.

The problem is in the fact, that right before the connection termination is discovered, av_read_frame returns incomplete frame.
AVIOContext::eof_reached is true in that case, and AVIOContext::error has an error code, which my read function returned to libav.

I can see that the frame is incomplete from AVPacket::size analysis (server returns frame size before sending data).
The broken frame, returned from av_read_frame() also sometimes doesn't have PTS value.

When connection to the server is restored, next call to av_read_packet returns the same frame, now with complete data. But this frame has now invalid DTS/PTS values, they are increased, compared to the previous case, where the frame data were broken.

If I dumbly write both those frames to the output file, the resulting movie will have couples of same frames, first of which will be incomplete, and a player displays both of them, which gives a picture freeze for a moment.
If I skip broken frames without any other actions, the resulting movie will contain only complete frames, but with invalid DTS/PTS.

So, is it possible to say libav that it now retries reading the frame it has returned recently?
That it should not calculate new PTS/DTS for the newly returned frame, but use the recent values instead?
Loading...