drop entire frame when RTP packets are lost
[Please forgive me if this issue has already been discussed -- I am new to ffmpeg-devel. I could not, however, find any discussion on this topic on this list in the past year, so here goes.] In the current design of ffplay/ffmpeg, when an RTP packet is lost, the containing -- and incomplete -- encoded frame is still passed along to the decoder. I have implemented a patch that has the read thread keep track of how many packets are missed, and when any are missed, the entire containing frame is dropped (that is, never makes it out of the read thread). I would be happy to send this patch upstream, or discuss it further if anyone likes. (The patch touches six files and about 25 lines of code.) Martin Carroll
On Fri, Jun 29, 2012 at 01:41:06PM -0400, Martin Carroll wrote:
[Please forgive me if this issue has already been discussed -- I am new to ffmpeg-devel. I could not, however, find any discussion on this topic on this list in the past year, so here goes.]
In the current design of ffplay/ffmpeg, when an RTP packet is lost, the containing -- and incomplete -- encoded frame is still passed along to the decoder. I have implemented a patch that has the read thread keep track of how many packets are missed, and when any are missed, the entire containing frame is dropped (that is, never makes it out of the read thread).
I would be happy to send this patch upstream, or discuss it further if anyone likes.
(The patch touches six files and about 25 lines of code.)
the question left open is why the frame should be droped ? -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB If a bugfix only changes things apparently unrelated to the bug with no further explanation, that is a good sign that the bugfix is wrong.
the question left open is why the frame should be dropped ?
Good point. Two reasons: 1. In my testing, dropping the frame produces noticeably better visual results (than sending an incomplete encoded frame to the decoder). 2. One cause of lost RTP packets is ffplay's inability to keep up with the arriving packets. Dropping the frame (and not spending the time to decode it -- albeit in another thread) increases the probability that ffplay will be able to catch up. Martin Carroll
On Fri, Jun 29, 2012 at 01:53:39PM -0400, Martin Carroll wrote:
the question left open is why the frame should be dropped ?
Good point. Two reasons:
1. In my testing, dropping the frame produces noticeably better visual results (than sending an incomplete encoded frame to the decoder).
i would be interrested in a testcase, can you dump both variants to a file ? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Awnsering whenever a program halts or runs forever is On a turing machine, in general impossible (turings halting problem). On any real computer, always possible as a real computer has a finite number of states N, and will either halt in less than N cycles or never halt.
1. In my testing, dropping the frame produces noticeably better visual results (than sending an incomplete encoded frame to the decoder).
i would be interrested in a testcase, can you dump both variants to a file ?
What precisely is it that you want me to dump to a file? The patch? A recording of the video degredation that occurs in the two cases? Something else? Martin Carroll
On Fri, Jun 29, 2012 at 03:29:25PM -0400, Martin Carroll wrote:
1. In my testing, dropping the frame produces noticeably better visual results (than sending an incomplete encoded frame to the decoder).
i would be interrested in a testcase, can you dump both variants to a file ?
What precisely is it that you want me to dump to a file? The patch? A recording of the video degredation that occurs in the two cases? Something else?
you said that "dropping the frame produces noticeably better visual results" Iam interrested in investigating what goes wrong in the decoder and error concealment code that makes it look better with less data. so i would need something that i can feed into the decoder to reproduce this difference [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB When the tyrant has disposed of foreign enemies by conquest or treaty, and there is nothing more to fear from them, then he is always stirring up some war or other, in order that the people may require a leader. -- Plato
Hi Michael,
I am interested in investigating what goes wrong in the decoder and error concealment code that makes it look better with less data.
I conjecture that at least part of the visual improvement that results from dropping entire frames (when RTP packets are lost) is the fact that by dropping entire frames, ffplay has a better chance of catching up with the RTP stream. There may be other factors at work as well.
so i would need something that i can feed into the decoder to reproduce this difference
I presume that you have your favorite way of generating an RTP stream. If so, then I suggest that you just send it your favorite video and watch what happens with and without my patch. (My favorite video is glxgears.) And regarding my patch: Given that I am new to this list, I did not want to be presumptuous and send my patches up. Shall I do that now? Martin Carroll
Hi Martin On Mon, Jul 02, 2012 at 09:36:07AM -0400, Martin Carroll wrote:
Hi Michael,
I am interested in investigating what goes wrong in the decoder and error concealment code that makes it look better with less data.
I conjecture that at least part of the visual improvement that results from dropping entire frames (when RTP packets are lost) is the fact that by dropping entire frames, ffplay has a better chance of catching up with the RTP stream. There may be other factors at work as well.
so i would need something that i can feed into the decoder to reproduce this difference
I presume that you have your favorite way of generating an RTP stream. If so, then I suggest that you just send it your favorite video and watch what happens with and without my patch. (My favorite video is glxgears.)
just tried, no corruption here with rtp, so i would assume your patches wont make a difference
And regarding my patch: Given that I am new to this list, I did not want to be presumptuous and send my patches up. Shall I do that now?
your patches are welcome! though for this issue here, fixing it will require us to be able to reproduce & analyze it. Droping frames sounds quite wrong. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No human being will ever know the Truth, for even if they happen to say it by chance, they would not even known they had done so. -- Xenophanes
On Mon, Jul 02, 2012 at 12:57:55PM -0400, Martin Carroll wrote:
just tried, no corruption here with rtp,
Could you please tell me how you generated your stream? What tool did you use to send it, what were your command-line arguments, what was your resolution and frame rate, etc.?
vlc 320x240 30fps IIRC [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope
vlc 320x240 30fps IIRC
When you ran the experiment, were you also using RTSP or RTCP (or anything else), or were you only sending an RTP stream? mar
On Mon, Jul 02, 2012 at 01:11:37PM -0400, Martin Carroll wrote:
vlc 320x240 30fps IIRC
When you ran the experiment, were you also using RTSP or RTCP (or anything else), or were you only sending an RTP stream?
SDP + RTP but i think its more interresting what you did to produce the problem not so much what i did that failed to reproduce it ... its really if you used RTSP/RTCP, UDP vs TCP , which software which video, which command line parameters, ... that we need. I mean if you provide me a exact list of command line parameters with which i can run a whole server + client which then shows the problem then i likely can fix it properly instead of just droping the frames ... [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Into a blind darkness they enter who follow after the Ignorance, they as if into a greater darkness enter who devote themselves to the Knowledge alone. -- Isha Upanishad
but i think it's more interesting what you did to produce the problem
I used only an RTP stream, and I fed ffplay an SDP file on the command line. I generated the RTP stream using a special piece of hardware -- specifically, a Tilera board running an H.264 encoder. So unless you have a Tilera board, the ball is in my court to figure out what is different between my RTP stream and yours. Which is why I asked for your settings. mar
On Mon, Jul 02, 2012 at 01:44:32PM -0400, Martin Carroll wrote:
but i think it's more interesting what you did to produce the problem
I used only an RTP stream, and I fed ffplay an SDP file on the command line. I generated the RTP stream using a special piece of hardware -- specifically, a Tilera board running an H.264 encoder. So unless you have a Tilera board, the ball is in my court to figure out what is different between my RTP stream and yours. Which is why I asked for your settings.
hmm, ok, understood i used this: vlc --play-and-exit -vvv in.mpg --sout '#rtp{dst=127.0.0.1,port=1234,mux=ts,sdp=http://127.0.0.1:4321/test.sdp}' and played it with ffplay -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Complexity theory is the science of finding the exact solution to an approximation. Benchmarking OTOH is finding an approximation of the exact
vlc --play-and-exit -vvv in.mpg --sout '#rtp{dst=127.0.0.1,port=1234,mux=ts,sdp=http://127.0.0.1:4321/test.sdp}'
I am also seeing corruption when I do the above. What version of vlc are you running? Also, have you tried streaming a video for a long time (using --loop instead of --play-and-exit)? Corruption often does not start until a minute or so into the video. mar
On Mon, Jul 02, 2012 at 05:16:10PM -0400, Martin Carroll wrote:
vlc --play-and-exit -vvv in.mpg --sout '#rtp{dst=127.0.0.1,port=1234,mux=ts,sdp=http://127.0.0.1:4321/test.sdp}'
I am also seeing corruption when I do the above. What version of vlc are you running? Also, have you tried streaming a video for a long time (using --loop instead of --play-and-exit)? Corruption often does not start until a minute or so into the video.
thanks, i could reproduce the corruption the problem is caused by the OS UDP buffer overflowing this is because rtpproto.c disabled our ring buffer without the ring buffer the code depends on the OS having large enough buffers which it plain doesnt To fix this you would have to do 2 things first remove "url_add_option(buf, buf_size, "fifo_size=0");" from rtpproto.c and second make the rtp code actually work with the udp code with its fifo, currently the rtp code hacks into the udp code and extracts its fd and accesses this directly bypassing the fifo, which cannot work [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB You can kill me, but you cannot change the truth.
the problem is caused by the OS UDP buffer overflowing this is because rtpproto.c disabled our ring buffer without the ring buffer the code depends on
the OS having
large enough buffers which it plain doesnt ...
Yes, I had already spotted that, and to "fix" it I did a side-experiment in which I hard-coded a very large receive buffer (in the setsockopt() call in udp.c). Even with a very large buffer, I still eventually start losing packets. I did not bother to mention that side experiment, because I was under the impression that the *existing* code allegedly worked. Given your statements re how to fix it, I conclude that ffplay, as written, does not support the playing of RTP streams that are longer than under, say, a minute or so. Please correct me if I'm wrong... mar
On Tue, Jul 03, 2012 at 04:01:49PM -0400, Martin Carroll wrote:
the problem is caused by the OS UDP buffer overflowing this is because rtpproto.c disabled our ring buffer without the ring buffer the code depends on the OS having large enough buffers which it plain doesnt ...
Yes, I had already spotted that, and to "fix" it I did a side-experiment in which I hard-coded a very large receive buffer (in the setsockopt() call in udp.c). Even with a very large buffer, I still eventually start losing packets. I did not bother to mention that side experiment, because I was under the impression that the *existing* code allegedly worked.
I tried the same before writing the mail and my results where different. are you sure you updated net.core.rmem_max and net.core.rmem_default ? because these limit the buffer size on linux?
Given your statements re how to fix it, I conclude that ffplay, as written, does not support the playing of RTP streams that are longer than under, say, a minute or so. Please correct me if I'm wrong...
Iam not aware of such a limitation. the way stream probing works is libavformat causes a irregularity in the calling of the rtp code which then causes the OS buffers to overflow as the UDP ring buffer is not useable with RTP ATM. This has nothing to do with ffplay, ffplay reads data as it needs it ffmpeg reads all data it can get as quick as it can. You can achive the same with ffplay by increasing MIN_FRAMES but this has other disadvantages ... [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The educated differ from the uneducated as much as the living from the dead. -- Aristotle
On Wed, Jul 04, 2012 at 02:19:29AM +0200, Michael Niedermayer wrote:
On Tue, Jul 03, 2012 at 04:01:49PM -0400, Martin Carroll wrote:
the problem is caused by the OS UDP buffer overflowing this is because rtpproto.c disabled our ring buffer without the ring buffer the code depends on the OS having large enough buffers which it plain doesnt ...
Yes, I had already spotted that, and to "fix" it I did a side-experiment in which I hard-coded a very large receive buffer (in the setsockopt() call in udp.c). Even with a very large buffer, I still eventually start losing packets. I did not bother to mention that side experiment, because I was under the impression that the *existing* code allegedly worked.
I tried the same before writing the mail and my results where different. are you sure you updated net.core.rmem_max and net.core.rmem_default ? because these limit the buffer size on linux?
Given your statements re how to fix it, I conclude that ffplay, as written, does not support the playing of RTP streams that are longer than under, say, a minute or so. Please correct me if I'm wrong...
Iam not aware of such a limitation. the way stream probing works is libavformat causes a irregularity in the calling of the rtp code which then causes the OS buffers to overflow as the UDP ring buffer is not useable with RTP ATM. This has nothing to do with ffplay, ffplay reads data as it needs it ffmpeg reads all data it can get as quick as it can. You can achive the same with ffplay by increasing MIN_FRAMES but this has other disadvantages ...
you can now use ffplay -infbuf instead of changing MIN_FRAMES to enable this hack, thanks to martin. but still this is not a proper solution, some applications cannot gurantee that they would call the rtp code frequently enough to avoid buffer overflows. Single threaded players like mplayer come to mind ... [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No great genius has ever existed without some touch of madness. -- Aristotle
On Wed, Jul 04, 2012 at 09:27:02PM +0200, Michael Niedermayer wrote:
On Wed, Jul 04, 2012 at 02:19:29AM +0200, Michael Niedermayer wrote:
On Tue, Jul 03, 2012 at 04:01:49PM -0400, Martin Carroll wrote:
the problem is caused by the OS UDP buffer overflowing this is because rtpproto.c disabled our ring buffer without the ring buffer the code depends on the OS having large enough buffers which it plain doesnt ...
Yes, I had already spotted that, and to "fix" it I did a side-experiment in which I hard-coded a very large receive buffer (in the setsockopt() call in udp.c). Even with a very large buffer, I still eventually start losing packets. I did not bother to mention that side experiment, because I was under the impression that the *existing* code allegedly worked.
I tried the same before writing the mail and my results where different. are you sure you updated net.core.rmem_max and net.core.rmem_default ? because these limit the buffer size on linux?
Given your statements re how to fix it, I conclude that ffplay, as written, does not support the playing of RTP streams that are longer than under, say, a minute or so. Please correct me if I'm wrong...
Iam not aware of such a limitation. the way stream probing works is libavformat causes a irregularity in the calling of the rtp code which then causes the OS buffers to overflow as the UDP ring buffer is not useable with RTP ATM. This has nothing to do with ffplay, ffplay reads data as it needs it ffmpeg reads all data it can get as quick as it can. You can achive the same with ffplay by increasing MIN_FRAMES but this has other disadvantages ...
you can now use ffplay -infbuf instead of changing MIN_FRAMES to enable this hack, thanks to martin. but still this is not a proper solution, some applications cannot gurantee that they would call the rtp code frequently enough to avoid buffer overflows. Single threaded players like mplayer come to mind ...
Well, the cache code in MPlayer could handle it just fine. But I think rtp is one of the formats that bypasses the stream layer and thus MPlayer can't use the cache...
Martin Carroll <martin.carroll <at> alcatel-lucent.com> writes:
[Please forgive me if this issue has already been discussed -- I am new to ffmpeg-devel. I could not, however, find any discussion on this topic on this list in the past year, so here goes.]
In the current design of ffplay/ffmpeg, when an RTP packet is lost, the containing -- and incomplete -- encoded frame is still passed along to the decoder. I have implemented a patch that has the read thread keep track of how many packets are missed, and when any are missed, the entire containing frame is dropped (that is, never makes it out of the read thread).
I would be happy to send this patch upstream, or discuss it further if anyone likes.
(The patch touches six files and about 25 lines of code.)
Martin Carroll
Hi Martin Carroll, Can you share the patch so that we can also test the results for frame drop if packet is missing. Thank you pradeep T
participants (4)
-
Martin Carroll -
Michael Niedermayer -
pradeep -
Reimar Döffinger