srs拉流的流程

概述

srs拉流的步骤前面几步和推流差不多,就不再赘述了。这边直接从playing函数调用开始开始讲起。srs推流的流程

  1. 在connect和create stream完毕后调用palying用于开始拉流。值得一提的是,在集群模式下,如果源站没有流这边会去判断别的源站是否有流。
  2. 在play的时候会开启新协程,SrsQueueRecvThread用于接受Message,处理对应的Message。
  3. 旧协程会从consumer队列中消费推流协程生产的Message,将它发送给拉流端。

开始play流程

在playing函数中,会启动一个新协程专门用来接受Message并且处理对饮的流程。旧协程会执行do_playing用于消费Message队列,往对端发送数据。

srs_error_t SrsRtmpConn::playing(SrsSource* source)
{
     
    if (!info->edge && _srs_config->get_vhost_origin_cluster(req->vhost) && source->inactive()) {
     
    /*这段代码是用来如果当前的源站没有流,去请求别的源站是否有流*/
    }

    /*用于接受Message并且进行处理*/
    SrsQueueRecvThread trd(consumer, rtmp, SRS_PERF_MW_SLEEP, _srs_context->get_id());
    if ((err = trd.start()) != srs_success) {
     
        return srs_error_wrap(err, "rtmp: start receive thread");
    }
    /*消费Message队列*/
    err = do_playing(source, consumer, &trd);
   
    return err;
}

旧的协程会等待事件通知,在队列有数据时去消费Message,最后发送给对端。

srs_error_t SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRecvThread* rtrd)
{
        
    while (true) {
     
       
        
#ifdef SRS_PERF_QUEUE_COND_WAIT
        // wait for message to incoming.
        // 等待队列中有数据生产
        consumer->wait(mw_msgs, mw_sleep);
#endif
        
        // 获取数据
        if ((err = consumer->dump_packets(&msgs, count)) != srs_success) {
     
            return srs_error_wrap(err, "rtmp: consumer dump packets");
        }

		// 发送数据
        if (user_specified_duration_to_stop) {
     
            if (duration >= req->duration) {
     
                return srs_error_new(ERROR_RTMP_DURATION_EXCEED, "rtmp: time %d up %d", srsu2msi(duration), srsu2msi(req->duration));
            }
        }
        
        // apply the minimal interval for delivery stream in srs_utime_t.
        if (send_min_interval > 0) {
     
            srs_usleep(send_min_interval);
        }
    }
    
    return err;
}

你可能感兴趣的:(rtmp,srs,rtmp,srs)