<div dir="ltr">"<font color="#212121">No, you don’t ‘set’ “</font>fTo<font color="#212121">” to point to the data; you *copy* the data to the address pointed to by “</font>fTo<font color="#212121">”"</font><br><br><font color="#212121">Yes, you are correct. I was using "</font>loosey<font color="#212121"> goosey" terminology here. </font>Specifically<font color="#212121">, I do something like this: </font><br><br><font color="#212121">memmove(fTo, nal.p_payload ......</font><br><div><font color="#212121"><br></font></div><div><font color="#212121">A bit more details on the crash I'm encountering. First, it's not really a "crash" in that the server dies. It appears to be a C++ exception that is being fired and handled somewhere (I get a notification of it in my development environment). But since my streaming server isn't streaming the file (according to VLC, no bytes are being received), I assume there's something wrong somewhere. This makes me suspicious of the fact I am NOT prepending the NAL units with 0x0 0x0 0x0 0x1 as you described. However, I'm a bit confused as to why my live streaming code is working, then, as I'm not explicitly doing that from within it. Here is the code that's popping a NAL unit off a queue I'm building and writing it onto fTo. This is for my LIVE streaming server and it's working just fine and is in production. I found the code for doing the "truncation" business online and it's worked great for us; admittedly I didn't understand it too well. </font></div><div><font color="#212121"><br></font></div><div><font color="#212121">......<br><br><div>    x264_nal_t nal = this->_nalQueue.front();</div><div>    this->_nalQueue.pop();</div><div>    assert(nal.p_payload != NULL);</div><div>    // You need to remove the start code which is there in front of every nal unit.</div><div>    // the start code might be 0x00000001 or 0x000001. so detect it and remove it. pass remaining data to live555</div><div>    int trancate = 0;</div><div>    if (nal.i_payload >= 4 && nal.p_payload[0] == 0 && nal.p_payload[1] == 0 && nal.p_payload[2] == 0 && nal.p_payload[3] == 1)</div><div>    {</div><div>        trancate = 4;</div><div>    }</div><div>    else</div><div>    {</div><div>        if (nal.i_payload >= 3 && nal.p_payload[0] == 0 && nal.p_payload[1] == 0 && nal.p_payload[2] == 1)</div><div>        {</div><div>            trancate = 3;</div><div>        }</div><div>    }</div><div><br></div><div>    if (nal.i_payload - trancate > fMaxSize)</div><div>    {</div><div>        fFrameSize = fMaxSize;</div><div>        fNumTruncatedBytes = nal.i_payload - trancate - fMaxSize;</div><div>    }</div><div>    else</div><div>    {</div><div>        fFrameSize = nal.i_payload - trancate;</div><div>    }</div><div>    //<a href="http://comments.gmane.org/gmane.comp.multimedia.live555.devel/4930">http://comments.gmane.org/gmane.comp.multimedia.live555.devel/4930</a></div><div>    //<a href="http://stackoverflow.com/questions/13863673/how-to-write-a-live555-framedsource-to-allow-me-to-stream-h-264-live">http://stackoverflow.com/questions/13863673/how-to-write-a-live555-framedsource-to-allow-me-to-stream-h-264-live</a></div><div>    timeval lastPresentationTime = fPresentationTime;</div><div>    fPresentationTime = this->_time;</div><div>    if (newData)</div><div>    {</div><div>        fDurationInMicroseconds = 1000000 / m_fps; // 66000;</div><div>    }</div><div>    else</div><div>    {</div><div>        fDurationInMicroseconds = 0;</div><div>    }</div><div>    memmove(fTo, nal.p_payload + trancate, fFrameSize);</div><div><br></div><div>.....</div><div><br>And this is the stack for the exception that does occur (again, this exception DOES NOT happen in the live streaming code, only when trying to stream a static file). As you can see, it's within the call to getAuxSDPLine.  I notice "test4Bytes" which makes me think it's related to this prepending of 0x0 0x0 0x0 0x1? </div><div><br><div> <span class="Apple-tab-span" style="white-space:pre">   </span>ManagedStreamingServerLibrary.dll!StreamParser::ensureValidBytes1(unsigned int)<span class="Apple-tab-span" style="white-space:pre">     </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!StreamParser::ensureValidBytes(unsigned int)<span class="Apple-tab-span" style="white-space:pre">      </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!StreamParser::test4Bytes(void)<span class="Apple-tab-span" style="white-space:pre">    </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!H264or5VideoStreamParser::parse(void)<span class="Apple-tab-span" style="white-space:pre">     </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!MPEGVideoStreamFramer::continueReadProcessing(void)<span class="Apple-tab-span" style="white-space:pre">       </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!MPEGVideoStreamFramer::doGetNextFrame(void)<span class="Apple-tab-span" style="white-space:pre">       </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!FramedSource::getNextFrame(unsigned char *,unsigned int,void (*)(void *,unsigned int,unsigned int,struct timeval,unsigned int),void *,void (*)(void *),void *)<span class="Apple-tab-span" style="white-space:pre">    </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!H264or5Fragmenter::doGetNextFrame(void)<span class="Apple-tab-span" style="white-space:pre">   </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!FramedSource::getNextFrame(unsigned char *,unsigned int,void (*)(void *,unsigned int,unsigned int,struct timeval,unsigned int),void *,void (*)(void *),void *)<span class="Apple-tab-span" style="white-space:pre">    </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!MultiFramedRTPSink::packFrame(void)<span class="Apple-tab-span" style="white-space:pre">       </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!MultiFramedRTPSink::buildAndSendPacket(bool)<span class="Apple-tab-span" style="white-space:pre">      </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!MultiFramedRTPSink::continuePlaying(void)<span class="Apple-tab-span" style="white-space:pre"> </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!H264or5VideoRTPSink::continuePlaying(void)<span class="Apple-tab-span" style="white-space:pre">        </span>C++</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>ManagedStreamingServerLibrary.dll!MediaSink::startPlaying(class MediaSource &,void (*)(void *),void *)<span class="Apple-tab-span" style="white-space:pre">  </span>C++</div><div>><span class="Apple-tab-span" style="white-space:pre">      </span>ManagedStreamingServerLibrary.dll!OCVFileServerMediaSubsession::getAuxSDPLine(RTPSink * rtpSink, FramedSource * inputSource) Line 99<span class="Apple-tab-span" style="white-space:pre">        </span>C++</div></div><div><br></div><div><br></div><div>At any rate, I tried modifying the code that moves the data to fTo to include 0x0 0x0 0x0 0x1 and I'm still seeing these exceptions. <br><br><div><div>        fFrameSize += 4;</div><div><br></div><div>        fTo[0] = 0x0;</div><div>        fTo[1] = 0x0;</div><div>        fTo[2] = 0x0;</div><div>        fTo[3] = 0x1;</div><div><br></div><div>        memmove(fTo + 4, nal.p_payload + trancate, fFrameSize);<br><br>Any thoughts? Something is wonky, but I'm having a helluva time tracking it down. </div></div></div></font></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Apr 6, 2017 at 3:02 PM Ross Finlayson <<a href="mailto:finlayson@live555.com">finlayson@live555.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> FramedSource* OCVFileServerMediaSubsession::createNewStreamSource(unsigned /*clientSessionId*/, unsigned& estBitrate) {<br class="gmail_msg">
>     estBitrate = 90000; // kbps, estimate<br class="gmail_msg">
><br class="gmail_msg">
>     // Create the video source:<br class="gmail_msg">
>     {<br class="gmail_msg">
>         std::ifstream in(fFileName, std::ifstream::ate | std::ifstream::binary);<br class="gmail_msg">
>         fFileSize = in.tellg();<br class="gmail_msg">
>     }<br class="gmail_msg">
><br class="gmail_msg">
>     OCVFileSource* fileSource = OCVFileSource::createNew(envir(), fFileName);<br class="gmail_msg">
>     if (fileSource == NULL) return NULL;<br class="gmail_msg">
><br class="gmail_msg">
>     // Create a framer for the Video Elementary Stream:<br class="gmail_msg">
>     return H264VideoStreamFramer::createNew(envir(), fileSource);<br class="gmail_msg">
> }<br class="gmail_msg">
<br class="gmail_msg">
This is correct, *provided that* your “OCVFileSource” delivers a stream of H.264 NAL units, each prepended with a 4-byte ‘start code’ (0x00 0x00 0x00 0x01).  (That’s because the downstream ‘framer’ object - “H264VideoStreamFramer” - expects a stream of NAL units in this format.)<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
> Then within OCVFileSource::doGetNextFrame() I use our own special file reader to get a frame from the OCV file and I use lib x264 to encode it into a group of NAL units (much like I do with our live camera solution).<br class="gmail_msg">
<br class="gmail_msg">
Again, each NAL unit in this ‘group of NAL units’ needs to be prepended with a (0x00 0x00 0x00 0x01) ‘start code’.<br class="gmail_msg">
<br class="gmail_msg">
> I then set "fTo" with the encoded data<br class="gmail_msg">
<br class="gmail_msg">
No, you don’t ‘set’ “fTo” to point to the data; you *copy* the data to the address pointed to by “fTo”.  You should also check the size of the data against “fMaxSize” (and then set “fFrameSize” and “fNumTruncatedBytes” as appropriate).<br class="gmail_msg">
<br class="gmail_msg">
I.e., you do something like this:<br class="gmail_msg">
        if (myDataSize > fMaxSize) {<br class="gmail_msg">
                fFrameSize = fMaxSize;<br class="gmail_msg">
                fNumTruncatedBytes = newFrameSize - fMaxSize;<br class="gmail_msg">
        } else {<br class="gmail_msg">
                fFrameSize = myDataSize;<br class="gmail_msg">
        }<br class="gmail_msg">
        memmove(fTo, myDataPointer, fFrameSize);<br class="gmail_msg">
<br class="gmail_msg">
Note that, in your case, you don’t need to set “fPresentationTime” or “fDurationInMicroseconds”; those will be computed by the downstream “H264VideoStreamFramer” object instead.<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
> and call<br class="gmail_msg">
><br class="gmail_msg">
>  nextTask() = envir().taskScheduler().scheduleDelayedTask(0,<br class="gmail_msg">
>         (TaskFunc*)FramedSource::afterGetting, this);<br class="gmail_msg">
><br class="gmail_msg">
> to reschedule another call to doGetNextFrame().<br class="gmail_msg">
<br class="gmail_msg">
This will work.  However, in your case you could replace this with:<br class="gmail_msg">
        FramedSource::afterGetting(this);<br class="gmail_msg">
which is more efficient.  (You can do this because you’re streaming to a network, rather than to a file.  The downstream ‘RTPSink’ object will - after transmitting a RTP packet - return to the event loop, so you won’t get infinite recursion.)<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Ross Finlayson<br class="gmail_msg">
Live Networks, Inc.<br class="gmail_msg">
<a href="http://www.live555.com/" rel="noreferrer" class="gmail_msg" target="_blank">http://www.live555.com/</a><br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
live-devel mailing list<br class="gmail_msg">
<a href="mailto:live-devel@lists.live555.com" class="gmail_msg" target="_blank">live-devel@lists.live555.com</a><br class="gmail_msg">
<a href="http://lists.live555.com/mailman/listinfo/live-devel" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.live555.com/mailman/listinfo/live-devel</a><br class="gmail_msg">
</blockquote></div>