2013-01-21 3 views
1

RTP 수신기를 구현 중입니다. UDP 패킷을 수신하고, 코덱을 디코드하고, 재생을 위해 AudioTrack에 PCM 샘플을 씁니다. 문제가있는 것 같습니다, 그 AudioTrack.write 차단하고 같은 UDP 패킷을 놓치지 그 동안.AudioTrack에서 비 차단 데이터 재생

이 문제를 해결하는 방법에 대한 알려진 해결책이 있습니까?

오디오 데이터와 setNotificationMarkerPosition에 대해 자체 버퍼를 사용하려고했지만 audioTrack이 버퍼가 어느 정도 채워지면 마커 위치에 도달하지 못하거나 audioTrack.write이 다시 블로킹되는 것처럼 보입니다.

또한 각 쓰기 전에 audioTrack.pause()을 시도한 다음 다시 .play()을 시도했지만 음질에 현저한 영향을 미치는 것 같습니다.

답변

3

내가 문제를 해결했는지 여부는 알 수 없지만 몇 가지 문제가 있습니다. 내가 할 수있는 최선의 방법은 스레드의 UDP 패킷을 ArrayBlockingQueue (ABQ)로 가져와 ABQ에서 하나씩 가져 오는 다른 스레드에서 재생하는 것입니다. 그러나 이번에는 (모든 장치가 아닌 일부 장치는 이중 스레드로 시원함) 고생하고 ABQ의 크기가 커지면 지연이 증가합니다. 따라서 지연을 줄이기 위해 크기를 확인하고 일부 패킷을 체계적으로 (간단히 AudioTrack에 기록하지 않음) 드롭합니다. 그러나 지연이 있으면 괜찮습니다.

한가지 더, 나는 같은 스레드의 우선 순위를 증가하고있다 : 더 나은 속도를 제공

private class Player extends Thread { 
    public void run() { 
    Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO); 
     .... 
    } 
} 

합니다.

솔루션은 여전히 ​​차단되지만 UDP 패킷은 용량에 따라 ABQ 크기가 증가 할 때까지 플레이어에 의해 차단되지 않습니다.

+0

저는 실제로 비슷한 솔루션을 사용하고 있습니다. audioData에 대한 수동 링 버퍼가 있습니다. 하나의 스레드가 그것을 읽고 그것을 재생, 다른 스레드는 그것에 씁니다. 가득 차면 패킷이 삭제됩니다. 아직 완벽한 것은 아니지만 지금은 괜찮습니다. – rumpel

+0

필자가 쓰레드를 쓰러 뜨리면 지연 시간은 ringbuffer의 크기에 달려 있다고 생각합니다. 문제가 발생하면 다음과 같이 삭제됩니다. *가 괜찮을 경우 _을 버려야합니다. ************* ___________ ********* 대신 패킷 삭제를 사용하는 경우 플레이어 측에서 이번에는 뭔가를 얻을 것입니다 : ****** _ * _ ** _ * _ * _ ** _ ****** 더 귀에 좋고 또한 딜레이가 더 좋고 실제로는 아닙니다. ringbuffer의 크기에 따라 다릅니다. 마지막으로 삭제할 때, 전체 패킷을 삭제할 필요가 없습니다. 패킷을 8로 나누고, 버퍼가 양호하면 삭제합니다. 버퍼가 너무 작 으면 2를 삭제하십시오. – guness

+0

그리고 버퍼가 실제로 손상되면 모두 삭제됩니다. 그 사이에 0에서 8로 변경하십시오. 더 나은 방법을 찾으면 그냥 알아둬야합니다. – guness

0

"버퍼 및 스레드 추가"솔루션보다 더 매력적인 솔루션이 있다고 생각합니다. 이 솔루션은 대기 시간에 민감한 시스템에 대기 시간을 추가합니다. 다음은 할 수있는 일입니다.

AudioTrack의 버퍼 크기에 유의하십시오. 그런 다음 마지막 X 밀리 초 동안 버퍼에 얼마나 많은 바이트가 기록되었는지 추적하십시오 (이것은 너무 계산적으로 강렬하지 않게 수행 할 수 있어야합니다). 여기서 X는 오디오에 들어갈 수있는 오디오의 밀리 초 수입니다. 버퍼 (버퍼 크기 및 샘플링 속도 및 양자화 속도 (비트/샘플) 및 채널 수에 기초한 간단한 계산). "버퍼 크기"의 데이터 양을 X 밀리 초 단위로 작성한 경우 오디오 패킷을 삭제해야합니다. 패킷 삭제는 "버퍼 및 스레드 추가"솔루션의 증상이기도합니다.

버퍼를 실제로 채울 수 없도록 작은 임계 값을 추가 할 수 있습니다 (버퍼가 실제 크기보다 조금 작다고 가정).

행운을 빈다.