1.directProxy默认值为1 也就是开启代理 我们先看默认设置下的推流流程
断点断在ringbuffer.h文件的write函数这里不管怎样都要经过这里
然后看堆栈
整理一下
RingBuffer<std::shared_ptr<toolkit::List<std::shared_ptr<mediakit::RtpPacket> > > >::write
RtspMediaSource::onFlush
PacketCache<mediakit::RtpPacket, mediakit::FlushPolicy, toolkit::List<std::shared_ptr<mediakit::RtpPacket> > >::flush
PacketCache<mediakit::RtpPacket, mediakit::FlushPolicy, toolkit::List<std::shared_ptr<mediakit::RtpPacket> > >::inputPacket
RtspMediaSource::onWrite
RtspMediaSourceImp::onWrite
RtspSession::onRtpSorted
RtpTrackImp::onRtpSorted
popIterator
popPacket
tryPopPacket
sortPacket
RtpTrack::inputRtp
RtpMultiReceiver<2>::handleOneRtp
:RtspSession::onRtpPacket
RtspSplitter::onRecvHeader
HttpRequestSplitter::input
RtspSession::onRecv
2.directProxy设置为0时候的推流过程
此堆栈是一直走到写环形队列时候的堆栈
先说结果 不开代理时候的最终为走到这里 由于这个是在头文件 无法下断点 所以把函数体写在cpp文件里 如下:涉及到文件:RtpCodec.h 和RtpCodec.cpp
编译之后 gdb开起来直接在这里这个函数下断点 ffmpeg开启rtsp推流
由于包含了视频和音频所以音频数据 视频数据都会走到这
先看音频的AAC数据
内容太多了看起来有点费劲 直接把调用堆栈写出来吧
RtspMediaSource::onFlush
flush
inputPacket
RtspMediaSource::onWrite
RingBuffer<std::shared_ptr<mediakit::RtpPacket> >::write
RtspMuxer::onRtp
RingDelegateHelper::onWrite
RingBuffer<std::shared_ptr<mediakit::RtpPacket> >::write
RtpRing::inputRtp
AACRtpEncoder::makeAACRtp
AACRtpEncoder::inputFrame
RtspMuxer::inputFrame
RtspMediaSourceMuxer::inputFrame
MultiMediaSourceMuxer::onTrackFrame
MediaSink::addTrack
FrameWriterInterfaceHelper::inputFrame
FrameDispatcher::inputFrame
AACTrack::inputFrame_l
AACTrack::inputFrame
MediaSink::inputFrame
MediaSink::emitAllTrackReady
MediaSink::checkTrackIfReady
MediaSink::inputFrame
FrameDispatcher::inputFrame
AACTrack::inputFrame_l
AACTrack::inputFrame
FrameDispatcher::inputFrame
AACRtpDecoder::flushData
AACRtpDecoder::inputRtp
RtspDemuxer::inputRtp
RtspMediaSourceImp::onWrite
RtspSession::onRtpSorted
RtpTrackImp::onRtpSorted
popIterator
popPacket
tryPopPacket
sortPacket
RtpTrack::inputRtp //我们下断点那 也叫inputRtp 中间经历了那么多调用
RtspSession::onRtpPacket
RtspSplitter::onRecvHeader
HttpRequestSplitter::input
RtspSession::onRecv
TcpServer::onAcceptConnection
Socket::onRead
Socket::attachEvent
EventPoller::runLoop
这个是视频的H264堆栈
再把视频的写出来
RtpRing::inputRtp
H264RtpEncoder::packRtpStapA
H264RtpEncoder::packRtp
H264RtpEncoder::inputFrame_l
H264RtpEncoder::inputFrame
RtspMuxer::inputFrame
RtspMediaSourceMuxer::inputFrame
MultiMediaSourceMuxer::onTrackFrame
MediaSink::addTrack
FrameWriterInterfaceHelper::inputFrame
FrameDispatcher::inputFrame
H264Track::inputFrame_l
H264Track::inputFrame
splitH264
H264Track::inputFrame
MediaSink::inputFrame
MediaSink::emitAllTrackReady
MediaSink::checkTrackIfReady
MediaSink::inputFrame
//之后的堆栈和音频是一样的
可以发现就是在MediaSink::inputFrame函数这里音视频走了不同的调用 函数如下
本次测试中音频是AACTrack 视频是H264Track
AAC的
这里的AudioTrack::inputFrame走到了基类的FrameDispatcher的inputFrame如下图
这里会走到这个FrameWriterInterfaceHelper的inputFrame
可以发现这里是一个callback 那么这个callback是在哪里设置的呢
frame.cpp的addDelegate这里 再看下谁调用了这里
直接给出来 MediaSink的addTrack函数 onTrackFrame那段就是这里设置的cb 已经加上注释
这样在去看调用堆栈就能看到走到onTrackFrame了 此函数根据不同的协议走到不同的inputFrame中 如下图
这里是RTSP的
这里跟据不同的encoder 音视频分开了 AAC走到AACRtpEncoder H264走到 H264RtpEncoder
终于走到写环形队列这里了
再看下视频的H264
视频也走到inputRtp这里了
通过两种方式对比发现 差异就在 onWrite函数这里