소스 검색

aja: Fix memory overrun on aja-source

When too many audio frames are captured and at the same time the ring
buffer on the card is wrapped, memory overrun was not captured before
DMA transfer, which resulted in corruption of memory contents. This
commit moves the overrun check before the DMA transfer.
Norihiro Kamae 3 년 전
부모
커밋
08a071d7a5
1개의 변경된 파일18개의 추가작업 그리고 11개의 파일을 삭제
  1. 18 11
      plugins/aja/aja-source.cpp

+ 18 - 11
plugins/aja/aja-source.cpp

@@ -293,11 +293,28 @@ void AJASource::CaptureThread(AJAThread *thread, void *data)
 				audioOverrun = true;
 			}
 
-			if (!audioOverrun) {
+			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<ULWord *>(
@@ -311,16 +328,6 @@ void AJASource::CaptureThread(AJAThread *thread, void *data)
 						     offsets.readOffset;
 			}
 
-			if (offsets.bytesRead >
-			    ajaSource->mAudioBuffer.GetByteCount()) {
-				blog(LOG_DEBUG,
-				     "AJASource::CaptureThread: Audio overrun (2)! Buffer Size: %d, Bytes Captured: %d",
-				     ajaSource->mAudioBuffer.GetByteCount(),
-				     offsets.bytesRead);
-				ResetAudioBufferOffsets(card, audioSystem,
-							offsets);
-				audioOverrun = true;
-			}
 		} else {
 			offsets.bytesRead =
 				offsets.currentAddress - offsets.lastAddress;