[MPlayer-dev-eng] [PATCH] fix frame buffer size in libmpdemux/demux_rtp.cpp

Spectr spectr at gmail.com
Wed Jan 17 21:15:30 CET 2007


Hello.

I work in Elphel, Inc - we make network video cameras with high resolution,
what send video in RTP MJPEG stream. I try MPlayer RC1 with latest our
camera, and use official build from latest Ubuntu release, what have live555
library in his build. All work very good, but limitation of frame size in
50KB make broken images in video stream.
Simple solution - increase this constant in
libmpdemux/demux_rtp.cpp
from
#define MAX_RTP_FRAME_SIZE 50000
to
#define MAX_RTP_FRAME_SIZE 5000000
- but it's not good for all situation, because this frame buffer size not
small for work with other video streams.

So, i try solve this problem with this patch, and ask about add this code in
MPlayer repository - and wait what in next builds of MPlayer this problem be
solved.

About path - i add frame size variable, what set by default in 65535 (i use
all time power of 2 in buffer size, because it's better memory usage for
system memory allocator); and after this - check next frames - if frame size
(really, frame size and half of this - for prevent broken frames if image
size in stream can increase by change complexity of scene, for example) is
larger than current buffer size - increase buffer size to next near power of
two. And set upper frame size limit to 4Mb. With this algorithm we have
first frame of videostream broken - but this is limitation of live555
library.

So, this is patch (as output of "diff -Naur" for original and changed
files):

--- demux_rtp.cpp.original      2006-10-23 01:32:31.000000000 +0300
+++ demux_rtp.cpp       2007-01-15 23:30:04.000000000 +0200
@@ -384,16 +384,26 @@

 ////////// Extra routines that help implement the above interface
functions:

-#define MAX_RTP_FRAME_SIZE 50000
+#define MAX_RTP_FRAME_SIZE 4194304
     // >= the largest conceivable frame composed from one or more RTP
packets
+unsigned long rtp_frame_size = 65536;

 static void afterReading(void* clientData, unsigned frameSize,
-                        unsigned /*numTruncatedBytes*/,
+                        unsigned truncSize/*numTruncatedBytes*/,
                         struct timeval presentationTime,
                         unsigned /*durationInMicroseconds*/) {
-  if (frameSize >= MAX_RTP_FRAME_SIZE) {
-    fprintf(stderr, "Saw an input frame too large (>=%d).  Increase
MAX_RTP_FRAME_SIZE in \"demux_rtp.cpp\".\n",
-           MAX_RTP_FRAME_SIZE);
+  int size = frameSize + truncSize;
+  size += size / 2;
+  if (size > rtp_frame_size) {
+    int i;
+    int j = size - 1;
+    for(i = 0; j >>= 1; i++);
+    rtp_frame_size = 1 << (i + 1);
+    if(rtp_frame_size > MAX_RTP_FRAME_SIZE) {
+      fprintf(stderr, "Saw an input frame too large (>=%d).  Increase
MAX_RTP_FRAME_SIZE in \"demux_rtp.cpp\".\n",
+            MAX_RTP_FRAME_SIZE);
+      rtp_frame_size = MAX_RTP_FRAME_SIZE;
+    }
   }
   ReadBufferQueue* bufferQueue = (ReadBufferQueue*)clientData;
   demuxer_t* demuxer = bufferQueue->ourDemuxer();
@@ -486,13 +496,13 @@
   }

   // Allocate a new packet buffer, and arrange to read into it:
-  dp = new_demux_packet(MAX_RTP_FRAME_SIZE);
+  dp = new_demux_packet(rtp_frame_size);
   bufferQueue->dp = dp;
   if (dp == NULL) return NULL;

   // Schedule the read operation:
   bufferQueue->blockingFlag = 0;
-  bufferQueue->readSource()->getNextFrame(dp->buffer, MAX_RTP_FRAME_SIZE,
+  bufferQueue->readSource()->getNextFrame(dp->buffer, rtp_frame_size,
                                          afterReading, bufferQueue,
                                          onSourceClosure, bufferQueue);
   // Block ourselves until data becomes available:

-- 
With best regards, Spectr.



More information about the MPlayer-dev-eng mailing list