From a8d74197325f61ea87befeb780448f231631dde5 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Fri, 3 Mar 2017 16:58:42 -0800 Subject: [PATCH] win-dshow: Actually fix LGP issue The LGP issue is caused by the device drivers returning two or more packets in a single segment of audio data. This fixes it by detecting that and decoding subsequent packets. When the FFmpeg audio decoder returns, it returns how many bytes of data was decoded. To have it decode multiple packets in a single segment, just subtract the return value from the expected size, and if that size is still larger than zero, then there are more packets in the segment to decode. Otherwise, stop. --- plugins/win-dshow/win-dshow.cpp | 34 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/plugins/win-dshow/win-dshow.cpp b/plugins/win-dshow/win-dshow.cpp index 344745de0..3b3d3a2d2 100644 --- a/plugins/win-dshow/win-dshow.cpp +++ b/plugins/win-dshow/win-dshow.cpp @@ -116,6 +116,7 @@ public: inline ~Decoder() {ffmpeg_decode_free(&decode);} inline operator ffmpeg_decode*() {return &decode;} + inline ffmpeg_decode *operator->() {return &decode;} }; class CriticalSection { @@ -509,21 +510,30 @@ void DShowInput::OnEncodedAudioData(enum AVCodecID id, } } - bool got_output; - int len = ffmpeg_decode_audio(audio_decoder, data, size, - &audio, &got_output); - if (len < 0) { - blog(LOG_WARNING, "Error decoding audio"); - return; - } + do { + bool got_output; + int len = ffmpeg_decode_audio(audio_decoder, data, size, + &audio, &got_output); + if (len < 0) { + blog(LOG_WARNING, "Error decoding audio"); + return; + } - if (got_output) { - audio.timestamp = (uint64_t)ts * 100; + if (got_output) { + audio.timestamp = (uint64_t)ts * 100; #if LOG_ENCODED_AUDIO_TS - blog(LOG_DEBUG, "audio ts: %llu", audio.timestamp); + blog(LOG_DEBUG, "audio ts: %llu", audio.timestamp); #endif - obs_source_output_audio(source, &audio); - } + obs_source_output_audio(source, &audio); + } else { + break; + } + + ts += int64_t(audio_decoder->frame->nb_samples) * 10000000LL / + int64_t(audio_decoder->frame->sample_rate); + size -= (size_t)len; + data += len; + } while (size > 0); } void DShowInput::OnAudioData(const AudioConfig &config,