<div dir="ltr">Ross, <br><br>Thanks for the swift response. As it happens, I am using a discrete framer for just this reason (in hopes it'd make synchronization easier). Here is the implementation of my createNewStreamSource: <br><br><div>FramedSource* H264LiveServerMediaSession::createNewStreamSource(unsigned clientSessionID, unsigned& estBitRate)</div><div>{</div><div>    estBitRate = 90000;</div><div>    SimpleFramedSource *source = SimpleFramedSource::createNew(envir());</div><div>    return H264VideoStreamDiscreteFramer::createNew(envir(), source);</div><div>}<br><br>So as to be clear, I'm not doubting your intuition on this (as you wrote the darn thing, you obviously know more than I), but I still don't understand why the SERVER itself is calling my AudioInputDevice less frequently once the video is enabled. I expected it to call the audio and video at the same rate as when each is enabled individually. <br><br>Here is doGetNextFrame on my video source (cout statements are there for debugging this issue): <br><br><div>void SimpleFramedSource::doGetNextFrame()</div><div>{</div><div>    std::cout << "-"; </div><div>    long currentTickCount = ::GetTickCount();</div><div><br></div><div>    _lastTickCount = currentTickCount;</div><div><br></div><div>    if (this->_nalQueue.empty())</div><div>    {</div><div>        // get a frame of data, encode, and enqueue it. </div><div>        this->GetFrameAndEncodeToNALUnitsAndEnqueue();</div><div>        // get time of day for the broadcaster</div><div><br></div><div>        ::gettimeofday(&_time, NULL);</div><div><br></div><div>        // take the nal units and push them to live 555. </div><div>        this->DeliverNALUnitsToLive555FromQueue(true);</div><div>    }</div><div>    else</div><div>    {</div><div>        // there's already stuff to deliver, so just deliver it. </div><div>        this->DeliverNALUnitsToLive555FromQueue(false);</div><div>    }</div><div>}</div></div><div><br></div><div>And here it is on my audio source: <br><br><div>void WindowsAudioInputDevice_common::doGetNextFrame() {</div><div>    std::cout << "<"; </div><div><br></div><div>    if (!fHaveStarted) {</div><div>        // Before reading the first audio data, flush any existing data:</div><div>        while (readHead != NULL) releaseHeadBuffer();</div><div>        fHaveStarted = True;</div><div>    }</div><div>    fTotalPollingDelay = 0;</div><div><br></div><div>    audioReadyPoller1();</div><div>    std::cout << ">";</div><div>}</div></div><div><br></div>By the way, off topic (and I don't know if you care to know), but I had to fix something in your waveInCallback method (in WindowsAudioInputDevice_common). The callback method needs to have DWORD parameters changed to DWORD_PTR to support 64-bit Windows. <br><br><div>static void CALLBACK waveInCallback(HWAVEIN /*hwi*/, UINT uMsg,</div><div>    DWORD_PTR /*dwInstance*/, DWORD_PTR dwParam1, DWORD_PTR /*dwParam2*/) {</div><div>    switch (uMsg) {</div><div>    case WIM_DATA:</div><div>        WAVEHDR* hdr = (WAVEHDR*)dwParam1;</div><div>        WindowsAudioInputDevice_common::waveInProc(hdr);</div><div>        break;</div><div>    }</div><div>}</div><div><br><br>The call stack was being messed up and dwParam1 was pointing to garbage otherwise. </div><br></div><br><div class="gmail_quote"><div dir="ltr">On Sat, Feb 6, 2016 at 3:30 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">> I have seen from reading the lists that care must be taken to ensure the timing is correct between the two streams<br>
<br>
Yes.  Problems like this are usually caused by not setting proper “fPresentationTime” values in your (video and audio) “OnDemandServerMediaSubsession” subclasses (when you deliver each frame).<br>
<br>
You should also read<br>
        <a href="http://lists.live555.com/pipermail/live-devel/2016-January/019856.html" rel="noreferrer" target="_blank">http://lists.live555.com/pipermail/live-devel/2016-January/019856.html</a><br>
<br>
If your H.264 video source is coming from a byte stream (i.e., you’re using “H264VideoStreamFramer” rather than “H264VideoStreamDiscreteFramer”), then you can’t expect to get good audio/video synchronization, because the H.264 video stream parsing code can’t give you accurate presentation times (it can only give you accurate presentation times relative to the rest of the video stream).  Instead, you’ll need to use a “H264VideoStreamDiscreteFramer”, and set accurate presentation times when you deliver H.264 NAL units to it.<br>
<br>
<br>
Ross Finlayson<br>
Live Networks, Inc.<br>
<a href="http://www.live555.com/" rel="noreferrer" target="_blank">http://www.live555.com/</a><br>
<br>
<br>
_______________________________________________<br>
live-devel mailing list<br>
<a href="mailto:live-devel@lists.live555.com" target="_blank">live-devel@lists.live555.com</a><br>
<a href="http://lists.live555.com/mailman/listinfo/live-devel" rel="noreferrer" target="_blank">http://lists.live555.com/mailman/listinfo/live-devel</a><br>
</blockquote></div>