ffmpeg 怎么处理udp音频_视音频数据处理入门:UDP-RTP协议解析
=====================================================
視音頻數據處理入門系列文章:
=====================================================
本文介紹網絡協議數據的處理程序。網絡協議數據在視頻播放器中的位置如下所示。
本文中的程序是一個UDP/RTP協議流媒體數據解析器。該程序可以分析UDP協議中的RTP 包頭中的內容,以及RTP負載中MPEG-TS封裝格式的信息。通過修改該程序可以實現不同的UDP/RTP協議數據處理功能。
原理
MPEG-TS封裝格式數據打包為RTP/UDP協議然后發送出去的流程如下圖所示。圖中首先每7個MPEG-TS Packet打包為一個RTP,然后每個RTP再打包為一個UDP。其中打包RTP的方法就是在MPEG-TS數據前面加上RTP Header,而打包RTP的方法就是在RTP數據前面加上UDP Header。
有關MPEG-TS、RTP、UDP的知識不再詳細介紹,可以參考相關的文檔了解其中的細節信息。本文記錄的程序是一個收取流媒體的程序,因此本文程序的流程和上述發送MPEG-TS的流程正好是相反的。該程序可以通過Socket編程收取UDP包,解析其中的RTP包的信息,然后再解析RTP包中MPEG-TS Packet的信息。
代碼
整個程序位于simplest_udp_parser()函數中,如下所示。
/**
*?最簡單的視音頻數據處理示例
*?Simplest?MediaData?Test
*
*?雷霄驊?Lei?Xiaohua
*?leixiaohua1020@126.com
*?中國傳媒大學/數字電視技術
*?Communication?University?of?China?/?Digital?TV?Technology
*?http://blog.csdn.net/leixiaohua1020
*
*?本項目包含如下幾種視音頻測試示例:
*??(1)像素數據處理程序。包含RGB和YUV像素格式處理的函數。
*??(2)音頻采樣數據處理程序。包含PCM音頻采樣格式處理的函數。
*??(3)H.264碼流分析程序。可以分離并解析NALU。
*??(4)AAC碼流分析程序??梢苑蛛x并解析ADTS幀。
*??(5)FLV封裝格式分析程序。可以將FLV中的MP3音頻碼流分離出來。
*??(6)UDP-RTP協議分析程序??梢詫⒎治鯱DP/RTP/MPEG-TS數據包。
*
*?This?project?contains?following?samples?to?handling?multimedia?data:
*??(1)?Video?pixel?data?handling?program.?It?contains?several?examples?to?handle?RGB?and?YUV?data.
*??(2)?Audio?sample?data?handling?program.?It?contains?several?examples?to?handle?PCM?data.
*??(3)?H.264?stream?analysis?program.?It?can?parse?H.264?bitstream?and?analysis?NALU?of?stream.
*??(4)?AAC?stream?analysis?program.?It?can?parse?AAC?bitstream?and?analysis?ADTS?frame?of?stream.
*??(5)?FLV?format?analysis?program.?It?can?analysis?FLV?file?and?extract?MP3?audio?stream.
*??(6)?UDP-RTP?protocol?analysis?program.?It?can?analysis?UDP/RTP/MPEG-TS?Packet.
*
*/
#include?
#include?
#pragma?comment(lib,?"ws2_32.lib")
#pragma?pack(1)
/*
*?[memo]?FFmpeg?stream?Command:
*?ffmpeg?-re?-i?sintel.ts?-f?mpegts?udp://127.0.0.1:8880
*?ffmpeg?-re?-i?sintel.ts?-f?rtp_mpegts?udp://127.0.0.1:8880
*/
typedef?struct?RTP_FIXED_HEADER{
/*?byte?0?*/
unsigned?char?csrc_len:4;???????/*?expect?0?*/
unsigned?char?extension:1;??????/*?expect?1?*/
unsigned?char?padding:1;????????/*?expect?0?*/
unsigned?char?version:2;????????/*?expect?2?*/
/*?byte?1?*/
unsigned?char?payload:7;
unsigned?char?marker:1;????????/*?expect?1?*/
/*?bytes?2,?3?*/
unsigned?short?seq_no;
/*?bytes?4-7?*/
unsigned??long?timestamp;
/*?bytes?8-11?*/
unsigned?long?ssrc;????????????/*?stream?number?is?used?here.?*/
}?RTP_FIXED_HEADER;
typedef?struct?MPEGTS_FIXED_HEADER?{
unsigned?sync_byte:?8;
unsigned?transport_error_indicator:?1;
unsigned?payload_unit_start_indicator:?1;
unsigned?transport_priority:?1;
unsigned?PID:?13;
unsigned?scrambling_control:?2;
unsigned?adaptation_field_exist:?2;
unsigned?continuity_counter:?4;
}?MPEGTS_FIXED_HEADER;
int?simplest_udp_parser(int?port)
{
WSADATA?wsaData;
WORD?sockVersion?=?MAKEWORD(2,2);
int?cnt=0;
//FILE?*myout=fopen("output_log.txt","wb+");
FILE?*myout=stdout;
FILE?*fp1=fopen("output_dump.ts","wb+");
if(WSAStartup(sockVersion,?&wsaData)?!=?0){
return?0;
}
SOCKET?serSocket?=?socket(AF_INET,?SOCK_DGRAM,?IPPROTO_UDP);
if(serSocket?==?INVALID_SOCKET){
printf("socket?error?!");
return?0;
}
sockaddr_in?serAddr;
serAddr.sin_family?=?AF_INET;
serAddr.sin_port?=?htons(port);
serAddr.sin_addr.S_un.S_addr?=?INADDR_ANY;
if(bind(serSocket,?(sockaddr?*)&serAddr,?sizeof(serAddr))?==?SOCKET_ERROR){
printf("bind?error?!");
closesocket(serSocket);
return?0;
}
sockaddr_in?remoteAddr;
int?nAddrLen?=?sizeof(remoteAddr);
//How?to?parse?
int?parse_rtp=1;
int?parse_mpegts=1;
printf("Listening?on?port?%d\n",port);
char?recvData[10000];
while?(1){
int?pktsize?=?recvfrom(serSocket,?recvData,?10000,?0,?(sockaddr?*)&remoteAddr,?&nAddrLen);
if?(pktsize?>?0){
//printf("Addr:%s\r\n",inet_ntoa(remoteAddr.sin_addr));
//printf("packet?size:%d\r\n",pktsize);
//Parse?RTP
//
if(parse_rtp!=0){
char?payload_str[10]={0};
RTP_FIXED_HEADER?rtp_header;
int?rtp_header_size=sizeof(RTP_FIXED_HEADER);
//RTP?Header
memcpy((void?*)&rtp_header,recvData,rtp_header_size);
//RFC3551
char?payload=rtp_header.payload;
switch(payload){
case?0:
case?1:
case?2:
case?3:
case?4:
case?5:
case?6:
case?7:
case?8:
case?9:
case?10:
case?11:
case?12:
case?13:
case?14:
case?15:
case?16:
case?17:
case?18:?sprintf(payload_str,"Audio");break;
case?31:?sprintf(payload_str,"H.261");break;
case?32:?sprintf(payload_str,"MPV");break;
case?33:?sprintf(payload_str,"MP2T");break;
case?34:?sprintf(payload_str,"H.263");break;
case?96:?sprintf(payload_str,"H.264");break;
default:sprintf(payload_str,"other");break;
}
unsigned?int?timestamp=ntohl(rtp_header.timestamp);
unsigned?int?seq_no=ntohs(rtp_header.seq_no);
fprintf(myout,"[RTP?Pkt]?%5d|?%5s|?%10u|?%5d|?%5d|\n",cnt,payload_str,timestamp,seq_no,pktsize);
//RTP?Data
char?*rtp_data=recvData+rtp_header_size;
int?rtp_data_size=pktsize-rtp_header_size;
fwrite(rtp_data,rtp_data_size,1,fp1);
//Parse?MPEGTS
if(parse_mpegts!=0&&payload==33){
MPEGTS_FIXED_HEADER?mpegts_header;
for(int?i=0;i
if(rtp_data[i]!=0x47)
break;
//MPEGTS?Header
//memcpy((void?*)&mpegts_header,rtp_data+i,sizeof(MPEGTS_FIXED_HEADER));
fprintf(myout,"???[MPEGTS?Pkt]\n");
}
}
}else{
fprintf(myout,"[UDP?Pkt]?%5d|?%5d|\n",cnt,pktsize);
fwrite(recvData,pktsize,1,fp1);
}
cnt++;
}
}
closesocket(serSocket);
WSACleanup();
fclose(fp1);
return?0;
}
上文中的函數調用方法如下所示。
simplest_udp_parser(8880);
結果
本程序輸入為本機的一個端口號,輸出為UDP/RTP/MPEG-TS的解析結果。程序開始運行后,可以使用推流軟件向本機的udp://127.0.0.1:8880地址進行推流。例如可以使用VLC Media Player的“打開媒體”對話框中的“串流”功能(位于“播放”按鈕旁邊的小三角按鈕的菜單中)。在該功能的對話框中添加一個“RTP / MPEG Transport Stream”的新目標。
也可以使用FFmpeg對本機的8880端口進行推流。下面的命令可以推流UDP封裝的MPEG-TS。
ffmpeg?-re?-i?sintel.ts?-f?mpegts?udp://127.0.0.1:8880
下面的命令可以推流首先經過RTP封裝,然后經過UDP封裝的MPEG-TS。
ffmpeg?-re?-i?sintel.ts?-f?rtp_mpegts?udp://127.0.0.1:8880
推流之后,本文的程序會通過Socket接收到UDP包并且解析其中的數據。解析的結果如下圖所示。
下載
Simplest mediadata test
項目主頁
開源中國:http://git.oschina.net/leixiaohua1020/simplest_mediadata_test
CSDN下載地址:http://download.csdn.net/detail/leixiaohua1020/9422409
本項目包含如下幾種視音頻數據解析示例:
(1)像素數據處理程序。包含RGB和YUV像素格式處理的函數。
(2)音頻采樣數據處理程序。包含PCM音頻采樣格式處理的函數。
(3)H.264碼流分析程序。可以分離并解析NALU。
(4)AAC碼流分析程序。可以分離并解析ADTS幀。
(5)FLV封裝格式分析程序??梢詫LV中的MP3音頻碼流分離出來。
(6)UDP-RTP協議分析程序??梢詫⒎治鯱DP/RTP/MPEG-TS數據包。
總結
以上是生活随笔為你收集整理的ffmpeg 怎么处理udp音频_视音频数据处理入门:UDP-RTP协议解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java练手代码大全手机版_java循环
- 下一篇: 四位共阳极数码管显示函数_Verilog