2

I have built a version of Live555 that uses FFMPEG to encode a video and stream it over RTSP.

Basically it works but the RTSP stream is very jittery.

I looked into it further and it turns out that Live555's max buffer size (fMaxSize) is too small and Live555 is truncating the frame as shown below:

/* This should never happen, but check anyway.. */
if (newFrameSize > fMaxSize) {
  fFrameSize = fMaxSize;
  fNumTruncatedBytes = newFrameSize - fMaxSize;
} else {
  fFrameSize = newFrameSize;
}

Now, I have almost no control over how big the packets are from FFMPEG, I can set the bitrate low but the quality is appauling and the packets are still too big!

Basically FFMPEG decides how big each frame is here:

int reti = avcodec_encode_video2(m_c, &pkt, m_frame, &got_packet);

If pkt.size > fMaxSize then the frame will be truncated and Live555 will stuff up streaming the video, which is does ALL the time. Also FFMPEG sometimes decides to buffer frames so the packet could be more than one frame big.

I can try and tell Live555 to up it's buffer size but it ignores it completely:

OutPacketBuffer::maxSize = 100000;

Has anyone else got a solution to stream the encoded video correctly? I have tried breaking the packets up and passing them to Live555 in smaller chunks but it doesn't work, and Live555 brings down it's fMaxSize if I send more packets.

My code is here:

https://dl.dropboxusercontent.com/u/15883001/Code.zip

Some images of what is happening to the RTSP stream is here, as you can see in the higher detail images LIVE555 struggles to send the packets properly:

https://dl.dropboxusercontent.com/u/15883001/vlcsnap-2013-12-12-09h34m30s225.zip

In the black and white image, the frame size is 117000 bytes and is less than the max frame size 300000

In the Iron coloured image, the frame size is 212000 bytes.

In the rainbow coloured image, the frame size is 322000 bytes and is greater than the max frame size 300000 and is truncated resulting in what you see in the example image.

Any help would be much appreciated

Thanks

mpromonet
  • 11,326
  • 43
  • 62
  • 91
ALM865
  • 1,078
  • 13
  • 21
  • I probably should mention that I have tested the FFPEG part of the code by writing the packets to a file and playing it in VLC, it appears to be functioning correctly. Live555 seems to be doing something funny with the stream before sending it over RTSP, I beleive it is because it is dropping too many frames. – ALM865 Dec 11 '13 at 04:36
  • AFAIK ffmpeg use x264 to encode (provided you're coding H.264). In that case you could configure the maximum slice size. – Ralf Dec 11 '13 at 06:13
  • It doesn't seem like I can set the max-slice-size in FFMPEG. I can see options for slice_count. I'll give it a go and let you know... – ALM865 Dec 11 '13 at 21:54
  • Well the slice_count option didn't seem to do anything. I'll keep looking into if I can set the max_slice_size somewhere... – ALM865 Dec 11 '13 at 22:06
  • For anyone reading this question with a similar problem, you need to put OutPacketBuffer::maxSize = xxxxx; in the xxxxxMediaSubsession.cpp file under ::createNewRTPSink for it to work. Unfortunately it still doesn't solve my problem though – ALM865 Dec 12 '13 at 00:16
  • I'm currently stuck with the same problem. Setting OutPacketBuffer::maxSize where you said I should however doesn't change anything. fMaxSize keeps getting smaller and smaller every call of deliverFrame to the point the buffer cannot hold all the data anymore. At this point, data is dropped and the client draws garbage. Any hints on how to prevent from this to happen? – iko79 Jan 12 '17 at 16:06

1 Answers1

1

You need to do correct packetization of data. Live555 already has everything. Look at how it works by reading from a file, packetizing it to rtp and then sending it. The only difference here is you are taking it from a encoder instead of file.

av501
  • 6,645
  • 2
  • 23
  • 34
  • 1
    Any tips on how to do that? At the moment I just tell FFMPEG to encode the frame (avcodec_encode_video2) and it spits back a packet if it's ready. – ALM865 Dec 11 '13 at 22:00
  • Okay, so using the H264VideoStreamDiscreteFramer my code works by increasing the OutputBufferSize, good! But I need to use the H264VideoStreamFramer because it adds extra data to the stream which is needed by the program I an trying to read the RTSP stream into. How to I turn my packets from avcodec_encode_video2 into slices that H264VideoStreamFramer can use? – ALM865 Dec 11 '13 at 23:51
  • I know this is a little off topic but is this SDP response correct? https://dl.dropboxusercontent.com/u/15883001/packets.txt It is different to the response created by H264VideoStreamFramer. – ALM865 Dec 12 '13 at 00:15
  • There is already a file media server example source code in live555 examples. If you can replace the fopen / fread of that file to instead read from your ffmpeg buffer you should be able to use live555 as is. I would have done that first. Its been quite some time for me to remember internal details though! Sorry. – av501 Dec 12 '13 at 02:48
  • Unfortunately my source is a GigEVision stream which then gets decoded to a RGB Frame, which I then encode with FFMPEG then send off to Live555 for RTSP streaming. I think your answer is right but it doesn't solve my overall problem. – ALM865 Dec 12 '13 at 03:27
  • Then use pipes. Get ffmpeg to write output to a pipe. Let live555 read from it. As long as ffmpeg is running on a fast enough server you should not starve! That allows you to do this without modifying ffmpeg or live555. – av501 Dec 12 '13 at 04:14