SRS流媒体服务器之HTTP-FLV框架分析( 五 )

从源码中看出,这里有个new SrsTsStreamEncoder,这个是用来合成flv数据,以供拉流端使用 。
接下来打印断点调试看看 。输入命令如下:
b SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
界面如下:

SRS流媒体服务器之HTTP-FLV框架分析

文章插图
 
输入命令,继续运行:
c
这时候开启拉流端,再输入命令:
bt
查看调用栈,如下界面:
SRS流媒体服务器之HTTP-FLV框架分析

文章插图
 
(1)st_thread_create,在sched.c:616行 。
(2)_st_thread_main,在sched.c:337行 。
(3)函数SrsSTCoroutine::pfn,在
src/app/srs_app_st.cpp:213行 。
(4)函数SrsSTCoroutine::cycle,在
src/app/srs_app_st.cpp:198行 。
(5)函数SrsConnection::cycle,在
src/app/srs_app_conn.cpp:171行 。
(6)函数SrsHttpConn::do_cycle,在
src/app/srs_app_http_conn.cpp:133行 。
(7)函数
SrsHttpConn::process_request,在src/app/srs_app_http_conn.cpp:161行 。
(8)函数
SrsHttpCorsMux::server_http,在src/protocol/srs_http_stack.cpp:859行 。
(9)函数
SrsHttpServer::server_http,在src/app/srs_app_http_conn.cpp:300行 。
(10)函数
SrsHttpServerMux::server_http,在src/protocol/srs_http_stack.cpp:711行 。
(11)函数
SrsLiveStream::server_http,在src/app/srs_app_http_stream.cpp:544行 。
(12)函数
SrsLiveStream::do_serve_http,在src/app/srs_app_http_stream.cpp:552行 。
 
当拉流端通过onsumer->dump_packets(&msgs, count)读出消息后,然后就用ffe->write_tags(msgs.msgs, count)绑定一个Encoder(这里就指的是用flv封装),源代码如下图:

SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)函数下 。
int count = 0;if ((err = consumer->dump_packets(&msgs, count)) != srs_success) {return srs_error_wrap(err, "consumer dump packets");}if (count <= 0) {// Directly use sleep, donot use consumer wait, because we couldn't awake consumer.srs_usleep(mw_sleep);// ignore when nothing got.continue;}if (pprint->can_print()) {srs_trace("-> " SRS_CONSTS_LOG_HTTP_STREAM " http: got %d msgs, age=%d, min=%d, mw=%d",count, pprint->age(), SRS_PERF_MW_MIN_MSGS, srsu2msi(mw_sleep));}// sendout all messages.if (ffe) {err = ffe->write_tags(msgs.msgs, count);} else {err = streaming_send_messages(enc, msgs.msgs, count);} 
对应源码文件为Srs_app_source.cpp,拉流端通过SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count),读取消息 。关于这个函数的调用,在前面文章有更详细的分析 。
srs_error_t SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count){srs_error_t err = srs_success;srs_assert(count >= 0);srs_assert(msgs->max > 0);// the count used as input to reset the max if positive.int max = count? srs_min(count, msgs->max) : msgs->max;// the count specifies the max acceptable count,// here maybe 1+, and we must set to 0 when got nothing.count = 0;if (should_update_source_id) {srs_trace("update source_id=%d[%d]", source->source_id(), source->source_id());should_update_source_id = false;}// paused, return nothing.if (paused) {return err;}// pump msgs from queue.if ((err = queue->dump_packets(max, msgs->msgs, count)) != srs_success) {return srs_error_wrap(err, "dump packets");}return err;}SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count)在源码Srs_app_http_stream.cpp,调用函数ffe->write_tags(msgs.msgs, count)(包括写头和数据),绑定Encoder,这里指的是封装格式 。详细分析,会在后面的文章继续分析,源码如下:
srs_error_t SrsFlvStreamEncoder::write_tags(SrsSharedPtrMessage** msgs, int count){srs_error_t err = srs_success;// For https://github.com/ossrs/srs/issues/939if (!header_written) {bool has_video = false;bool has_audio = false;for (int i = 0; i < count && (!has_video || !has_audio); i++) {SrsSharedPtrMessage* msg = msgs[i];if (msg->is_video()) {has_video = true;} else if (msg->is_audio()) {has_audio = true;}}// Drop data if no A+V.if (!has_video && !has_audio) {return err;}if ((err = write_header(has_video, has_audio))!= srs_success) {return srs_error_wrap(err, "write header");}}return enc->write_tags(msgs, count);} 
8.拉流时,SRS流媒体服务器发送数据给客户端
调试界面如下:
SRS流媒体服务器之HTTP-FLV框架分析

文章插图
 
在SRS流媒体服务器给客户端发送数据的函数,打断点,跟踪函数调用流程,输入命令如下:
b SrsHttpResponseWriter::writev
(1)包括了前面连接过程的连接,这些流程就反应了函数调用的关系(调用关系是从下至上,即从15到0),跟踪流程如下:


推荐阅读