Qt — Как отправить / получить RTP аудио поток (C ++)?

Извините, я плохо говорю по-английски.

Я сделал два проекта (QT, c ++, mingw32).

Это для отправки / получения аудиопотока с использованием RTP (ortp-0.20.0).

Но полученный звук искажен. (выходной звук искажается.)

Кто-нибудь может помочь?

RTPSend.cpp

#include <ortp/ortp.h>  // ortp-0.20.0

RtpSession *session;
unsigned char buffer[160];

#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

#define BS 8000
int sampleRate = 8000; // 8000, 11025, 16000, 22050, 24000, 32000, 44100
int NUMPTS = sampleRate * 10;  // 10 seconds
short int waveIn[BS];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
WAVEFORMATEX pFormat;

uint32_t user_ts = 0;void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
WAVEHDR *pHdr=NULL;
WAVEHDR pHdr2;
switch(uMsg)
{
case WIM_CLOSE:
cout << "waveInProc()... WIM_CLOSE" << endl;
break;

case WIM_DATA:
{
pHdr = (WAVEHDR *)dwParam1;
pHdr2.lpData = (LPSTR)pHdr->lpData;
pHdr2.dwBufferLength = pHdr->dwBufferLength;
pHdr2.dwBytesRecorded = pHdr->dwBytesRecorded;
pHdr2.dwUser = 0;
pHdr2.dwFlags = 0;
pHdr2.dwLoops = 0;

cout << "waveInProc()... WIM_DATA : " << "pHdr->dwBufferLength:" << pHdr->dwBufferLength << "  pHdr->dwBytesRecorded:" << pHdr->dwBytesRecorded<< endl;

int len = pHdr->dwBytesRecorded;
for(int i=0; i<len;) {
int length = 160;
if(len-i < 160) length=len-i;
memcpy(buffer, pHdr->lpData+i, length);
rtp_session_send_with_ts(session, buffer, length, user_ts);
user_ts+=160;
i+=length;
}

waveInPrepareHeader(hwi, pHdr, sizeof(WAVEHDR));
waveInAddBuffer(hwi, pHdr, sizeof(WAVEHDR));

}
break;

case WIM_OPEN:
cout << "waveInProc()... WIM_OPEN" << endl;
break;

default:
break;
}
}

int main(int argv, char **args)
{
ortp_init();
ortp_scheduler_init();
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
session=rtp_session_new(RTP_SESSION_SENDONLY);

rtp_session_set_scheduling_mode(session,1);
rtp_session_set_blocking_mode(session,1);
rtp_session_set_connected_mode(session,TRUE);
rtp_session_set_remote_addr(session,"192.168.0.181",61610);
rtp_session_set_payload_type(session,0);pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;

result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, (DWORD_PTR)waveInProc, NULL, CALLBACK_FUNCTION);

if(result) {
cout << "Failed to open waveform input device." << endl;
return -1;
}

WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = BS;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
if(result) {
cout << "Failed to read block from device" << endl;
return -1;
}

result = waveInStart(hWaveIn);
if(result) {
cout << "Failed to start recording" << endl;
return -1;
}

cout << "Recording..." << endl;

Sleep((NUMPTS/sampleRate) * 1000);

waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
//  waveInClose(hWaveIn);

rtp_session_destroy(session);
ortp_exit();
ortp_global_stats_display();

return 0;
}

RTPRecv.cpp

#include <ortp/ortp.h> // ortp-0.20.0

#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int sampleRate = 8000; // 8000, 11025, 16000, 22050, 24000, 32000, 44100
WAVEHDR WaveOutHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;

int main(int argv, char **args)
{
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;

if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
{
MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
}

RtpSession *session;

int jittcomp=40;
bool_t adapt=TRUE;

ortp_init();
ortp_scheduler_init();
ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
session=rtp_session_new(RTP_SESSION_RECVONLY);
rtp_session_set_scheduling_mode(session,1);
rtp_session_set_blocking_mode(session,1);
rtp_session_set_local_addr(session,"0.0.0.0",61610);
rtp_session_set_connected_mode(session,TRUE);
rtp_session_set_symmetric_rtp(session,TRUE);
rtp_session_enable_adaptive_jitter_compensation(session,adapt);
rtp_session_set_jitter_compensation(session,jittcomp);

rtp_session_set_payload_type(session,0);

rtp_session_signal_connect(session,"ssrc_changed",(RtpCallback)rtp_session_reset,0);

unsigned char buffer[160];
int have_more;
int err;
uint32_t ts=0;
int stream_received=0;

while(1) {
have_more=1;
while (have_more){
err=rtp_session_recv_with_ts(session, buffer, 160, ts, &have_more);
if (err>0) stream_received=1;
if ((stream_received) && (err>0)) {
WaveOutHdr.lpData = (LPSTR)buffer;
WaveOutHdr.dwBufferLength = 160;
WaveOutHdr.dwBytesRecorded = 160;
WaveOutHdr.dwUser = 0;
WaveOutHdr.dwFlags = 0;
WaveOutHdr.dwLoops = 0;
waveOutPrepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
}
}
ts+=160;
}

waveOutUnprepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
waveOutClose(hWaveOut);

rtp_session_destroy(session);
ortp_exit();
ortp_global_stats_display();

return 0;
}

1

Решение

Вы можете сделать большой буфер на клиенте. Например: буфер, содержащий 10 сек. Попробуйте получить маленький буфер и добавить его в большой, так как waveOutGetPosition() и непрерывно освобождать основной буфер, затем waveOutWrite() после WOM_DONE сообщение.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]