rtsp_read_header函数

static int rtsp_read_header(AVFormatContext *s,
                            AVFormatParameters *ap){

RTSPState *rt = s->priv_data;

该函数发起rtsp连接请求。

1 .打开rtsp对应的TCP连接

    /* open the tcp connexion */
    snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port);
    if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0)
        return AVERROR(EIO);
    rt->rtsp_hd = rtsp_hd;
    rt->seq = 0;

2. 发送OPTIONS命令,等待答复

 snprintf(cmd, sizeof(cmd),
                 "OPTIONS %s RTSP/1.0/r/n", s->filename);

....

rtsp_send_cmd(s, cmd, reply, NULL);

3. 发送DESCRIBE命令,等待答复

  snprintf(cmd, sizeof(cmd),
             "DESCRIBE %s RTSP/1.0/r/n"
             "Accept: application/sdp/r/n",
             s->filename);

....

 rtsp_send_cmd(s, cmd, reply, &content);

4. 解析SDP中的多媒体信息

 ret = sdp_parse(s, (const char *)content);
    av_freep(&content);

SDP中包含服务器的ip地址,RTP端口, RTCP端口, audio, video

例如:

An example SDP description is:
v=0
o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
s=SDP Seminar
i=A Seminar on the session description protocol
u=http://www.example.com/seminars/sdp.pdf
e=j.doe@example.com (Jane Doe)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 99
a=rtpmap:99 h263-1998/90000

如果SDP中包含多媒体信息(audio,video),那么构造对应的RTSPStream:

 case 'm':
        /* new stream */
        get_word(st_type, sizeof(st_type), &p);
        if (!strcmp(st_type, "audio")) {
            codec_type = CODEC_TYPE_AUDIO;---->audio
        } else if (!strcmp(st_type, "video")) {
            codec_type = CODEC_TYPE_VIDEO;----->video
        } else {
            return;
        }
        rtsp_st = av_mallocz(sizeof(RTSPStream));----分配RTSPStream结构
        if (!rtsp_st)
            return;
        rtsp_st->stream_index = -1;
        dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);

        ----加入大到rtsp_stream动态数组中

        rtsp_st->sdp_ip = s1->default_ip;
        rtsp_st->sdp_ttl = s1->default_ttl;

        get_word(buf1, sizeof(buf1), &p); /* port */
        rtsp_st->sdp_port = atoi(buf1);--------数据流对应的端口

        get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */

        /* XXX: handle list of formats */
        get_word(buf1, sizeof(buf1), &p); /* format list */
        rtsp_st->sdp_payload_type = atoi(buf1);//payload type

        if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
            /* no corresponding stream */

         如果payload type为mpeg2 ts流,怎么做???
        } else {

        否则,分配AVStream结构
            st = av_new_stream(s, 0);
            if (!st)
                return;
            st->priv_data = rtsp_st;
            rtsp_st->stream_index = st->index;
            st->codec->codec_type = codec_type;----->补充av stream对应的codecContext的codec_type
            if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
                /* if standard payload type, we can find the codec right now */

                 根据rtp的payload type,获取av stream对应的编解码信息(codec_type, codec_id)

                 rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);

           }
        }
        /* put a default control url */
        av_strlcpy(rtsp_st->control_url, s->filename, sizeof(rtsp_st->control_url));

case 'a':

        接下来分析媒体的attribute属性,rtsp协议里面定义了rtpmap属性,处理的方式:

    .....

 

        } else if (av_strstart(p, "rtpmap:", &p)) {
            /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
            get_word(buf1, sizeof(buf1), &p);
            payload_type = atoi(buf1);
            for(i = 0; i < s->nb_streams;i++) {
                st = s->streams[i];
                rtsp_st = st->priv_data;
                if (rtsp_st->sdp_payload_type == payload_type) {
                    sdp_parse_rtpmap(st->codec, rtsp_st, payload_type, p);
                }
            }

......

这段代码根据rtpmap里面指定的palod type和codec name为rtsp携带的数据找到codec,例如对于

a=rtpmap:99 h263-1998/90000

payload type为99, encoder name为h263-1998,速率为90KHZ,sdp_parse_rtpmap函数根据这个信息寻找对应的decoder,decoder的信息记录在AVCodecContext的codec_id和codec_type中。

 

5. 发送setup命令

参考make_setup_request

 

6. 发送PLAY命令,进入RTP数据传输阶段

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值