<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I'm using the DarwinInjector class to stream JPEG to our server. (Yes, I know -- we ultimately don't plan to use JPEG but it lets us get the framework in place quickly.) I have no trouble sending JPEG frames of ~10K (plus or minus 2K) but when sending higher resolution frames (480x360) of ~40K we see a lot of image corruption starting about halfway through the image that looks very much like what I'd expect from a buffer being overwritten before its prior contents had been sent. Strangely, this doesn't appear related to frame rate. If I limit my video source to only produce a frame per second, I get the same results.<div><br></div><div>I've attached my JpegCaptureDeviceSource class which provides the JPEGVideoSource implementation for my video source. It's heavily based on the ElphelJPEGDeviceSource sample but since our video source doesn't provide a pull mechanism, I added two new public methods for it to provide data to JpegCaptureDeviceSource. The gotAFrame() method provides the image data and JPEG quality. The close() method tells it that the source won't provide more data. It's using the Live 555 event mechanism to trigger our task scheduler to deliver the frame. The only other change from Elphel is that we need to pull the quantization tables from the JPEG header.</div><div><br></div><div>Our video capture code (which we already had and works great in our existing product) runs on its own thread, captures an image in JPEG format and calls JpegCaptureDeviceSource::gotAFrame(). It also passes in a frameObj which contains state data about the frame. It then waits and doesn't provide another frame until JpegCaptureDeviceSource::deliverFrameToClient() calls doneWithFrame() with that same frameObj. This makes me somewhat confident that there are no buffer overwrites on our end. By time we start capturing another frame, we've already copied the image data into the fTo buffer in FramedSource.</div><div><br></div><div>Here's the code that sets up the DarwinInjector, source, and sink. (If the syntax looks strange it's because it's Objective-C++ which we are using as a thin interface layer between our Objective-C application and the Live555 C++ code.) Obviously, this runs on its own thread.</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// create Darwin injector</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(84, 128, 135); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #6e36aa">DarwinInjector</span><span style="color: #000000"> * injector = </span><span style="color: #6e36aa">DarwinInjector</span><span style="color: #000000">::</span><span style="color: #3d1381">createNew</span><span style="color: #000000">(*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>rtspEnvironment<span style="color: #000000">, </span>progName<span style="color: #000000">, </span>verbosityLevel<span style="color: #000000">);</span></div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// create video sink</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #b522a3">struct</span> <span style="color: #6e36aa">in_addr</span> dummyDestAddress;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>dummyDestAddress.<span style="color: #6e36aa">s_addr</span> = <span style="color: #2c0bd8">0</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #6e36aa">Groupsock</span> <span style="color: #3d1381">rtpGroupsockVideo</span>(*<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspEnvironment</span>, dummyDestAddress, <span style="color: #2c0bd8">0</span>, <span style="color: #2c0bd8">0</span>);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #6e36aa">Groupsock</span> <span style="color: #3d1381">rtcpGroupsockVideo</span>(*<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspEnvironment</span>, dummyDestAddress, <span style="color: #2c0bd8">0</span>, <span style="color: #2c0bd8">0</span>);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #b522a3">self</span>.<span style="color: #548087">videoSink</span> = <span style="color: #6e36aa">JPEGVideoRTPSink</span>::<span style="color: #3d1381">createNew</span>(*<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspEnvironment</span>, &rtpGroupsockVideo);</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// create video source</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(84, 128, 135); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>videoSource<span style="color: #000000"> = </span>JpegCaptureDeviceSource<span style="color: #000000">::</span><span style="color: #36595d">createNew</span><span style="color: #000000">(*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>rtspEnvironment<span style="color: #000000">);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(84, 128, 135); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #b522a3">if</span><span style="color: #000000"> (</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>videoSource<span style="color: #000000"> == </span><span style="color: #b522a3">NULL</span><span style="color: #000000">) </span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(202, 47, 35); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span>*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000"> << </span>"Unable to open video source: "<span style="color: #000000"> << </span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000">-></span><span style="color: #3d1381">getResultMsg</span><span style="color: #000000">() << </span>"\n"<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(54, 89, 93); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span>[</span><span style="color: #b522a3">self</span><span style="color: #000000"> </span>shutdownWithExitCode<span style="color: #000000">:</span><span style="color: #2c0bd8">1</span><span style="color: #000000">];</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(202, 47, 35); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span>*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000"> << </span>"Starting video capture device...\n"<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(84, 128, 135); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>videoSink<span style="color: #000000">-></span><span style="color: #3d1381">startPlaying</span><span style="color: #000000">(*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>videoSource<span style="color: #000000">, </span><span style="color: #36595d">afterPlaying</span><span style="color: #000000">, </span><span style="color: #b522a3">self</span><span style="color: #000000">.</span>videoSink<span style="color: #000000">);</span></div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// create rtcp channel</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #b522a3">const</span> <span style="color: #b522a3">unsigned</span> estimatedSessionBandwidthVideo = <span style="color: #2c0bd8">2000</span>; <span style="color: #1a8500">// in kbps; for RTCP b/w share</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #b522a3">const</span> <span style="color: #b522a3">unsigned</span> maxCNAMElen = <span style="color: #2c0bd8">100</span>;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #b522a3">unsigned</span> <span style="color: #b522a3">char</span> CNAME[maxCNAMElen+<span style="color: #2c0bd8">1</span>];</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #3d1381">gethostname</span>((<span style="color: #b522a3">char</span>*)CNAME, maxCNAMElen);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>CNAME[maxCNAMElen] = <span style="color: #2c0bd8">'\0'</span>; <span style="color: #1a8500">// just in case</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #6e36aa">RTCPInstance</span>* videoRTCP = <span style="color: #6e36aa">RTCPInstance</span>::<span style="color: #3d1381">createNew</span>(*<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspEnvironment</span>, &rtcpGroupsockVideo,</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>estimatedSessionBandwidthVideo, CNAME,</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #548087">videoSink</span>, <span style="color: #b522a3">NULL</span> <span style="color: #1a8500">/* we're a server */</span>);</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// connect rtp and rtcp channels to Darwin injector</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>injector-><span style="color: #3d1381">addStream</span>(<span style="color: #548087">videoSink</span>, videoRTCP);</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// connect to server and start streaming data</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(61, 19, 129); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #b522a3">if</span><span style="color: #000000"> (!injector-></span>setDestination<span style="color: #000000">([</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspServer</span><span style="color: #000000"> </span>UTF8String<span style="color: #000000">], </span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>[<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspFile</span> <span style="color: #3d1381">UTF8String</span>],</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><span style="color: #ca2f23">"Cannonball"</span>, </div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(202, 47, 35); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>"Cannonball live stream"<span style="color: #000000">)) </span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(202, 47, 35); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span>*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000"> << </span>"injector->setDestination() failed: "<span style="color: #000000"> << </span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000">-></span><span style="color: #3d1381">getResultMsg</span><span style="color: #000000">() << </span>"\n"<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(54, 89, 93); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span>[</span><span style="color: #b522a3">self</span><span style="color: #000000"> </span>shutdownWithExitCode<span style="color: #000000">:</span><span style="color: #2c0bd8">1</span><span style="color: #000000">];</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(181, 34, 163); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>return<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(202, 47, 35); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span>*</span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000"> << </span>"Play this stream (from the Darwin Streaming Server) using the URL:\n"</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "><span class="Apple-tab-span" style="white-space:pre"> </span><< <span style="color: #ca2f23">"\trtsp://"</span> << [<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspServer</span> <span style="color: #3d1381">UTF8String</span>] << <span style="color: #ca2f23">"/"</span> << [<span style="color: #b522a3">self</span>.<span style="color: #548087">rtspFile</span> <span style="color: #3d1381">UTF8String</span>] << <span style="color: #ca2f23">"\n"</span>;</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(26, 133, 0); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span>// never returns</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(61, 19, 129); "><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="color: #b522a3">self</span><span style="color: #000000">.</span><span style="color: #548087">rtspEnvironment</span><span style="color: #000000">-></span>taskScheduler<span style="color: #000000">().</span>doEventLoop<span style="color: #000000">();</span></div></div><div><span style="color: #000000"><br></span></div><div><span style="color: #000000">Any thoughts about what might be causing the issue we are seeing with streaming larger images? Is there something I need to configure to handle larger images, maybe on the sink (RTP) side?</span></div><div><span style="color: #000000"><br></span></div><div><span style="color: #000000">Thanks,</span></div><div><span style="color: #000000"><br></span></div><div><span style="color: #000000">Thomas Aylesworth</span></div><div><span style="color: #000000"><br></span></div><div></div></body></html>