日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ffmpeg 怎么处理udp音频_视音频数据处理入门:UDP-RTP协议解析

發布時間:2025/3/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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碼流分析程序。可以分離并解析ADTS幀。

*??(5)FLV封裝格式分析程序。可以將FLV中的MP3音頻碼流分離出來。

*??(6)UDP-RTP協議分析程序。可以將分析UDP/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封裝格式分析程序。可以將FLV中的MP3音頻碼流分離出來。

(6)UDP-RTP協議分析程序。可以將分析UDP/RTP/MPEG-TS數據包。

總結

以上是生活随笔為你收集整理的ffmpeg 怎么处理udp音频_视音频数据处理入门:UDP-RTP协议解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。