FFmpegrtsp播放代码剖析-创新互联

rtsp url播放的时候,会根据url中是否有rtsp来判断是否调用ff_rtsp_demuxer进行网络数据的读取

源城网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设等网站项目制作,到程序开发,运营维护。创新互联从2013年创立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联。

AVInputFormatff_rtsp_demuxer = {
    .name           = "rtsp",
    .long_name      = NULL_IF_CONFIG_SMALL("RTSP input"),
    .priv_data_size = sizeof(RTSPState),
    .read_probe     = rtsp_probe,
    .read_header    = rtsp_read_header,
    .read_packet    = rtsp_read_packet,
    .read_close     = rtsp_read_close,
    .read_seek      = rtsp_read_seek,
    .flags          = AVFMT_NOFILE,
    .read_play      = rtsp_read_play,
    .read_pause     = rtsp_read_pause,
    .priv_class     = &rtsp_demuxer_class,
};

码流格式探测分析

> ffplayd.exe!rtp_read(URLContext * h, unsigned char * buf, int size) 行 377 C

(调用recvfrom读取RTP传输数据,transfer_func指向了rtp_read的实现)

ffplayd.exe!retry_transfer_wrapper(URLContext * h, unsigned char * buf, int size, int size_min, int (URLContext *, unsigned char *, int) * transfer_func) 行 376 C
  ffplayd.exe!ffurl_read(URLContext * h, unsigned char * buf, int size) 行 412 C
  ffplayd.exe!udp_read_packet(AVFormatContext * s, RTSPStream * * prtsp_st, unsigned char * buf, int buf_size, __int64 wait_end) 行 2033 C
  ffplayd.exe!read_packet(AVFormatContext * s, RTSPStream * * rtsp_st, RTSPStream * first_queue_st, __int64 wait_end) 行 2116 C
  ffplayd.exe!ff_rtsp_fetch_packet(AVFormatContext * s, AVPacket * pkt) 行 2202 C
  ffplayd.exe!rtsp_read_packet(AVFormatContext * s, AVPacket * pkt) 行 879 C
  ffplayd.exe!ff_read_packet(AVFormatContext * s, AVPacket * pkt) 行 856 C
  ffplayd.exe!read_frame_internal(AVFormatContext * s, AVPacket * pkt) 行 1582 C
  ffplayd.exe!avformat_find_stream_info(AVFormatContext * ic, AVDictionary * * options) 行 3772 C
  ffplayd.exe!read_thread(void * arg) 行 2805 C
  ffplayd.exe!SDL_RunThread(void * data) 行 283 C
  ffplayd.exe!RunThread(void * data) 行 91 C
  ffplayd.exe!RunThreadViaBeginThreadEx(void * data) 行 106 

重点分析函数ff_rtsp_fetch_packet,该函数调用read_packet获取到RTP数据,调用ff_rtp_parse_packet分析RTP数据,去掉RTP包头,添加起始码,然后封装成AVPacket,但是封装的AVPacket并不是完整的NAL单元的视频流,对于FU-A分包的数据,仍然需要对多个AVPacket进行重新组装

> ffplayd.exe!h364_handle_packet_fu_a(AVFormatContext * ctx, PayloadContext * data, AVPacket * pkt, const unsigned char * buf, int len, int * nal_counters, int nal_mask) 行 291 C

(对FU-A分包的RTP格式数据,会根据是否是第一个包添加起始码,关键是start_bit    = fu_header >> 7;)
  ffplayd.exe!h364_handle_packet(AVFormatContext * ctx, PayloadContext * data, AVStream * st, AVPacket * pkt, unsigned int * timestamp, const unsigned char * buf, int len, unsigned short seq, int flags) 行 359 C
  ffplayd.exe!rtp_parse_packet_internal(RTPDemuxContext * s, AVPacket * pkt, const unsigned char * buf, int len) 行 692 C
  ffplayd.exe!rtp_parse_one_packet(RTPDemuxContext * s, AVPacket * pkt, unsigned char * * bufptr, int len) 行 841 C
  ffplayd.exe!ff_rtp_parse_packet(RTPDemuxContext * s, AVPacket * pkt, unsigned char * * bufptr, int len) 行 875 C
  ffplayd.exe!ff_rtsp_fetch_packet(AVFormatContext * s, AVPacket * pkt) 行 2217 C
  ffplayd.exe!rtsp_read_packet(AVFormatContext * s, AVPacket * pkt) 行 879 C
  ffplayd.exe!ff_read_packet(AVFormatContext * s, AVPacket * pkt) 行 856 C
  ffplayd.exe!read_frame_internal(AVFormatContext * s, AVPacket * pkt) 行 1582 C
  ffplayd.exe!av_read_frame(AVFormatContext * s, AVPacket * pkt) 行 1776 C
  ffplayd.exe!read_thread(void * arg) 行 3008 C
  ffplayd.exe!SDL_RunThread(void * data) 行 283 C
  ffplayd.exe!RunThread(void * data) 行 91 C
  ffplayd.exe!RunThreadViaBeginThreadEx(void * data) 行 106 C

av_read_frame分包代码剖析

ffplayd.exe!ff_combine_frame(ParseContext * pc, int next, const unsigned char * * buf, int * buf_size) 行 265 C
> ffplayd.exe!h364_parse(AVCodecParserContext * s, AVCodecContext * avctx, const unsigned char * * poutbuf, int * poutbuf_size, const unsigned char * buf, int buf_size) 行 595 C
  ffplayd.exe!av_parser_parse2(AVCodecParserContext * s, AVCodecContext * avctx, unsigned char * * poutbuf, int * poutbuf_size, const unsigned char * buf, int buf_size, __int64 pts, __int64 dts, __int64 pos) 行 166 C
  ffplayd.exe!parse_packet(AVFormatContext * s, AVPacket * pkt, int stream_index) 行 1461 C
  ffplayd.exe!read_frame_internal(AVFormatContext * s, AVPacket * pkt) 行 1675 C
  ffplayd.exe!av_read_frame(AVFormatContext * s, AVPacket * pkt) 行 1776 C
  ffplayd.exe!read_thread(void * arg) 行 3008 C
  ffplayd.exe!SDL_RunThread(void * data) 行 283 C
  ffplayd.exe!RunThread(void * data) 行 91 C
  ffplayd.exe!RunThreadViaBeginThreadEx(void * data) 行 106 C
  [外部代码] 

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前文章:FFmpegrtsp播放代码剖析-创新互联
分享网址:http://myzitong.com/article/decjig.html