Ịchọgharị igwe Mediastreamer2 VoIP. Nkeji 6

A na-ewepụta ihe nke isiokwu ahụ site na nke m zen ọwa.

Na-ebufe mgbama ọdịyo site na iyi RTP

Ịchọgharị igwe Mediastreamer2 VoIP. Nkeji 6

Na nke ikpeazu ederede Anyị achịkọtala sekit njikwa anya site na generator ụda na ihe nchọpụta ụda na-arụ ọrụ n'ime otu mmemme. N'isiokwu a, anyị ga-amụta otú e si eji RTP protocol (RFC 3550 -). RTP: Usoro njem maka ngwa oge) maka ịnata / na-ebufe mgbaàmà ọdịyo n'elu netwọk Ethernet.

Usoro RTP (Protocol Real Time) ntụgharị pụtara ezigbo oge protocol, a na-eji ya na-ebufe ọdịyo, vidiyo, data, ihe ọ bụla chọrọ nnyefe ozugbo. Ka anyị were mgbama ọdịyo dịka ọmụmaatụ. Mgbanwe nke protocol bụ nke na ọ na-enye gị ohere ịnyefe mgbama ọdịyo nwere àgwà a kara aka.

A na-eme nnyefe ahụ site na iji ngwugwu UDP, nke pụtara na mfu ngwugwu na-anabata nke ọma n'oge nnyefe. Ihe ngwugwu ọ bụla nwere nkụnye eji isi mee RTP pụrụ iche yana ngọngọ data nke mgbama a na-ebufe. nkụnye eji isi mee nwere ihe nchọpụta mgbama ahọpụtara na-akpaghị aka, ozi gbasara ụdị mgbaama a na-ebufe, yana nọmba usoro ngwungwu pụrụ iche ka enwere ike ịhazi ngwugwu ndị ahụ n'usoro ziri ezi mgbe a na-eme nchọpụta, n'agbanyeghị usoro nke ndị ọrụ ahụ wetara ha. netwọk. nkụnye eji isi mee nwekwara ike ịnwe ozi ndị ọzọ, nke a na-akpọ ndọtị, nke na-enye ohere ịmegharị nkụnye eji isi mee maka otu ọrụ ngwa.

Ihe ngọngọ data nwere nkwụ ụgwọ nke ngwugwu. Nhazi ime nke ọdịnaya dabere n'ụdị ibu, ọ nwere ike ịbụ ihe atụ nke akara ngosi mono, akara stereo, akara onyonyo vidiyo, wdg.

A na-egosipụta ụdị ibu ahụ site na nọmba asaa-bit. Nkwanye RFC3551 (Profaịlụ RTP maka ọgbakọ ọdịyo na vidiyo na njikwa pere mpe) na-ewepụta ụdị ibu dị iche iche; tebụl kwekọrọ na-enye nkọwa nke ụdị ibu na ihe koodu ndị e ji hazie ha pụtara. Koodu ụfọdụ anaghị ejikọta ya na ụdị ibu ọ bụla; enwere ike iji ha gosipụta ibu aka ike.

Ogo nke ngọngọ data na-ejedebe n'elu site na oke ngwungwu kachasị nke enwere ike ibunye na netwọk enyere na-enweghị nkewa (MTU parameter). N'ozuzu, nke a abụghị ihe karịrị 1500 bytes. Ya mere, iji mee ka ọnụọgụ data na-ebufe kwa nkeji, ị nwere ike ịbawanye nha nke ngwugwu ahụ ruo n'ókè ụfọdụ, mgbe ahụ, ị ​​​​ga-achọ ịbawanye ugboro nke izipu ngwugwu. Na mgbasa ozi mgbasa ozi, nke a bụ ntọala nwere ike ịhazi. Na ndabara ọ bụ 50 Hz, i.e. 50 ngwugwu kwa nkeji. Anyị ga-akpọ usoro ngwungwu RTP ebufere na iyi RTP.

Iji malite ịnyefe data n'etiti isi iyi na onye nnata, o zuru ezu na onye na-ebufe ya maara adreesị IP nke onye nata na nọmba ọdụ ụgbọ mmiri ọ na-eji maka ịnata. Ndị ahụ. na-enweghị usoro mmalite ọ bụla, isi mmalite na-amalite ịnyefe data, na onye nnata, n'aka nke ya, dị njikere ịnata ozugbo ma hazie ya. Dị ka ọkọlọtọ si dị, nọmba ọdụ ụgbọ mmiri eji ebufe ma ọ bụ nata iyi RTP ga-adịrịrị.

N'ọnọdụ ebe ọ na-agaghị ekwe omume ịmata adreesị onye nnata tupu oge eruo, a na-eji sava ebe ndị nnata na-ahapụ adreesị ha, onye na-ebugharị nwere ike ịrịọ ya site n'ịrụtụ aka na aha pụrụ iche nke onye nata ya.

N'ọnọdụ ebe a na-amaghị àgwà nke ọwa nkwurịta okwu ma ọ bụ ike nke onye na-anata, a na-ahazi ọwa nzaghachi nke onye nata ya nwere ike ịgwa onye na-ebufe ikike ya, ọnụ ọgụgụ nke ngwugwu ọ tụfuru, wdg. Ọwa a na-eji protocol RTCP. A kọwapụtara usoro ngwugwu na-ebufe na ọwa a na RFC 3605. A na-ebufe obere data n'elu ọwa a, 200..300 bytes kwa nkeji, ya mere n'ozuzu, ọnụnọ ya adịghị arọ. Nọmba ọdụ ụgbọ mmiri nke ezigara ngwugwu RTCP ga-abụrịrị ihe na-adịghị mma yana nke karịrị nọmba ọdụ ụgbọ mmiri nke iyi RTP si abịa. N'ihe atụ anyị, anyị agaghị eji ọwa a, ebe ọ bụ na ike nke onye nata na ọwa doro anya karịa mkpa anyị, dị nnọọ obere.

Na mmemme anyị, sekit nnyefe data, n'adịghị ka ihe atụ gara aga, ga-ekewa n'ime akụkụ abụọ: ụzọ nnyefe na ụzọ nnata. Maka akụkụ nke ọ bụla, anyị ga-emepụta ebe elekere nke anyị, dị ka egosiri na foto isiokwu.

A ga-eme mkparịta ụka otu ụzọ n'etiti ha site na iji usoro RTP. N'ihe atụ a, anyị achọghị netwọk dị n'èzí, ebe ọ bụ na ma onye na-ebufe ya na onye nnata ga-adị n'otu kọmputa - ngwugwu ga-aga n'ime ya.

Iji guzobe iyi RTP, mgbasa ozi mgbasa ozi na-eji nzacha abụọ: MS_RTP_SEND na MS_RTP_RECV. Nke mbụ na-ebufe nke abụọ wee nata iyi RTP. Ka ihe nzacha ndị a wee rụọ ọrụ, ha kwesịrị ịnyefe ihe nrịbama na ihe nnọkọ RTP, nke nwere ike ịtụgharị iyi nke blocks data ka ọ bụrụ iyi nke ngwugwu RTP ma ọ bụ mee nke ọzọ. Ebe usoro data dị n'ime nke mgbasa ozi mgbasa ozi adabaghị n'ụdị data nke ngwugwu RTP, tupu ibufee data ahụ na MS_RTP_SEND, ịkwesịrị iji nzacha nzacha nke na-atụgharị n'ụdị mgbama ọdịyo 16-bit ka ọ bụrụ XNUMX-bit nke etinyere n'usoro. u-law (mu-law). N'akụkụ nnabata, nzacha decoder na-arụ ọrụ na-abụghị nke ya.

N'okpuru ebe a bụ ederede nke mmemme na-emejuputa atụmatụ egosiri na ọnụọgụ (# akara tupu ewepu ntuziaka ahụ, echefula itinye ha):

/* Файл 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);
}
}

Anyị na-achịkọta ma na-agba ọsọ. Mmemme ga-arụ ọrụ dị ka ọ dị na ihe atụ gara aga, mana a ga-ebufe data ahụ site na iyi RTP.

N'isiokwu na-esonụ, anyị ga-ekewa mmemme a n'ime ngwa abụọ nọọrọ onwe ha - onye na-anata na nnyefe ma malite ha na njedebe dị iche iche. N'otu oge ahụ, anyị ga-amụta ka esi nyochaa ngwugwu RTP site na iji mmemme TShark.

isi: www.habr.com

Tinye a comment