diff --git a/plugins/aja/aja-source.cpp b/plugins/aja/aja-source.cpp index 447207ac4..3ef074d35 100644 --- a/plugins/aja/aja-source.cpp +++ b/plugins/aja/aja-source.cpp @@ -40,8 +40,8 @@ AJASource::~AJASource() mTestPattern.clear(); mVideoBuffer.Deallocate(); mAudioBuffer.Deallocate(); - mVideoBuffer = NULL; - mAudioBuffer = NULL; + mVideoBuffer = 0; + mAudioBuffer = 0; } void AJASource::SetCard(CNTV2Card *card) @@ -184,6 +184,64 @@ static inline uint64_t get_sample_time(size_t frames, uint_fast32_t rate) return os_gettime_ns() - samples_to_ns(frames, rate); } +static bool CheckTransferAudioDMA(CNTV2Card *card, + const NTV2AudioSystem audioSystem, + void *buffer, ULWord bufferSize, + ULWord dmaOffset, ULWord dmaSize, + const char *log_id) +{ + if (dmaSize > bufferSize) { + blog(LOG_DEBUG, + "AJASource::CaptureThread: Audio overrun %s! Buffer Size: %u, Bytes Captured: %u", + log_id, bufferSize, dmaSize); + return false; + } + + card->DMAReadAudio(audioSystem, (ULWord *)buffer, dmaOffset, dmaSize); + return true; +} + +static inline bool TransferAudio(CNTV2Card *card, + const NTV2AudioSystem audioSystem, + NTV2_POINTER &audioBuffer, + AudioOffsets &offsets) +{ + card->ReadAudioLastIn(offsets.currentAddress, audioSystem); + offsets.currentAddress += 1; + offsets.currentAddress += offsets.readOffset; + + if (offsets.currentAddress < offsets.lastAddress) { + offsets.bytesRead = offsets.wrapAddress - offsets.lastAddress; + + if (!CheckTransferAudioDMA(card, audioSystem, audioBuffer, + audioBuffer.GetByteCount(), + offsets.lastAddress, + offsets.bytesRead, "(1)")) + return false; + + if (!CheckTransferAudioDMA( + card, audioSystem, + audioBuffer.GetHostAddress(offsets.bytesRead), + audioBuffer.GetByteCount() - offsets.bytesRead, + offsets.readOffset, + offsets.currentAddress - offsets.readOffset, "(2)")) + return false; + offsets.bytesRead += + offsets.currentAddress - offsets.readOffset; + + } else { + offsets.bytesRead = + offsets.currentAddress - offsets.lastAddress; + if (!CheckTransferAudioDMA(card, audioSystem, audioBuffer, + audioBuffer.GetByteCount(), + offsets.lastAddress, + offsets.bytesRead, "(3)")) + return false; + } + + return true; +} + void AJASource::CaptureThread(AJAThread *thread, void *data) { UNUSED_PARAMETER(thread); @@ -242,7 +300,6 @@ void AJASource::CaptureThread(AJAThread *thread, void *data) auto videoFormat = sourceProps.videoFormat; auto pixelFormat = sourceProps.pixelFormat; auto ioSelection = sourceProps.ioSelect; - bool audioOverrun = false; card->WaitForInputFieldID(NTV2_FIELD0, channel); currentCardFrame ^= 1; @@ -275,81 +332,10 @@ void AJASource::CaptureThread(AJAThread *thread, void *data) break; } - card->ReadAudioLastIn(offsets.currentAddress, audioSystem); - offsets.currentAddress += 1; - offsets.currentAddress += offsets.readOffset; - if (offsets.currentAddress < offsets.lastAddress) { - offsets.bytesRead = - offsets.wrapAddress - offsets.lastAddress; - - if (offsets.bytesRead > - ajaSource->mAudioBuffer.GetByteCount()) { - blog(LOG_DEBUG, - "AJASource::CaptureThread: Audio overrun (1)! Buffer Size: %d, Bytes Captured: %d", - ajaSource->mAudioBuffer.GetByteCount(), - offsets.bytesRead); - ResetAudioBufferOffsets(card, audioSystem, - offsets); - audioOverrun = true; - } - - if (!audioOverrun) - card->DMAReadAudio(audioSystem, - ajaSource->mAudioBuffer, - offsets.lastAddress, - offsets.bytesRead); - - if (!audioOverrun && - offsets.currentAddress - offsets.readOffset > - ajaSource->mAudioBuffer.GetByteCount() - - offsets.bytesRead) { - blog(LOG_DEBUG, - "AJASource::CaptureThread: Audio overrun (2)! Buffer Size: %d, Bytes Captured: %d", - ajaSource->mAudioBuffer.GetByteCount() - - offsets.bytesRead, - offsets.currentAddress - - offsets.readOffset); - ResetAudioBufferOffsets(card, audioSystem, - offsets); - audioOverrun = true; - } - - if (!audioOverrun) { - card->DMAReadAudio( - audioSystem, - reinterpret_cast( - ajaSource->mAudioBuffer - .GetHostAddress( - offsets.bytesRead)), - offsets.readOffset, - offsets.currentAddress - - offsets.readOffset); - offsets.bytesRead += offsets.currentAddress - - offsets.readOffset; - } - + if (!TransferAudio(card, audioSystem, ajaSource->mAudioBuffer, + offsets)) { + ResetAudioBufferOffsets(card, audioSystem, offsets); } else { - offsets.bytesRead = - offsets.currentAddress - offsets.lastAddress; - if (offsets.bytesRead > - ajaSource->mAudioBuffer.GetByteCount()) { - blog(LOG_DEBUG, - "AJASource::CaptureThread: Audio overrun (3)! Buffer Size: %d, Bytes Captured: %d", - ajaSource->mAudioBuffer.GetByteCount(), - offsets.bytesRead); - ResetAudioBufferOffsets(card, audioSystem, - offsets); - audioOverrun = true; - } - if (!audioOverrun) { - card->DMAReadAudio(audioSystem, - ajaSource->mAudioBuffer, - offsets.lastAddress, - offsets.bytesRead); - } - } - - if (!audioOverrun) { offsets.lastAddress = offsets.currentAddress; obs_source_audio audioPacket; audioPacket.samples_per_sec = 48000; @@ -819,8 +805,8 @@ void aja_source_destroy(void *data) ajaSource->mVideoBuffer.Deallocate(); ajaSource->mAudioBuffer.Deallocate(); - ajaSource->mVideoBuffer = NULL; - ajaSource->mAudioBuffer = NULL; + ajaSource->mVideoBuffer = 0; + ajaSource->mAudioBuffer = 0; auto &cardManager = aja::CardManager::Instance(); const auto &cardID = ajaSource->CardID();