<div dir="ltr"><div><div><div><div>Hello.<br></div>I`m implementing low-latency h264 rtsp source. Based on this code<br><a href="http://stackoverflow.com/questions/13863673/how-to-write-a-live555-framedsource-to-allow-me-to-stream-h-264-live" target="_blank">http://stackoverflow.com/questions/13863673/how-to-write-a-live555-framedsource-to-allow-me-to-stream-h-264-live</a> <br>
</div>I wrote subclass of FramedSource and able to watch this stream in my client app. But even if I put 1 frame per second setting in x264 codec, I have exactly one frame-delayed data in my client. This delay is 100% on server side, because MultiFramedRTPSink::sendPacketIfNecessary() sending compressed data of previous frame (i just compare first several bytes of data in fOutBuf with those I wrote in fTo).<br>
</div><br>What can I do to send rtp packets immediately after filling fTo buffer?<br><br></div>Here is my deliverFrame implementation:<br><br><br>void H264FramedSource::deliverFrame()<br>{<br> if(nals_count==0)<br> {<br>
clr=clr+1;<br> if(clr==25) clr = 0;<br> envir() << "color=\t"<<clr<<"\r\n" ;<br> memset(frame_buf, 0, W*H*3);<br> for(int i=0; i<clr; i++) memset(&frame_buf[W*3*i*23], 200, W*11*3);<br>
AddToBuffer(frame_buf, W*H*3);<br> }<br> x264_nal_t nalToDeliver;<br><br> if (fPlayTimePerFrame > 0 && fPreferredFrameSize > 0) {<br> if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) {<br>
// This is the first frame, so use the current time:<br> gettimeofday(&fPresentationTime, NULL);<br> } else {<br> // Increment by the play time of the previous data:<br> unsigned uSeconds = fPresentationTime.tv_usec + fLastPlayTime;<br>
fPresentationTime.tv_sec += uSeconds/1000000;<br> fPresentationTime.tv_usec = uSeconds%1000000;<br> }<br><br> // Remember the play time of this data:<br> fLastPlayTime = (fPlayTimePerFrame*fFrameSize)/fPreferredFrameSize;<br>
fDurationInMicroseconds = fLastPlayTime;<br> } else {<br> // We don't know a specific play time duration for this data,<br> // so just record the current time as being the 'presentation time':<br>
gettimeofday(&fPresentationTime, NULL);<br> }<br><br>fPresentationTime.tv_usec;<br><br> if(nals_count>0)//!m_queue.empty())<br> {<br> nalToDeliver = nals_queue[nal_num];<br><br> uint8_t* newFrameDataStart = (uint8_t*)0xD15EA5E;<br>
<br> newFrameDataStart = (uint8_t*)(nalToDeliver.p_payload);<br> unsigned newFrameSize = nalToDeliver.i_payload;<br><br> nal_num++;<br> nals_count--;<br> // Deliver the data here:<br> if (newFrameSize > fMaxSize) {<br>
fFrameSize = fMaxSize;<br> fNumTruncatedBytes = newFrameSize - fMaxSize;<br> envir() << "truncate!!!\r\n" << fNumTruncatedBytes << "\r\n";<br> }<br>
else {<br> fFrameSize = newFrameSize;<br> }<br><br> memcpy(fTo, nalToDeliver.p_payload, fFrameSize);<br> <br> if(nals_count==0) nal_num=0;<br> nextTask() = envir().taskScheduler().scheduleDelayedTask(0,<br>
(TaskFunc*)FramedSource::afterGetting, this);<br><br><br> }else{<br> nal_num = 0;<br> }<br> <br>}<br></div>