Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 6

Tógtar ábhar an ailt ó mo cainéal zen.

Comhartha fuaime a tharchur trí shruth RTP

Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 6

Sa cheann deireanach Airteagal Tá ciorcad cianrialaithe curtha le chéile againn ó ghineadóir ton agus brathadóir ton a fheidhmíonn laistigh den chlár céanna. San Airteagal seo foghlaimeoimid conas an prótacal RTP (RFC 3550 -) a úsáid. RTP: Prótacal Iompair le haghaidh Feidhmchláir Fíor-Ama) chun comhartha fuaime a ghlacadh/a tharchur thar líonra Ethernet.

prótacal RTP (Prótacal Fíor-ama) ciallaíonn aistrithe prótacal fíor-ama, úsáidtear é chun fuaime, físeáin, sonraí, gach rud a éilíonn tarchur i bhfíor-am a tharchur. Glacaimis comhartha fuaime mar shampla. Mar gheall ar sholúbthacht an phrótacail is féidir leat comhartha fuaime a tharchur le cáilíocht réamhshocraithe.

Déantar an tarchur ag baint úsáide as paicéid UDP, rud a chiallaíonn go bhfuil caillteanas paicéad inghlactha go leor le linn tarchurtha. Tá ceanntásc RTP speisialta agus bloc sonraí den chomhartha tarchurtha i ngach paicéad. Tá aitheantóir foinse comhartha roghnaithe go randamach sa cheanntásc, faisnéis faoin gcineál comhartha atá á tharchur, agus uimhir seicheamh paicéid uathúil ionas gur féidir na paicéid a shocrú san ord ceart agus iad ag díchódú, beag beann ar an ord ina seachadadh iad ag an líonra. Is féidir faisnéis bhreise a bheith sa cheanntásc freisin, an síneadh mar a thugtar air, a cheadaíonn an ceanntásc a oiriúnú le húsáid i dtasc feidhmchlár ar leith.

Tá pálasta an phaicéid sa bhloc sonraí. Braitheann eagraíocht inmheánach an ábhair ar an gcineál ualach, is féidir é a bheith ina shamplaí de chomhartha mona, comhartha steirió, líne íomhá físe, etc.

Cuirtear an cineál ualaigh in iúl le uimhir seacht ngiotán. Moladh RFC3551 (Próifíl RTP le haghaidh Comhdhálacha Fuaime agus Físe le Rialú Íosta(e) bunaítear roinnt cineálacha ualaí; cuireann an tábla comhfhreagrach tuairisc ar na cineálacha ualaigh agus brí na gcód lena n-ainmnítear iad. Níl roinnt cóid ceangailte go docht le haon chineál ualaigh; is féidir iad a úsáid chun ualach treallach a ainmniú.

Tá teorainn leis an méid bloc sonraí thuas ag an uasmhéid paicéad is féidir a tharchur ar líonra ar leith gan deighilt (paraiméadar MTU). Go ginearálta, níl sé seo níos mó ná 1500 bytes. Mar sin, chun an méid sonraí a tharchuirtear in aghaidh an tsoicind a mhéadú, is féidir leat méid an phacéid a mhéadú suas go pointe áirithe, agus ansin beidh ort minicíocht seolta na bpacáistí a mhéadú. I sruthóir meán, is socrú inchumraithe é seo. De réir réamhshocraithe tá sé 50 Hz, i.e. 50 paicéad in aghaidh an tsoicind. Tabharfaimid sruth RTP ar sheicheamh na bpaicéad RTP tarchurtha.

Chun tús a chur le sonraí a tharchur idir an fhoinse agus an glacadóir, is leor go bhfuil a fhios ag an tarchuradóir seoladh IP an ghlacadóra agus uimhir an chalafoirt a úsáideann sé lena fháil. Iad siúd. gan aon réamh-nósanna imeachta, tosaíonn an fhoinse sonraí a tharchur, agus tá an glacadóir, ar a seal, réidh chun é a fháil agus a phróiseáil láithreach. De réir an chaighdeáin, caithfidh an uimhir chalafoirt a úsáidtear chun sruth RTP a tharchur nó a fháil a bheith cothrom.

I gcásanna ina bhfuil sé dodhéanta seoladh an ghlacadóra a bheith ar eolas roimh ré, úsáidtear freastalaithe nuair a fhágann glacadóirí a seoladh, agus is féidir leis an tarchuradóir é a iarraidh trí thagairt a dhéanamh d’ainm uathúil éigin an ghlacadóra.

I gcásanna nach fios cáilíocht an chainéil chumarsáide nó cumais an ghlacadóra, eagraítear cainéal aiseolais trína bhféadfaidh an glacadóir an tarchuradóir a chur ar an eolas faoina chumais, líon na bpacáistí a chaill sé, etc. Úsáideann an cainéal seo prótacal RTCP. Sainmhínítear formáid na bpacáistí a tharchuirtear sa chainéal seo i RFC 3605. Is beag sonraí a tharchuirtear thar an gcainéal seo, 200..300 bytes in aghaidh an tsoicind, mar sin go ginearálta, níl a láithreacht trom. Caithfidh uimhir an phoirt chuig a seoltar paicéid RTCP a bheith corr agus uimhir amháin níos mó ná uimhir an phoirt óna dtagann an sruth RTP. Inár sampla, ní úsáidfimid an cainéal seo, mar is léir go sáraíonn cumais an ghlacadóra agus an chainéil ár gcuid riachtanas measartha go dtí seo.

Inár gclár, déanfar an ciorcad tarchurtha sonraí, murab ionann agus an sampla roimhe seo, a roinnt ina dhá chuid: cosán tarchurtha agus cosán glactha. Do gach cuid déanfaimid ár bhfoinse clog féin, mar a thaispeántar sa phictiúr teidil.

Déanfar cumarsáid aontreo eatarthu trí úsáid a bhaint as prótacal RTP. Sa sampla seo, níl líonra seachtrach ag teastáil uainn, ós rud é go mbeidh an tarchuradóir agus an glacadóir suite ar an ríomhaire céanna - beidh na paicéid ag taisteal taobh istigh de.

Chun sruth RTP a bhunú, úsáideann an sruthlóir meán dhá scagaire: MS_RTP_SEND agus MS_RTP_RECV. Tarchuireann an chéad cheann an dara ceann agus faigheann sé an sruth RTP. Ionas go n-oibreoidh na scagairí seo, ní mór dóibh pointeoir a chur ar aghaidh chuig réad seisiúin RTP, ar féidir leo sruth de bhlocanna sonraí a thiontú ina sruth de phaicéid RTP nó a mhalairt a dhéanamh. Ós rud é nach bhfuil formáid sonraí inmheánacha an tsrutha meáin ag teacht le formáid sonraí an phaicéid RTP, sula n-aistrítear na sonraí go MS_RTP_SEND, ní mór duit scagaire ionchódóra a úsáid a thiontaíonn samplaí comhartha fuaime 16-giotán ina n-ocht ngiotán atá ionchódaithe de réir an u-dlí (mu-law). Ar an taobh glactha, comhlíonann an scagaire díchódóra an fheidhm os coinne.

Seo thíos téacs an chláir a chuireann an scéim a thaispeántar san fhigiúr i bhfeidhm (na # siombailí sular baineadh na treoracha san áireamh, ná déan dearmad iad a chur san áireamh):

/* Файл mstest6.c Имитатор пульта управления и приемника. */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/msvolume.h>
#include <mediastreamer2/mstonedetector.h>
#include <mediastreamer2/msrtp.h>
#include <ortp/rtpsession.h>
#include <ortp/payloadtype.h>
/* Подключаем заголовочный файл с функциями управления событиями
* медиастримера.*/
include <mediastreamer2/mseventqueue.h>
#define PCMU 0
/* Функция обратного вызова, она будет вызвана фильтром, как только он
обнаружит совпадение характеристик входного сигнала с заданными. */
static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id,
MSToneDetectorEvent *ev)
{
printf("Принята команда: %sn", ev->tone_name);
}
/*----------------------------------------------------------------------------*/
/* Функция регистрации типов полезных нагрузок. */
void register_payloads(void)
{
/*Регистрируем типы нагрузок в таблице профилей. Позднее, по индексу
взятому из заголовка RTP-пакета из этой таблицы будут извлекаться
параметры нагрузки, необходимые для декодирования данных пакета. */
rtp_profile_set_payload (&av_profile, PCMU, &payload_type_pcm8000);
}
/*----------------------------------------------------------------------------*/
/* Эта функция создана из функции create_duplex_rtpsession() в audiostream.c
медиастримера2. */
static RtpSession *
create_rtpsession (int loc_rtp_port, int loc_rtcp_port,
bool_t ipv6, RtpSessionMode mode)
{
RtpSession *rtpr;
rtpr = rtp_session_new ((int) mode);
rtp_session_set_scheduling_mode (rtpr, 0);
rtp_session_set_blocking_mode (rtpr, 0);
rtp_session_enable_adaptive_jitter_compensation (rtpr, TRUE);
rtp_session_set_symmetric_rtp (rtpr, TRUE);
rtp_session_set_local_addr (rtpr, ipv6 ? "::" : "0.0.0.0", loc_rtp_port,
loc_rtcp_port);
rtp_session_signal_connect (rtpr, "timestamp_jump",
(RtpCallback) rtp_session_resync, 0);
rtp_session_signal_connect (rtpr, "ssrc_changed",
(RtpCallback) rtp_session_resync, 0);
rtp_session_set_ssrc_changed_threshold (rtpr, 0);
rtp_session_set_send_payload_type(rtpr, PCMU);
/* По умолчанию выключаем RTCP-сессию, так как наш пульт не будет использовать её. */
rtp_session_enable_rtcp (rtpr, FALSE);
return rtpr;
}
/*----------------------------------------------------------------------------*/
int main()
{
ms_init();
/* Создаем экземпляры фильтров. */
MSFilter *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);
MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
MSFilter *volume = ms_filter_new(MS_VOLUME_ID);
MSSndCard *card_playback =
ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
MSFilter *snd_card_write = ms_snd_card_create_writer(card_playback);
MSFilter *detector = ms_filter_new(MS_TONE_DETECTOR_ID);
/* Очищаем массив находящийся внутри детектора тонов, он описывает
* особые приметы разыскиваемых сигналов.*/
ms_filter_call_method(detector, MS_TONE_DETECTOR_CLEAR_SCANS, 0);
/* Подключаем к фильтру функцию обратного вызова. */
ms_filter_set_notify_callback(detector,
(MSFilterNotifyFunc)tone_detected_cb, NULL);
/* Создаем массив, каждый элемент которого описывает характеристику
* одного из тонов, который требуется обнаруживать: Текстовое имя
* данного элемента, частота в герцах, длительность в миллисекундах,
* минимальный уровень относительно 0,775В. */
MSToneDetectorDef scan[6]=
{
{"V+",440, 100, 0.1}, /* Команда "Увеличить громкость". */
{"V-",540, 100, 0.1}, /* Команда "Уменьшить громкость". */
{"C+",640, 100, 0.1}, /* Команда "Увеличить номер канала". */
{"C-",740, 100, 0.1}, /* Команда "Уменьшить номер канала". */
{"ON",840, 100, 0.1}, /* Команда "Включить телевизор". */
{"OFF", 940, 100, 0.1}/* Команда "Выключить телевизор". */
};
/* Передаем "приметы" сигналов детектор тонов. */
int i;
for (i = 0; i < 6; i++)
{
ms_filter_call_method(detector, MS_TONE_DETECTOR_ADD_SCAN,
&scan[i]);
}
/* Создаем фильтры кодера и декодера */
MSFilter *encoder = ms_filter_create_encoder("PCMU");
MSFilter *decoder=ms_filter_create_decoder("PCMU");
/* Регистрируем типы нагрузки. */
register_payloads();
/* Создаем RTP-сессию передатчика. */
RtpSession *tx_rtp_session = create_rtpsession (8010, 8011, FALSE, RTP_SESSION_SENDONLY);
rtp_session_set_remote_addr_and_port(tx_rtp_session,"127.0.0.1", 7010, 7011);
rtp_session_set_send_payload_type(tx_rtp_session, PCMU);
MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID);
ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, tx_rtp_session);
/* Создаем RTP-сессию приемника. */
MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
RtpSession *rx_rtp_session = create_rtpsession (7010, 7011, FALSE, RTP_SESSION_RECVONLY);
ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rx_rtp_session);
/* Создаем источники тактов - тикеры. */
MSTicker *ticker_tx = ms_ticker_new();
MSTicker *ticker_rx = ms_ticker_new();
/* Соединяем фильтры передатчика. */
ms_filter_link(voidsource, 0, dtmfgen, 0);
ms_filter_link(dtmfgen, 0, volume, 0);
ms_filter_link(volume, 0, encoder, 0);
ms_filter_link(encoder, 0, rtpsend, 0);
/* Соединяем фильтры приёмника. */
ms_filter_link(rtprecv, 0, decoder, 0);
ms_filter_link(decoder, 0, detector, 0);
ms_filter_link(detector, 0, snd_card_write, 0);
/* Подключаем источник тактов. */
ms_ticker_attach(ticker_tx, voidsource);
ms_ticker_attach(ticker_rx, rtprecv);
/* Настраиваем структуру, управляющую выходным сигналом генератора. */
MSDtmfGenCustomTone dtmf_cfg;
dtmf_cfg.tone_name[0] = 0;
dtmf_cfg.duration = 1000;
dtmf_cfg.frequencies[0] = 440;
/* Будем генерировать один тон, частоту второго тона установим в 0. */
dtmf_cfg.frequencies[1] = 0;
dtmf_cfg.amplitude = 1.0;
dtmf_cfg.interval = 0.;
dtmf_cfg.repeat_count = 0.;
/* Организуем цикл сканирования нажатых клавиш. Ввод нуля завершает
* цикл и работу программы. */
char key='9';
printf("Нажмите клавишу команды, затем ввод.n"
"Для завершения программы введите 0.n");
while(key != '0')
{
key = getchar();
if ((key >= 49) && (key <= 54))
{
printf("Отправлена команда: %cn", key);
/* Устанавливаем частоту генератора в соответствии с
* кодом нажатой клавиши. */
dtmf_cfg.frequencies[0] = 440 + 100*(key-49);
/* Включаем звуковой генератор c обновленной частотой. */
ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
(void*)&dtmf_cfg);
}
/* Укладываем тред в спячку на 20мс, чтобы другие треды
* приложения получили время на работу. */
ms_usleep(20000);
}
}

Táimid ag tiomsú agus ag rith. Oibreoidh an clár mar a bhí sa sampla roimhe seo, ach déanfar na sonraí a tharchur trí shruth RTP.

Sa chéad alt eile roinnfimid an clár seo ina dhá fheidhmchlár neamhspleách - glacadóir agus tarchuradóir agus seolfar iad i gcríochfoirt éagsúla. Ag an am céanna, beidh muid ag foghlaim conas anailís a dhéanamh ar phaicéid RTP ag baint úsáide as an gclár TShark.

Foinse: will.com

Add a comment