Esempio n. 1
0
static int open_input(struct variant *var)
{
    AVDictionary *opts = NULL;
    int ret;
    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
    av_dict_set(&opts, "seekable", "0", 0);
    if (seg->key_type == KEY_NONE) {
        ret = ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
                          &var->parent->interrupt_callback, &opts);
        goto cleanup;
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        if (strcmp(seg->key, var->key_url)) {
            URLContext *uc;
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
                           &var->parent->interrupt_callback, &opts) == 0) {
                if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                    != sizeof(var->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, var->key, sizeof(var->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ,
                               &var->parent->interrupt_callback)) < 0)
            goto cleanup;
        av_opt_set(var->input->priv_data, "key", key, 0);
        av_opt_set(var->input->priv_data, "iv", iv, 0);
        /* Need to repopulate options */
        av_dict_free(&opts);
        av_dict_set(&opts, "seekable", "0", 0);
        if ((ret = ffurl_connect(var->input, &opts)) < 0) {
            ffurl_close(var->input);
            var->input = NULL;
            goto cleanup;
        }
        ret = 0;
    }
    else
      ret = AVERROR(ENOSYS);

cleanup:
    av_dict_free(&opts);
    return ret;
}
Esempio n. 2
0
static int gopher_open(URLContext *h, const char *uri, int flags)
{
    GopherContext *s = h->priv_data;
    char hostname[1024], auth[1024], path[1024], buf[1024];
    int port, err;

    h->is_streamed = 1;

    /* needed in any case to build the host string */
    av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
                 path, sizeof(path), uri);

    if (port < 0)
        port = 70;

    ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);

    s->hd = NULL;
    err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
                     &h->interrupt_callback, NULL);
    if (err < 0)
        goto fail;

    if ((err = gopher_connect(h, path)) < 0)
        goto fail;
    return 0;
 fail:
    gopher_close(h);
    return err;
}
Esempio n. 3
0
static int cache_open(URLContext *h, const char *arg, int flags)
{
    int access;
    const char *buffername;
    Context *c;

    c = av_mallocz(sizeof(Context));
    if (!c) {
        return AVERROR(ENOMEM);
    }
    h->priv_data = c;

    av_strstart(arg, "cache:", &arg);

    c->fd = av_tempfile("ffcache", &buffername, 0, h);
    if (c->fd < 0){
        av_log(h, AV_LOG_ERROR, "Failed to create tempfile\n");
        return c->fd;
    }

    unlink(buffername);
    av_free(buffername);

    return ffurl_open(&c->inner, arg, flags);
}
Esempio n. 4
0
static int mtc_open(URLContext * h, const char *uri, int flags)
{
	char path[1024];
    char buf[1024];
    const char *p;
	int error;
	MTCContext *c = h->priv_data;
	av_url_split(NULL, 0, NULL, 0, c->hostname, sizeof(c->hostname), &c->server_control_port, path, sizeof(path), uri);

	p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "authorization", p)) {
			av_strlcpy(c->credencials, buf, sizeof(c->credencials));	
		}
	}

    if (!s->conn_control) {
		ff_url_join(buf, sizeof(buf), "tcp", NULL, c->hostname, c->server_control_port,NULL);
		error = ffurl_open(&c->conn_control, buf, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, NULL);
		if (erro < 0) {
			av_log(h, AV_LOG_ERROR, "Cannot open control connection\n");
			return error;
		}
	}
	//授权
	return 0;
}
static int rtmpe_open(URLContext *h, const char *uri, int flags)
{
    RTMPEContext *rt = h->priv_data;
    char host[256], url[1024];
    int ret, port;

    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri);

    if (rt->tunneling) {
        if (port < 0)
            port = 80;
        ff_url_join(url, sizeof(url), "ffrtmphttp", NULL, host, port, NULL);
    } else {
        if (port < 0)
            port = 1935;
        ff_url_join(url, sizeof(url), "tcp", NULL, host, port, NULL);
    }

    /* open the tcp or ffrtmphttp connection */
    if ((ret = ffurl_open(&rt->stream, url, AVIO_FLAG_READ_WRITE,
                          &h->interrupt_callback, NULL)) < 0) {
        rtmpe_close(h);
        return ret;
    }

    return 0;
}
Esempio n. 6
0
static int srtp_open(URLContext *h, const char *uri, int flags)
{
    SRTPProtoContext *s = h->priv_data;
    char hostname[256], buf[1024], path[1024];
    int rtp_port, ret;

    if (s->out_suite && s->out_params)
        if ((ret = ff_srtp_set_crypto(&s->srtp_out, s->out_suite, s->out_params)) < 0)
            goto fail;
    if (s->in_suite && s->in_params)
        if ((ret = ff_srtp_set_crypto(&s->srtp_in, s->in_suite, s->in_params)) < 0)
            goto fail;

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
                 path, sizeof(path), uri);
    ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path);
    if ((ret = ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL)) < 0)
        goto fail;

    h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size,
                               sizeof(s->encryptbuf)) - 14;
    h->is_streamed = 1;
    return 0;

fail:
    srtp_close(h);
    return ret;
}
Esempio n. 7
0
static int http_listen(URLContext *h, const char *uri, int flags,
                       AVDictionary **options) {
    HTTPContext *s = h->priv_data;
    int ret;
    static const char header[] = "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n";
    char hostname[1024], proto[10];
    char lower_url[100];
    const char *lower_proto = "tcp";
    int port, new_location;
    av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
                 NULL, 0, uri);
    if (!strcmp(proto, "https"))
        lower_proto = "tls";
    ff_url_join(lower_url, sizeof(lower_url), lower_proto, NULL, hostname, port,
                NULL);
    av_dict_set(options, "listen", "1", 0);
    if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
                          &h->interrupt_callback, options)) < 0)
        goto fail;
    if ((ret = http_read_header(h, &new_location)) < 0)
         goto fail;
    if ((ret = ffurl_write(s->hd, header, strlen(header))) < 0)
         goto fail;
    return 0;

fail:
    handle_http_errors(h, ret);
    av_dict_free(&s->chained_options);
    return ret;
}
static int md5_close(URLContext *h)
{
    struct MD5Context *c = h->priv_data;
    const char *filename = h->filename;
    uint8_t md5[16], buf[64];
    URLContext *out;
    int i, err = 0;

    av_md5_final(c->md5, md5);
    for (i = 0; i < sizeof(md5); i++)
        snprintf(buf + i*2, 3, "%02x", md5[i]);
    buf[i*2] = '\n';

    av_strstart(filename, "md5:", &filename);

    if (*filename) {
        err = ffurl_open(&out, filename, AVIO_FLAG_WRITE,
                         &h->interrupt_callback, NULL);
        if (err)
            return err;
        err = ffurl_write(out, buf, i*2+1);
        ffurl_close(out);
    } else {
        if (fwrite(buf, 1, i*2+1, stdout) < i*2+1)
            err = AVERROR(errno);
    }

    av_freep(&c->md5);

    return err;
}
Esempio n. 9
0
static int cache_open(URLContext *h, const char *arg, int flags)
{
	int ret;

    Context *c= (Context*)h->priv_data;

    c->local_buffer_path = getLocalCachePath(h);

    if(!c->local_buffer_path){
    	c->fd = -1;
    	return -1;
    }

    av_strstart(arg, "ucache:", &arg);

    av_log(h, AV_LOG_INFO, "cache_open:local_buffer_path:%s\n",c->local_buffer_path);

    c->fd = open(c->local_buffer_path, O_RDWR |  O_CREAT | O_TRUNC, 0666);
    if (c->fd < 0){
        av_log(h, AV_LOG_ERROR, "ucache_protocol.cache_open:Failed to create tempfile\n");
        //return c->fd;
    }

    ret = ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL);

    if(ret && c->fd >= 0){
    	//删除文件
		close(c->fd);
		c->fd = -1;
		unlink(c->local_buffer_path);
    }
    return ret;

}
Esempio n. 10
0
static int md5_close(URLContext *h)
{
    const char *filename = h->filename;
    uint8_t md5[16], buf[64];
    URLContext *out;
    int i, err = 0;

    av_md5_final(h->priv_data, md5);
    for (i = 0; i < sizeof(md5); i++)
        snprintf(buf + i*2, 3, "%02x", md5[i]);
    buf[i*2] = '\n';

    av_strstart(filename, "md5:", &filename);

    if (*filename) {
        err = ffurl_open(&out, filename, AVIO_WRONLY);
        if (err)
            return err;
        err = ffurl_write(out, buf, i*2+1);
        ffurl_close(out);
    } else {
        if (fwrite(buf, 1, i*2+1, stdout) < i*2+1)
            err = AVERROR(errno);
    }

    return err;
}
Esempio n. 11
0
/*
* open fec connect
*/
int fec_connect(AVFormatContext *s,RTSPStream* rtsp_fec){
    int err = 0;
    av_log(NULL,AV_LOG_ERROR,"%s:s->filename = %s",__FUNCTION__,s->filename);

    if (!ff_network_init()){
        av_log(NULL,AV_LOG_ERROR,"%s:ff_network_init fail",__FUNCTION__);
        return AVERROR(EIO);
    }
    
    int flags = AVIO_FLAG_READ;
    av_log(NULL,AV_LOG_ERROR,"%s:url = %s",__FUNCTION__,rtsp_fec->control_url);
    if (ffurl_open(&rtsp_fec->rtp_handle, rtsp_fec->control_url, flags,
                   &s->interrupt_callback, NULL) < 0) {
        err = AVERROR_INVALIDDATA;
        av_log(NULL,AV_LOG_ERROR,"%s: ffurl_open fail",__FUNCTION__);
        goto fail;
    }
    if ((err = ff_rtsp_open_transport_ctx(s, rtsp_fec)))
        goto fail;

    av_log(NULL,AV_LOG_ERROR,"%s: OK********",__FUNCTION__);
    return 0;
fail:
    ff_network_close();
    return -1;
}
Esempio n. 12
0
static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
{
    const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
    char hostname[1024], hoststr[1024], proto[10];
    char auth[1024], proxyauth[1024] = "";
    char path1[MAX_URL_SIZE];
    char buf[1024], urlbuf[MAX_URL_SIZE];
    int port, use_proxy, err, location_changed = 0;
    HTTPContext *s = h->priv_data;

    av_url_split(proto, sizeof(proto), auth, sizeof(auth),
                 hostname, sizeof(hostname), &port,
                 path1, sizeof(path1), s->location);
    ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);

    proxy_path = getenv("http_proxy");
    use_proxy  = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
                 proxy_path && av_strstart(proxy_path, "http://", NULL);

    if (!strcmp(proto, "https")) {
        lower_proto = "tls";
        use_proxy   = 0;
        if (port < 0)
            port = 443;
    }
    if (port < 0)
        port = 80;

    if (path1[0] == '\0')
        path = "/";
    else
        path = path1;
    local_path = path;
    if (use_proxy) {
        /* Reassemble the request URL without auth string - we don't
         * want to leak the auth to the proxy. */
        ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s",
                    path1);
        path = urlbuf;
        av_url_split(NULL, 0, proxyauth, sizeof(proxyauth),
                     hostname, sizeof(hostname), &port, NULL, 0, proxy_path);
    }

    ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);

    if (!s->hd) {
        err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
                         &h->interrupt_callback, options);
        if (err < 0)
            return err;
    }

    err = http_connect(h, path, local_path, hoststr,
                       auth, proxyauth, &location_changed);
    if (err < 0)
        return err;

    return location_changed;
}
Esempio n. 13
0
File: avio.c Progetto: andoma/libav
int url_exist(const char *filename)
{
    URLContext *h;
    if (ffurl_open(&h, filename, AVIO_FLAG_READ) < 0)
        return 0;
    ffurl_close(h);
    return 1;
}
Esempio n. 14
0
static int open_input(struct variant *var)
{
    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
    if (seg->key_type == KEY_NONE) {
        return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ);
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        int ret;
        if (strcmp(seg->key, var->key_url)) {
            URLContext *uc;
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) {
                if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                    != sizeof(var->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, var->key, sizeof(var->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0)
            return ret;
        av_set_string3(var->input->priv_data, "key", key, 0, NULL);
        av_set_string3(var->input->priv_data, "iv", iv, 0, NULL);
        if ((ret = ffurl_connect(var->input)) < 0) {
            ffurl_close(var->input);
            var->input = NULL;
            return ret;
        }
        return 0;
    }
    return AVERROR(ENOSYS);
}
static int applehttp_read(URLContext *h, uint8_t *buf, int size)
{
    AppleHTTPContext *s = h->priv_data;
    const char *url;
    int ret;

start:
    if (s->seg_hd) {
        ret = ffurl_read(s->seg_hd, buf, size);
        if (ret > 0)
            return ret;
    }
    if (s->seg_hd) {
        ffurl_close(s->seg_hd);
        s->seg_hd = NULL;
        s->cur_seq_no++;
    }
retry:
    if (!s->finished) {
        int64_t now = av_gettime();
        if (now - s->last_load_time >= s->target_duration*1000000)
            if ((ret = parse_playlist(h, s->playlisturl)) < 0)
                return ret;
    }
    if (s->cur_seq_no < s->start_seq_no) {
        av_log(h, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlist\n",
               s->start_seq_no - s->cur_seq_no);
        s->cur_seq_no = s->start_seq_no;
    }
    if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
        if (s->finished)
            return AVERROR_EOF;
        while (av_gettime() - s->last_load_time < s->target_duration*1000000) {
            if (ff_check_interrupt(&h->interrupt_callback))
                return AVERROR_EXIT;
            usleep(100*1000);
        }
        goto retry;
    }
    url = s->segments[s->cur_seq_no - s->start_seq_no]->url,
    av_log(h, AV_LOG_DEBUG, "opening %s\n", url);
    ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ,
                     &h->interrupt_callback, NULL);
    if (ret < 0) {
        if (ff_check_interrupt(&h->interrupt_callback))
            return AVERROR_EXIT;
        av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url);
        s->cur_seq_no++;
        goto retry;
    }
    goto start;
}
Esempio n. 16
0
File: hls.c Progetto: lihp1603/libav
static int open_url(HLSContext *c, URLContext **uc, const char *url)
{
    AVDictionary *tmp = NULL;
    int ret;

    av_dict_copy(&tmp, c->avio_opts, 0);

    ret = ffurl_open(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);

    av_dict_free(&tmp);

    return ret;
}
Esempio n. 17
0
File: tls.c Progetto: AVLeo/libav
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
{
    int port;
    const char *p;
    char buf[200], opts[50] = "";
    struct addrinfo hints = { 0 }, *ai = NULL;
    const char *proxy_path;
    int use_proxy;

    if (c->listen)
        snprintf(opts, sizeof(opts), "?listen=1");

    av_url_split(NULL, 0, NULL, 0, c->host, sizeof(c->host), &port, NULL, 0, uri);

    p = strchr(uri, '?');

    if (!p) {
        p = opts;
    } else {
        if (av_find_info_tag(opts, sizeof(opts), "listen", p))
            c->listen = 1;
    }

    ff_url_join(buf, sizeof(buf), "tcp", NULL, c->host, port, "%s", p);

    hints.ai_flags = AI_NUMERICHOST;
    if (!getaddrinfo(c->host, NULL, &hints, &ai)) {
        c->numerichost = 1;
        freeaddrinfo(ai);
    }

    proxy_path = getenv("http_proxy");
    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), c->host) &&
                proxy_path && av_strstart(proxy_path, "http://", NULL);

    if (use_proxy) {
        char proxy_host[200], proxy_auth[200], dest[200];
        int proxy_port;
        av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth),
                     proxy_host, sizeof(proxy_host), &proxy_port, NULL, 0,
                     proxy_path);
        ff_url_join(dest, sizeof(dest), NULL, NULL, c->host, port, NULL);
        ff_url_join(buf, sizeof(buf), "httpproxy", proxy_auth, proxy_host,
                    proxy_port, "/%s", dest);
    }

    return ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE,
                      &parent->interrupt_callback, options, parent->protocols, parent);
}
Esempio n. 18
0
static int cache_open(URLContext *h, const char *arg, int flags)
{
    const char *buffername;
    Context *c= (Context *)h->priv_data;

    av_strstart(arg, "cache:", &arg);

    c->fd = av_tempfile("ffcache", (char **)&buffername, 0, h);
    if (c->fd < 0){
        av_log(h, AV_LOG_ERROR, "Failed to create tempfile\n");
        return c->fd;
    }

    unlink(buffername);
    av_freep(&buffername);

    return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL);
}
bool StreamingRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
{
    avcodeclock->lock();
    av_register_all();
    avcodeclock->unlock();
    RingBuffer::AVFormatInitNetwork();

    rwlock.lockForWrite();

    safefilename = lfilename;
    filename = lfilename;

    // TODO check whether local area file

    QUrl url = filename;
    if (url.path().endsWith(QLatin1String("m3u8"), Qt::CaseInsensitive))
    {
        url.setScheme("hls+http");
    }

    int res = ffurl_open(&m_context, url.toString().toLatin1(), AVIO_FLAG_READ,
                         NULL, NULL);
    if (res >=0 && m_context &&
        !m_context->is_streamed && ffurl_seek(m_context, 0, SEEK_SET) >= 0)
    {
        m_streamed   = false;
        m_allowSeeks = true;
    }

    LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying %1 (allow seeks: %2")
        .arg(filename).arg(m_allowSeeks));

    rwlock.unlock();

    if (res < 0 || !m_context)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to open stream (error %1)") .arg(res));
        return false;
    }

    return true;
}
Esempio n. 20
0
File: crypto.c Progetto: AVLeo/libav
static int crypto_open(URLContext *h, const char *uri, int flags)
{
    const char *nested_url;
    int ret = 0;
    CryptoContext *c = h->priv_data;

    if (!av_strstart(uri, "crypto+", &nested_url) &&
        !av_strstart(uri, "crypto:", &nested_url)) {
        av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
        ret = AVERROR(EINVAL);
        goto err;
    }

    if (c->keylen < BLOCKSIZE || c->ivlen < BLOCKSIZE) {
        av_log(h, AV_LOG_ERROR, "Key or IV not set\n");
        ret = AVERROR(EINVAL);
        goto err;
    }
    if (flags & AVIO_FLAG_WRITE) {
        av_log(h, AV_LOG_ERROR, "Only decryption is supported currently\n");
        ret = AVERROR(ENOSYS);
        goto err;
    }
    if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ,
                          &h->interrupt_callback, NULL, h->protocols, h)) < 0) {
        av_log(h, AV_LOG_ERROR, "Unable to open input\n");
        goto err;
    }
    c->aes = av_aes_alloc();
    if (!c->aes) {
        ret = AVERROR(ENOMEM);
        goto err;
    }

    av_aes_init(c->aes, c->key, 128, 1);

    h->is_streamed = 1;

err:
    return ret;
}
Esempio n. 21
0
static int gopher_open(URLContext *h, const char *uri, int flags)
{
    GopherContext *s;
    char hostname[1024], auth[1024], path[1024], buf[1024];
    int port, err;

    h->is_streamed = 1;

    s = av_malloc(sizeof(GopherContext));
    if (!s)
    {
        return AVERROR(ENOMEM);
    }
    h->priv_data = s;

    /* needed in any case to build the host string */
    av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
                 path, sizeof(path), uri);

    if (port < 0)
        port = 70;

    ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);

    s->hd = NULL;
    err = ffurl_open(&s->hd, buf, AVIO_RDWR);
    if (err < 0)
        goto fail;

    if ((err = gopher_connect(h, path)) < 0)
        goto fail;
    return 0;
fail:
    gopher_close(h);
    return err;
}
Esempio n. 22
0
static int rtsp_listen(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    char host[128], path[512], auth[128];
    char uri[500];
    int port;
    char tcpname[500];
    unsigned char rbuf[4096];
    unsigned char method[10];
    int rbuflen = 0;
    int ret;
    enum RTSPMethod methodcode;

    /* extract hostname and port */
    av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
                 path, sizeof(path), s->filename);

    /* ff_url_join. No authorization by now (NULL) */
    ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, host,
                port, "%s", path);

    if (port < 0)
        port = RTSP_DEFAULT_PORT;

    /* Create TCP connection */
    ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
                "?listen&listen_timeout=%d", rt->initial_timeout * 1000);

    if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
                         &s->interrupt_callback, NULL)) {
        av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
        return ret;
    }
    rt->state       = RTSP_STATE_IDLE;
    rt->rtsp_hd_out = rt->rtsp_hd;
    for (;;) { /* Wait for incoming RTSP messages */
        ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
        if (ret < 0)
            return ret;
        ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
                                 sizeof(method), &methodcode);
        if (ret) {
            av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
            return ret;
        }

        if (methodcode == ANNOUNCE) {
            ret       = rtsp_read_announce(s);
            rt->state = RTSP_STATE_PAUSED;
        } else if (methodcode == OPTIONS) {
            ret = rtsp_read_options(s);
        } else if (methodcode == RECORD) {
            ret = rtsp_read_record(s);
            if (!ret)
                return 0; // We are ready for streaming
        } else if (methodcode == SETUP)
            ret = rtsp_read_setup(s, host, uri);
        if (ret) {
            ffurl_close(rt->rtsp_hd);
            return AVERROR_INVALIDDATA;
        }
    }
    return 0;
}
Esempio n. 23
0
static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
{
    RTSPState *rt             = s->priv_data;
    RTSPMessageHeader request = { 0 };
    int ret                   = 0;
    char url[1024];
    RTSPStream *rtsp_st;
    char responseheaders[1024];
    int localport    = -1;
    int transportidx = 0;
    int streamid     = 0;

    ret = rtsp_read_request(s, &request, "SETUP");
    if (ret)
        return ret;
    rt->seq++;
    if (!request.nb_transports) {
        av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
        return AVERROR_INVALIDDATA;
    }
    for (transportidx = 0; transportidx < request.nb_transports;
         transportidx++) {
        if (!request.transports[transportidx].mode_record ||
            (request.transports[transportidx].lower_transport !=
             RTSP_LOWER_TRANSPORT_UDP &&
             request.transports[transportidx].lower_transport !=
             RTSP_LOWER_TRANSPORT_TCP)) {
            av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
                   " protocol not supported (yet)\n");
            return AVERROR_INVALIDDATA;
        }
    }
    if (request.nb_transports > 1)
        av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
               "using first of all\n");
    for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
        if (!strcmp(rt->rtsp_streams[streamid]->control_url,
                    controlurl))
            break;
    }
    if (streamid == rt->nb_rtsp_streams) {
        av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
        return AVERROR_STREAM_NOT_FOUND;
    }
    rtsp_st   = rt->rtsp_streams[streamid];
    localport = rt->rtp_port_min;

    if (request.transports[0].lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
        rt->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
        if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
            return ret;
        }
        rtsp_st->interleaved_min = request.transports[0].interleaved_min;
        rtsp_st->interleaved_max = request.transports[0].interleaved_max;
        snprintf(responseheaders, sizeof(responseheaders), "Transport: "
                 "RTP/AVP/TCP;unicast;mode=receive;interleaved=%d-%d"
                 "\r\n", request.transports[0].interleaved_min,
                 request.transports[0].interleaved_max);
    } else {
        do {
            ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
            av_dlog(s, "Opening: %s", url);
            ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
                             &s->interrupt_callback, NULL);
            if (ret)
                localport += 2;
        } while (ret || localport > rt->rtp_port_max);
        if (localport > rt->rtp_port_max) {
            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
            return ret;
        }

        av_dlog(s, "Listening on: %d",
                ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle));
        if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
            return ret;
        }

        localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
        snprintf(responseheaders, sizeof(responseheaders), "Transport: "
                 "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
                 "client_port=%d-%d;server_port=%d-%d\r\n",
                 host, request.transports[0].client_port_min,
                 request.transports[0].client_port_max, localport,
                 localport + 1);
    }

    /* Establish sessionid if not previously set */
    /* Put this in a function? */
    /* RFC 2326: session id must be at least 8 digits */
    while (strlen(rt->session_id) < 8)
        av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());

    av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
                rt->session_id);
    /* Send Reply */
    rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);

    rt->state = RTSP_STATE_PAUSED;
    return 0;
}
Esempio n. 24
0
static int rtp_open(URLContext *h, const char *uri, int flags)
{
    RTPContext *s = h->priv_data;
    int rtp_port, rtcp_port,
        ttl, connect,
        local_rtp_port, local_rtcp_port, max_packet_size;
    char hostname[256];
    char buf[1024];
    char path[1024];
    const char *p;

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
                 path, sizeof(path), uri);
    /* extract parameters */
    ttl = -1;
    rtcp_port = rtp_port+1;
    local_rtp_port = -1;
    local_rtcp_port = -1;
    max_packet_size = -1;
    connect = 0;

    p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
            ttl = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
            rtcp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
            local_rtp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
            local_rtp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
            local_rtcp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
            max_packet_size = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
            connect = strtol(buf, NULL, 10);
        }
    }

    build_udp_url(buf, sizeof(buf),
                  hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
                  connect);
    if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
        goto fail;
    if (local_rtp_port>=0 && local_rtcp_port<0)
        local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1;

    build_udp_url(buf, sizeof(buf),
                  hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
                  connect);
    if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
        goto fail;

    /* just to ease handle access. XXX: need to suppress direct handle
       access */
    s->rtp_fd = ffurl_get_file_handle(s->rtp_hd);
    s->rtcp_fd = ffurl_get_file_handle(s->rtcp_hd);

    h->max_packet_size = s->rtp_hd->max_packet_size;
    h->is_streamed = 1;
    return 0;

 fail:
    if (s->rtp_hd)
        ffurl_close(s->rtp_hd);
    if (s->rtcp_hd)
        ffurl_close(s->rtcp_hd);
    return AVERROR(EIO);
}
Esempio n. 25
0
static int mms_open(URLContext *h, const char *uri, int flags)
{
    MMSTContext *mmst;
    MMSContext *mms;
    int port, err;
    char tcpname[256];

    h->is_streamed = 1;
    mmst = h->priv_data = av_mallocz(sizeof(MMSTContext));
    if (!h->priv_data)
        return AVERROR(ENOMEM);
    mms = &mmst->mms;

    // only for MMS over TCP, so set proto = NULL
    av_url_split(NULL, 0, NULL, 0,
                 mmst->host, sizeof(mmst->host), &port, mmst->path,
                 sizeof(mmst->path), uri);

    if(port < 0)
        port = 1755; // defaut mms protocol port

    // establish tcp connection.
    ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL);
    err = ffurl_open(&mms->mms_hd, tcpname, AVIO_RDWR);
    if (err)
        goto fail;

    mmst->packet_id        = 3;          // default, initial value.
    mmst->header_packet_id = 2;          // default, initial value.
    err = mms_safe_send_recv(mmst, send_startup_packet, SC_PKT_CLIENT_ACCEPTED);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_time_test_data, SC_PKT_TIMING_TEST_REPLY);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_HEADER);
    if (err)
        goto fail;
    if((mmst->incoming_flags != 0X08) && (mmst->incoming_flags != 0X0C))
    {
        av_log(NULL, AV_LOG_ERROR,
               "The server does not support MMST (try MMSH or RTSP)\n");
        err = AVERROR(EINVAL);
        goto fail;
    }
    err = ff_mms_asf_header_parser(mms);
    if (err)
    {
        av_dlog(NULL, "asf header parsed failed!\n");
        goto fail;
    }
    mms->header_parsed = 1;

    if (!mms->asf_packet_len || !mms->stream_num)
        goto fail;

    clear_stream_buffers(mms);
    err = mms_safe_send_recv(mmst, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED);
    if (err)
        goto fail;
    // send media packet request
    err = mms_safe_send_recv(mmst, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS);
    if (err)
    {
        goto fail;
    }
    av_dlog(NULL, "Leaving open (success)\n");
    return 0;
fail:
    mms_close(h);
    av_dlog(NULL, "Leaving open (failure: %d)\n", err);
    return err;
}
Esempio n. 26
0
File: avio.c Progetto: andoma/libav
int url_open(URLContext **puc, const char *filename, int flags)
{
    return ffurl_open(puc, filename, flags);
}
Esempio n. 27
0
static int rtp_open(URLContext *h, const char *uri, int flags)
{
    RTPContext *s = h->priv_data;
    int rtp_port, rtcp_port,
        ttl, connect,
        local_rtp_port, local_rtcp_port, max_packet_size;
    char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
    char buf[1024];
    char path[1024];
    const char *p;
    int i, max_retry_count = 3;

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
                 path, sizeof(path), uri);
    /* extract parameters */
    ttl = -1;
    rtcp_port = rtp_port+1;
    local_rtp_port = -1;
    local_rtcp_port = -1;
    max_packet_size = -1;
    connect = 0;

    p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
            ttl = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
            rtcp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
            local_rtp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
            local_rtp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
            local_rtcp_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
            max_packet_size = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
            connect = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
            s->write_to_source = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
            av_strlcpy(include_sources, buf, sizeof(include_sources));
            rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
        }
        if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
            av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
            rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
        }
    }

    for (i = 0;i < max_retry_count;i++) {
        build_udp_url(buf, sizeof(buf),
                      hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
                      connect, include_sources, exclude_sources);
        if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
            goto fail;
        local_rtp_port = ff_udp_get_local_port(s->rtp_hd);
        if(local_rtp_port == 65535) {
            local_rtp_port = -1;
            continue;
        }
        if (local_rtcp_port<0) {
            local_rtcp_port = local_rtp_port + 1;
            build_udp_url(buf, sizeof(buf),
                          hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
                          connect, include_sources, exclude_sources);
            if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) {
                local_rtp_port = local_rtcp_port = -1;
                continue;
            }
            break;
        }
        build_udp_url(buf, sizeof(buf),
                      hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
                      connect, include_sources, exclude_sources);
        if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
            goto fail;
        break;
    }

    /* just to ease handle access. XXX: need to suppress direct handle
       access */
    s->rtp_fd = ffurl_get_file_handle(s->rtp_hd);
    s->rtcp_fd = ffurl_get_file_handle(s->rtcp_hd);

    h->max_packet_size = s->rtp_hd->max_packet_size;
    h->is_streamed = 1;
    return 0;

 fail:
    if (s->rtp_hd)
        ffurl_close(s->rtp_hd);
    if (s->rtcp_hd)
        ffurl_close(s->rtcp_hd);
    return AVERROR(EIO);
}
Esempio n. 28
0
static int sap_write_header(AVFormatContext *s)
{
    struct SAPState *sap = s->priv_data;
    char host[1024], path[1024], url[1024], announce_addr[50] = "";
    char *option_list;
    int port = 9875, base_port = 5004, i, pos = 0, same_port = 0, ttl = 255;
    AVFormatContext **contexts = NULL;
    int ret = 0;
    struct sockaddr_storage localaddr;
    socklen_t addrlen = sizeof(localaddr);
    int udp_fd;

    if (!ff_network_init())
        return AVERROR(EIO);

    /* extract hostname and port */
    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &base_port,
                 path, sizeof(path), s->filename);
    if (base_port < 0)
        base_port = 5004;

    /* search for options */
    option_list = strrchr(path, '?');
    if (option_list) {
        char buf[50];
        if (av_find_info_tag(buf, sizeof(buf), "announce_port", option_list)) {
            port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "same_port", option_list)) {
            same_port = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "ttl", option_list)) {
            ttl = strtol(buf, NULL, 10);
        }
        if (av_find_info_tag(buf, sizeof(buf), "announce_addr", option_list)) {
            av_strlcpy(announce_addr, buf, sizeof(announce_addr));
        }
    }

    if (!announce_addr[0]) {
        struct addrinfo hints = { 0 }, *ai = NULL;
        hints.ai_family = AF_UNSPEC;
        if (getaddrinfo(host, NULL, &hints, &ai)) {
            av_log(s, AV_LOG_ERROR, "Unable to resolve %s\n", host);
            ret = AVERROR(EIO);
            goto fail;
        }
        if (ai->ai_family == AF_INET) {
            /* Also known as sap.mcast.net */
            av_strlcpy(announce_addr, "224.2.127.254", sizeof(announce_addr));
#if HAVE_STRUCT_SOCKADDR_IN6
        } else if (ai->ai_family == AF_INET6) {
            /* With IPv6, you can use the same destination in many different
             * multicast subnets, to choose how far you want it routed.
             * This one is intended to be routed globally. */
            av_strlcpy(announce_addr, "ff0e::2:7ffe", sizeof(announce_addr));
#endif
        } else {
            freeaddrinfo(ai);
            av_log(s, AV_LOG_ERROR, "Host %s resolved to unsupported "
                                    "address family\n", host);
            ret = AVERROR(EIO);
            goto fail;
        }
        freeaddrinfo(ai);
    }

    contexts = av_mallocz(sizeof(AVFormatContext*) * s->nb_streams);
    if (!contexts) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    s->start_time_realtime = av_gettime();
    for (i = 0; i < s->nb_streams; i++) {
        URLContext *fd;

        ff_url_join(url, sizeof(url), "rtp", NULL, host, base_port,
                    "?ttl=%d", ttl);
        if (!same_port)
            base_port += 2;
        ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
        if (ret) {
            ret = AVERROR(EIO);
            goto fail;
        }
        s->streams[i]->priv_data = contexts[i] =
            ff_rtp_chain_mux_open(s, s->streams[i], fd, 0);
        av_strlcpy(contexts[i]->filename, url, sizeof(contexts[i]->filename));
    }

    ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port,
                "?ttl=%d&connect=1", ttl);
    ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE,
                     &s->interrupt_callback, NULL);
    if (ret) {
        ret = AVERROR(EIO);
        goto fail;
    }

    udp_fd = ffurl_get_file_handle(sap->ann_fd);
    if (getsockname(udp_fd, (struct sockaddr*) &localaddr, &addrlen)) {
        ret = AVERROR(EIO);
        goto fail;
    }
    if (localaddr.ss_family != AF_INET
#if HAVE_STRUCT_SOCKADDR_IN6
        && localaddr.ss_family != AF_INET6
#endif
        ) {
        av_log(s, AV_LOG_ERROR, "Unsupported protocol family\n");
        ret = AVERROR(EIO);
        goto fail;
    }
    sap->ann_size = 8192;
    sap->ann = av_mallocz(sap->ann_size);
    if (!sap->ann) {
        ret = AVERROR(EIO);
        goto fail;
    }
    sap->ann[pos] = (1 << 5);
#if HAVE_STRUCT_SOCKADDR_IN6
    if (localaddr.ss_family == AF_INET6)
        sap->ann[pos] |= 0x10;
#endif
    pos++;
    sap->ann[pos++] = 0; /* Authentication length */
    AV_WB16(&sap->ann[pos], av_get_random_seed());
    pos += 2;
    if (localaddr.ss_family == AF_INET) {
        memcpy(&sap->ann[pos], &((struct sockaddr_in*)&localaddr)->sin_addr,
               sizeof(struct in_addr));
        pos += sizeof(struct in_addr);
#if HAVE_STRUCT_SOCKADDR_IN6
    } else {
        memcpy(&sap->ann[pos], &((struct sockaddr_in6*)&localaddr)->sin6_addr,
               sizeof(struct in6_addr));
        pos += sizeof(struct in6_addr);
#endif
    }

    av_strlcpy(&sap->ann[pos], "application/sdp", sap->ann_size - pos);
    pos += strlen(&sap->ann[pos]) + 1;

    if (av_sdp_create(contexts, s->nb_streams, &sap->ann[pos],
                       sap->ann_size - pos)) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }
    av_freep(&contexts);
    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", &sap->ann[pos]);
    pos += strlen(&sap->ann[pos]);
    sap->ann_size = pos;

    if (sap->ann_size > sap->ann_fd->max_packet_size) {
        av_log(s, AV_LOG_ERROR, "Announcement too large to send in one "
                                "packet\n");
        goto fail;
    }

    return 0;

fail:
    av_free(contexts);
    sap_write_close(s);
    return ret;
}
Esempio n. 29
0
static int m3u_format_parser(struct list_mgt *mgt,ByteIOContext *s)
{
    unsigned  char line[1024];
    int ret;
    unsigned char *p;
    int getnum=0;
    struct list_item tmpitem;
    char prefix[1024]="";
    char prefixex[1024]="";
    int prefix_len=0,prefixex_len=0;
    double start_time=mgt->full_time;
    char *oprefix=mgt->location!=NULL?mgt->location:mgt->filename;
    if(NULL!=mgt->prefix) {
        av_free(mgt->prefix);
        mgt->prefix = NULL;
    }
    if(oprefix) {
        mgt->prefix = strdup(oprefix);

        char *tail,*tailex,*extoptions;
        extoptions=strchr(oprefix,'?');/*ext options is start with ? ,we don't need in nested*/
        if(is_NET_URL(oprefix)) {
            tail=strchr(oprefix+10,'/');/*skip Http:// and shttp:,and to first '/'*/
            if(!extoptions)// no ?
                tailex=strrchr(oprefix+10,'/');/*skip Http:// and shttp:,start to  last '/'*/
            else
                tailex=memrchr(oprefix+10,'/',extoptions-oprefix-10);/*skip Http:// and shttp:,start to  last '/',between http-->? */
        } else {
            tail=strchr(oprefix,'/'); /*first '/'*/
            if(!extoptions)//no ?
                tailex=strrchr(oprefix,'/'); /*to last '/' */
            else
                tailex=memrchr(oprefix+10,'/',extoptions-oprefix-10);/*skip Http:// and shttp:,start to  last '/',between http-->? */
        }

        if(tail!=NULL) {
            prefix_len=tail-oprefix+1;/*left '/'..*/
            memcpy(prefix,oprefix,prefix_len);
            prefix[prefix_len]='\0';
        }

        if(tailex!=NULL) {
            prefixex_len=tailex-oprefix+1;/*left '/'..*/
            memcpy(prefixex,oprefix,prefixex_len);
            prefixex[prefixex_len]='\0';
        }
    }
    memset(&tmpitem,0,sizeof(tmpitem));
    tmpitem.seq=-1;
    av_log(NULL, AV_LOG_INFO, "m3u_format_parser get prefix=%s\n",prefix);
    av_log(NULL, AV_LOG_INFO, "m3u_format_parser get prefixex=%s\n",prefixex);
#if 0
    if(mgt->n_variants>0) {
        free_variant_list(mgt);
    }
#endif
    while(m3u_format_get_line(s,line,1024)>=0)
    {
        if (url_interrupt_cb()) {
            return -1;
        }
        tmpitem.ktype = KEY_NONE;
        ret = m3u_parser_line(mgt,line,&tmpitem);
        if(ret>0)
        {
            struct list_item*item;
            int need_prefix=0;
            int size_file=tmpitem.file?(strlen(tmpitem.file)+32):4;
            tmpitem.start_time=start_time;

            if(tmpitem.file &&
                    (is_NET_URL(prefix)) && /*net protocal*/
                    !(is_NET_URL(tmpitem.file)))/*if item is not net protocal*/
            {   /*if m3u is http,item is not http,add prefix*/
                need_prefix=1;
                size_file+=prefixex_len;
            }
            item=av_malloc(sizeof(struct list_item)+size_file);
            if(!item)
                return AVERROR(ENOMEM);
            memcpy(item,&tmpitem,sizeof(tmpitem));
            item->file=NULL;
            if(tmpitem.file)
            {
                item->file=&item[1];
                if(need_prefix) {
                    if(tmpitem.file[0]=='/') { /*has '/',not need the dir */
                        strcpy(item->file,prefix);
                        strcpy(item->file+prefix_len,tmpitem.file+1);/*don't copy two '/',we have left before*/
                    } else { /*no '/', some I save the full path frefix*/
                        if(!strncmp(prefixex,"shttps://",9)) {
                            strcpy(item->file,"http");
                            strcpy(item->file+4,prefixex+6);
                            strcpy(item->file+4+prefixex_len -6,tmpitem.file);
                        } else {
                            strcpy(item->file,prefixex);
                            strcpy(item->file+prefixex_len,tmpitem.file);
                        }

                    }
                }
                else {
                    strcpy(item->file,tmpitem.file);
                }
            }

            if(mgt->flags&KEY_FLAG&&NULL!= mgt->key_tmp&&mgt->key_tmp->is_have_key_file>0) {
                item->key_ctx = av_mallocz(sizeof(struct AES128KeyContext));
                if(!item->key_ctx) {
                    ret = AVERROR(ENOMEM);
                    break;
                }
                memcpy(item->key_ctx->key,mgt->key_tmp->key,sizeof(item->key_ctx->key));
                if(mgt->has_iv>0) {
                    memcpy(item->key_ctx->iv,mgt->key_tmp->iv,sizeof(item->key_ctx->iv));
                } else { //from applehttp.c
                    av_log(NULL,AV_LOG_INFO,"Current item seq number:%d\n",item->seq);
                    AV_WB32(item->key_ctx->iv + 12, item->seq);
                }


                item->ktype = mgt->key_tmp->key_type;

            }
            if(mgt->next_seq>=0 && item->seq<0) {
                item->seq=mgt->next_seq;
                mgt->next_seq++;
            }

            if(!(tmpitem.flags&INVALID_ITEM_FLAG)) {

                ret =list_test_and_add_item(mgt,item);
                if(ret==0) {
                    getnum++;
                    start_time+=item->duration;
                } else {
                    av_free(item);
                    mgt->next_seq--;
                }

            }

            if((item->flags &ENDLIST_FLAG) && (item->flags < (1<<12)))
            {
                mgt->have_list_end=1;
                break;
            }
            memset(&tmpitem,0,sizeof(tmpitem));
            tmpitem.seq=-1;
        }
        else if(ret <0) {
            if(ret ==-(TRICK_LOGIC_BASE+0)&&(mgt->flags&KEY_FLAG)&&NULL!= mgt->key_tmp&&0==mgt->key_tmp->is_have_key_file) { //get key from server
                URLContext *uc;
                if (ffurl_open(&uc, mgt->key_tmp->key_from, AVIO_FLAG_READ) == 0) {
                    if (ffurl_read_complete(uc, mgt->key_tmp->key, sizeof(mgt->key_tmp->key))
                            != sizeof(mgt->key_tmp->key)) {
                        av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                               mgt->key_tmp->key_from);

                    }
                    av_log(NULL,AV_LOG_INFO,"Just get aes key file from server\n");
                    mgt->key_tmp->is_have_key_file = 1;

                    ffurl_close(uc);
                } else {
                    av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                           mgt->key_tmp->key_from);
                }
                memset(&tmpitem,0,sizeof(tmpitem));
                continue;
            }

            if(ret ==-(TRICK_LOGIC_BASE+1)||ret ==-(TRICK_LOGIC_BASE+2)) {
                memset(&tmpitem,0,sizeof(tmpitem));
                continue;
            }
            break;
        }
        else {
            if(tmpitem.flags&ALLOW_CACHE_FLAG)
                mgt->flags|=ALLOW_CACHE_FLAG;
            if(tmpitem.flags&INVALID_ITEM_FLAG) {
                av_log(NULL,AV_LOG_INFO,"just a trick,drop this item,seq number:%d\n",tmpitem.seq);
                continue;
            }
        }

    }
    if(mgt->key_tmp) {
        av_free(mgt->key_tmp);
        mgt->key_tmp = NULL;
    }

    mgt->file_size=AVERROR_STREAM_SIZE_NOTVALID;
    mgt->full_time=start_time;
    mgt->last_load_time = av_gettime();
    av_log(NULL, AV_LOG_INFO, "m3u_format_parser end num =%d,fulltime=%.4lf\n",getnum,start_time);
    return getnum;
}
Esempio n. 30
0
static int sap_read_header(AVFormatContext *s)
{
    struct SAPState *sap = s->priv_data;
    char host[1024], path[1024], url[1024];
    uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
    int port;
    int ret, i;
    AVInputFormat* infmt;

    if (!ff_network_init())
        return AVERROR(EIO);

    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
                 path, sizeof(path), s->filename);
    if (port < 0)
        port = 9875;

    if (!host[0]) {
        /* Listen for announcements on sap.mcast.net if no host was specified */
        av_strlcpy(host, "224.2.127.254", sizeof(host));
    }

    ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d",
                port);
    ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ,
                     &s->interrupt_callback, NULL);
    if (ret)
        goto fail;

    while (1) {
        int addr_type, auth_len;
        int pos;

        ret = ffurl_read(sap->ann_fd, recvbuf, sizeof(recvbuf) - 1);
        if (ret == AVERROR(EAGAIN))
            continue;
        if (ret < 0)
            goto fail;
        recvbuf[ret] = '\0'; /* Null terminate for easier parsing */
        if (ret < 8) {
            av_log(s, AV_LOG_WARNING, "Received too short packet\n");
            continue;
        }

        if ((recvbuf[0] & 0xe0) != 0x20) {
            av_log(s, AV_LOG_WARNING, "Unsupported SAP version packet "
                                      "received\n");
            continue;
        }

        if (recvbuf[0] & 0x04) {
            av_log(s, AV_LOG_WARNING, "Received stream deletion "
                                      "announcement\n");
            continue;
        }
        addr_type = recvbuf[0] & 0x10;
        auth_len  = recvbuf[1];
        sap->hash = AV_RB16(&recvbuf[2]);
        pos = 4;
        if (addr_type)
            pos += 16; /* IPv6 */
        else
            pos += 4; /* IPv4 */
        pos += auth_len * 4;
        if (pos + 4 >= ret) {
            av_log(s, AV_LOG_WARNING, "Received too short packet\n");
            continue;
        }
#define MIME "application/sdp"
        if (strcmp(&recvbuf[pos], MIME) == 0) {
            pos += strlen(MIME) + 1;
        } else if (strncmp(&recvbuf[pos], "v=0\r\n", 5) == 0) {
            // Direct SDP without a mime type
        } else {
            av_log(s, AV_LOG_WARNING, "Unsupported mime type %s\n",
                                      &recvbuf[pos]);
            continue;
        }

        sap->sdp = av_strdup(&recvbuf[pos]);
        break;
    }

    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sap->sdp);
    ffio_init_context(&sap->sdp_pb, sap->sdp, strlen(sap->sdp), 0, NULL, NULL,
                  NULL, NULL);

    infmt = av_find_input_format("sdp");
    if (!infmt)
        goto fail;
    sap->sdp_ctx = avformat_alloc_context();
    if (!sap->sdp_ctx) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    sap->sdp_ctx->max_delay = s->max_delay;
    sap->sdp_ctx->pb        = &sap->sdp_pb;
    sap->sdp_ctx->interrupt_callback = s->interrupt_callback;
    ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL);
    if (ret < 0)
        goto fail;
    if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER)
        s->ctx_flags |= AVFMTCTX_NOHEADER;
    for (i = 0; i < sap->sdp_ctx->nb_streams; i++) {
        AVStream *st = avformat_new_stream(s, NULL);
        if (!st) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        st->id = i;
        avcodec_copy_context(st->codec, sap->sdp_ctx->streams[i]->codec);
        st->time_base = sap->sdp_ctx->streams[i]->time_base;
    }

    return 0;

fail:
    sap_read_close(s);
    return ret;
}