go srs 流媒体服务器_SRS流媒体服务器之RTMP推流消息处理(1)

本文深入解析SRS流媒体服务器RTMP推流消息处理流程,包括ffmpeg推流逻辑、meta data、audio data和video data的处理,以及gop cache的分析。介绍了数据从推流端到消费者的路径,强调了metadata和sequence header的发送时机,探讨了gop cache对延迟的影响,提出了是否只缓存I帧以优化秒开和延迟的问题。
摘要由CSDN通过智能技术生成

0.引言

阅读本文前,可以先阅读前面文章,能够帮助你更好理解本篇文章。文章列表如下:

SRS流媒体服务器之RTMP协议分析(2)

SRS流媒体框架分析(1)

SRS流媒体之RTMP推流框架分析(2)

SRS流媒体之RTMP拉流框架分析(3)

SRS流媒体服务器之RTMP协议分析(1)

简述SRS流媒体服务器相关技术

流媒体推拉流实战之RTMP协议分析(BAT面试官推荐)

流媒体服务器架构与应用分析

手把手搭建流媒体服务器详细步骤

手把手搭建FFmpeg的Windows环境

超详细手把手搭建在ubuntu系统的FFmpeg环境

HTTP实战之Wireshark抓包分析

本篇文章主要讲解以下内容:

(1)使用ffmpeg推流,理清数据处理逻辑。

(2)meta data 、audio data、video data是怎样发给消费者?

(3)讲清gop cache缓存分析。

1.RTMP推流消息处理流程(结合源码分析)

rtmp推流时的数据处理入口,函数间的调用关系如下图:

推流端把rtmp数据推上来后,需要调用SrsPublishRecvThread::consume(xxx)去处理和分发不同类型的数据,接着调用conn->handle_publish_message(xxx),继续调用process_publish_message(xxx),根据msg类型不同,分别调用on_meta_data,on_audio,on_video,对应的也要拷贝不同数据的头信息给消费者。

430d28d76d3b2cf75cd6825266851072.png

在这里,先回顾下前面的文章内容,SRS流媒体服务器中,正真去读取数据,是在SrsRecvThread::do_cycle,源码入下:

bdbd85f1f72eabcbc89c6da0ae75bd41.png

SrsRecvThread::do_cycle里调用consume,RTMP推流时的数据入口,如下函数,源码入下:

1e07c04be02685c37233f9644e0f6f92.png

在consume里调用handle_publish_message(_source,msg),处理控制命令消息以及调用process_publish_message(source, msg)处理音视频消息。处理完后,就存放在source执行的内存里,源码入下:

srs_error_t SrsSource::on_video(SrsCommonMessage* shared_video){    srs_error_t err = srs_success;        // monotically increase detect.    if (!mix_correct && is_monotonically_increase) {        if (last_packet_time > 0 && shared_video->header.timestamp < last_packet_time) {            is_monotonically_increase = false;            srs_warn("VIDEO: stream not monotonically increase, please open mix_correct.");        }    }    last_packet_time = shared_video->header.timestamp;        // drop any unknown header video.    // @see https://github.com/ossrs/srs/issues/421    if (!SrsFlvVideo::acceptable(shared_video->payload, shared_video->size)) {        char b0 = 0x00;        if (shared_video->size > 0) {            b0 = shared_video->payload[0];        }                srs_warn("drop unknown header video, size=%d, bytes[0]=%#x", shared_video->size, b0);        return err;    }        // convert shared_video to msg, user should not use shared_video again.    // the payload is transfer to msg, and set to NULL in shared_video.    SrsSharedPtrMessage msg;    if ((err = msg.create(shared_video)) != srs_success) {        return srs_error_wrap(err, "create message");    }        // directly process the audio message.    if (!mix_correct) {        return on_video_imp(&msg);    }        // insert msg to the queue.    mix_queue->push(msg.copy());        // fetch someone from mix queue.    SrsSharedPtrMessage* m = mix_queue->pop();    if (!m) {        return err;    }        // consume the monotonically increase message.    if (m->is_audio()) {        err = on_audio_imp(m);    } else {        err = on_video_imp(m);    }    srs_freep(m);        return err;}

在函数process_publish_message(source, msg)中处理音视频、onMetaData等数据消息,source->on_audio(msg),source->on_video(msg),rtmp->decode_message(msg, &pkt),source->on_edge_proxy_publish。由于onMetaData数据包会先过来,一般会先处理onMetaData。源码如下:

srs_error_t SrsSource::on_video_imp(SrsSharedPtrMessage* msg){    srs_error_t err = srs_success;        bool is_sequence_header = SrsFlvVideo::sh(msg->payload, msg->size);        // whether consumer should drop for the duplicated sequence header.    bool drop_for_reduce = false;    if (is_sequence_header && meta->previous_vsh() && _srs_confi
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值