⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsp.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 3 页
字号:
                if (av_open_input_file(&rtsp_st->ic, url, fmt, 0, NULL) < 0) {                    err = AVERROR_INVALIDDATA;                    goto fail;                }            }            break;        }    }    /* use callback if available to extend setup */    if (ff_rtsp_callback) {        if (ff_rtsp_callback(RTSP_ACTION_CLIENT_SETUP, rt->session_id,                              NULL, 0, rt->last_reply) < 0) {            err = AVERROR_INVALIDDATA;            goto fail;        }    }                             /* start playing */    snprintf(cmd, sizeof(cmd),              "PLAY %s RTSP/1.0\n",             s->filename);    rtsp_send_cmd(s, cmd, reply, NULL);    if (reply->status_code != RTSP_STATUS_OK) {        err = AVERROR_INVALIDDATA;        goto fail;    }    /* open TCP with bufferized input */    if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {        if (url_fdopen(&rt->rtsp_gb, rt->rtsp_hd) < 0) {            err = AVERROR_NOMEM;            goto fail;        }    }    return 0; fail:    for(i=0;i<s->nb_streams;i++) {        st = s->streams[i];        rtsp_st = st->priv_data;        if (rtsp_st) {            if (rtsp_st->ic)                av_close_input_file(rtsp_st->ic);        }        av_free(rtsp_st);    }    av_freep(&content);    url_close(rt->rtsp_hd);    return err;}static int tcp_read_packet(AVFormatContext *s,                           AVPacket *pkt){    RTSPState *rt = s->priv_data;    ByteIOContext *rtsp_gb = &rt->rtsp_gb;    int c, id, len, i, ret;    AVStream *st;    RTSPStream *rtsp_st;    char buf[RTP_MAX_PACKET_LENGTH]; redo:    for(;;) {        c = url_fgetc(rtsp_gb);        if (c == URL_EOF)            return AVERROR_IO;        if (c == '$')            break;    }    id = get_byte(rtsp_gb);    len = get_be16(rtsp_gb);    if (len > RTP_MAX_PACKET_LENGTH || len < 12)        goto redo;    /* get the data */    get_buffer(rtsp_gb, buf, len);        /* find the matching stream */    for(i = 0; i < s->nb_streams; i++) {        st = s->streams[i];        rtsp_st = st->priv_data;        if (i >= rtsp_st->interleaved_min &&             i <= rtsp_st->interleaved_max)             goto found;    }    goto redo; found:    ret = rtp_parse_packet(rtsp_st->ic, pkt, buf, len);    if (ret < 0)        goto redo;    pkt->stream_index = i;    return ret;}/* NOTE: output one packet at a time. May need to add a small fifo */static int udp_read_packet(AVFormatContext *s,                           AVPacket *pkt){    AVFormatContext *ic;    AVStream *st;    RTSPStream *rtsp_st;    fd_set rfds;    int fd1, fd2, fd_max, n, i, ret;    char buf[RTP_MAX_PACKET_LENGTH];    struct timeval tv;    for(;;) {        if (rtsp_abort_req)            return -EIO;        FD_ZERO(&rfds);        fd_max = -1;        for(i = 0; i < s->nb_streams; i++) {            st = s->streams[i];            rtsp_st = st->priv_data;            ic = rtsp_st->ic;            /* currently, we cannot probe RTCP handle because of blocking restrictions */            rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2);            if (fd1 > fd_max)                fd_max = fd1;            FD_SET(fd1, &rfds);        }        /* XXX: also add proper API to abort */        tv.tv_sec = 0;        tv.tv_usec = 500000;        n = select(fd_max + 1, &rfds, NULL, NULL, &tv);        if (n > 0) {            for(i = 0; i < s->nb_streams; i++) {                st = s->streams[i];                rtsp_st = st->priv_data;                ic = rtsp_st->ic;                rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2);                if (FD_ISSET(fd1, &rfds)) {                    ret = url_read(url_fileno(&ic->pb), buf, sizeof(buf));                    if (ret >= 0 &&                         rtp_parse_packet(ic, pkt, buf, ret) == 0) {                        pkt->stream_index = i;                        return ret;                    }                }            }        }    }}static int rtsp_read_packet(AVFormatContext *s,                            AVPacket *pkt){    RTSPState *rt = s->priv_data;    int ret;    switch(rt->protocol) {    default:    case RTSP_PROTOCOL_RTP_TCP:        ret = tcp_read_packet(s, pkt);        break;    case RTSP_PROTOCOL_RTP_UDP:        ret = udp_read_packet(s, pkt);        break;    }    return ret;}static int rtsp_read_close(AVFormatContext *s){    RTSPState *rt = s->priv_data;    AVStream *st;    RTSPStream *rtsp_st;    RTSPHeader reply1, *reply = &reply1;    int i;    char cmd[1024];    /* NOTE: it is valid to flush the buffer here */    if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {        url_fclose(&rt->rtsp_gb);    }    snprintf(cmd, sizeof(cmd),              "TEARDOWN %s RTSP/1.0\n",             s->filename);    rtsp_send_cmd(s, cmd, reply, NULL);    if (ff_rtsp_callback) {        ff_rtsp_callback(RTSP_ACTION_CLIENT_TEARDOWN, rt->session_id,                          NULL, 0, NULL);    }    for(i=0;i<s->nb_streams;i++) {        st = s->streams[i];        rtsp_st = st->priv_data;        if (rtsp_st) {            if (rtsp_st->ic)                av_close_input_file(rtsp_st->ic);        }        av_free(rtsp_st);    }    url_close(rt->rtsp_hd);    return 0;}static AVInputFormat rtsp_demux = {    "rtsp",    "RTSP input format",    sizeof(RTSPState),    rtsp_probe,    rtsp_read_header,    rtsp_read_packet,    rtsp_read_close,    .flags = AVFMT_NOFILE,};static int sdp_probe(AVProbeData *p1){    const char *p;    /* we look for a line beginning "c=IN IP4" */    p = p1->buf;    while (*p != '\0') {        if (strstart(p, "c=IN IP4", NULL))            return AVPROBE_SCORE_MAX / 2;        p = strchr(p, '\n');        if (!p)            break;        p++;        if (*p == '\r')            p++;    }    return 0;}#define SDP_MAX_SIZE 8192static int sdp_read_header(AVFormatContext *s,                           AVFormatParameters *ap){    AVStream *st;    RTSPStream *rtsp_st;    int size, i, err;    char *content;    char url[1024];    /* read the whole sdp file */    /* XXX: better loading */    content = av_malloc(SDP_MAX_SIZE);    size = get_buffer(&s->pb, content, SDP_MAX_SIZE - 1);    if (size <= 0) {        av_free(content);        return AVERROR_INVALIDDATA;    }    content[size] ='\0';    sdp_parse(s, content);    av_free(content);    /* open each RTP stream */    for(i=0;i<s->nb_streams;i++) {        st = s->streams[i];        rtsp_st = st->priv_data;                snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d",                  inet_ntoa(rtsp_st->sdp_ip),                  rtsp_st->sdp_port,                 rtsp_st->sdp_ttl);        if (av_open_input_file(&rtsp_st->ic, url, &rtp_demux, 0, NULL) < 0) {            err = AVERROR_INVALIDDATA;            goto fail;        }    }    return 0; fail:    for(i=0;i<s->nb_streams;i++) {        st = s->streams[i];        rtsp_st = st->priv_data;        if (rtsp_st) {            if (rtsp_st->ic)                av_close_input_file(rtsp_st->ic);        }        av_free(rtsp_st);    }    return err;}static int sdp_read_packet(AVFormatContext *s,                            AVPacket *pkt){    return udp_read_packet(s, pkt);}static int sdp_read_close(AVFormatContext *s){    AVStream *st;    RTSPStream *rtsp_st;    int i;    for(i=0;i<s->nb_streams;i++) {        st = s->streams[i];        rtsp_st = st->priv_data;        if (rtsp_st) {            if (rtsp_st->ic)                av_close_input_file(rtsp_st->ic);        }        av_free(rtsp_st);    }    return 0;}static AVInputFormat sdp_demux = {    "sdp",    "SDP",    sizeof(RTSPState),    sdp_probe,    sdp_read_header,    sdp_read_packet,    sdp_read_close,};/* dummy redirector format (used directly in av_open_input_file now) */static int redir_probe(AVProbeData *pd){    const char *p;    p = pd->buf;    while (redir_isspace(*p))        p++;    if (strstart(p, "http://", NULL) ||        strstart(p, "rtsp://", NULL))        return AVPROBE_SCORE_MAX;    return 0;}/* called from utils.c */int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f){    char buf[4096], *q;    int c;    AVFormatContext *ic = NULL;    /* parse each URL and try to open it */    c = url_fgetc(f);    while (c != URL_EOF) {        /* skip spaces */        for(;;) {            if (!redir_isspace(c))                break;            c = url_fgetc(f);        }        if (c == URL_EOF)            break;        /* record url */        q = buf;        for(;;) {            if (c == URL_EOF || redir_isspace(c))                break;            if ((q - buf) < sizeof(buf) - 1)                *q++ = c;            c = url_fgetc(f);        }        *q = '\0';        //printf("URL='%s'\n", buf);        /* try to open the media file */        if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0)            break;    }    *ic_ptr = ic;    if (!ic)        return AVERROR_IO;    else        return 0;}AVInputFormat redir_demux = {    "redir",    "Redirector format",    0,    redir_probe,    NULL,    NULL,    NULL,};int rtsp_init(void){    av_register_input_format(&rtsp_demux);    av_register_input_format(&redir_demux);    av_register_input_format(&sdp_demux);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -