int avpriv_io_delete(const char *url) { URLContext *h; int ret = ffurl_alloc(&h, url, AVIO_FLAG_WRITE, NULL); if (ret < 0) return ret; if (h->prot->url_delete) ret = h->prot->url_delete(h); else ret = AVERROR(ENOSYS); ffurl_close(h); return ret; }
static av_cold int concat_close(URLContext *h) { int err = 0; size_t i; struct concat_data *data = h->priv_data; struct concat_nodes *nodes = data->nodes; for (i = 0; i != data->length; i++) err |= ffurl_close(nodes[i].uc); av_freep(&data->nodes); av_freep(&h->priv_data); return err < 0 ? -1 : 0; }
/** Close the MMSH/MMST connection */ static int mms_close(URLContext *h) { MMSTContext *mmst = (MMSTContext *)h->priv_data; MMSContext *mms = &mmst->mms; if(mms->mms_hd) { send_close_packet(mmst); ffurl_close(mms->mms_hd); } /* free all separately allocated pointers in mms */ av_freep(&mms->streams); av_freep(&mms->asf_header); return 0; }
int url_open_protocol (URLContext **puc, struct URLProtocol *up, const char *filename, int flags) { int ret; ret = url_alloc_for_protocol(puc, up, filename, flags); if (ret) goto fail; ret = ffurl_connect(*puc); if (!ret) return 0; fail: ffurl_close(*puc); *puc = NULL; return ret; }
static int url_connect(struct variant *var, AVDictionary *opts) { AVDictionary *tmp = NULL; int ret; av_dict_copy(&tmp, opts, 0); if ((ret = av_opt_set_dict(var->input, &tmp)) < 0 || (ret = ffurl_connect(var->input, NULL)) < 0) { ffurl_close(var->input); var->input = NULL; } av_dict_free(&tmp); return ret; }
static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect) { HTTPContext *s = h->priv_data; URLContext *old_hd = s->hd; int64_t old_off = s->off; uint8_t old_buf[BUFFER_SIZE]; int old_buf_size, ret; AVDictionary *options = NULL; if (whence == AVSEEK_SIZE) return s->filesize; else if (!force_reconnect && ((whence == SEEK_CUR && off == 0) || (whence == SEEK_SET && off == s->off))) return s->off; else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed) return AVERROR(ENOSYS); if (whence == SEEK_CUR) off += s->off; else if (whence == SEEK_END) off += s->filesize; else if (whence != SEEK_SET) return AVERROR(EINVAL); if (off < 0) return AVERROR(EINVAL); s->off = off; /* we save the old context in case the seek fails */ old_buf_size = s->buf_end - s->buf_ptr; memcpy(old_buf, s->buf_ptr, old_buf_size); s->hd = NULL; /* if it fails, continue on old connection */ if ((ret = http_open_cnx(h, &options)) < 0) { av_dict_free(&options); memcpy(s->buffer, old_buf, old_buf_size); s->buf_ptr = s->buffer; s->buf_end = s->buffer + old_buf_size; s->hd = old_hd; s->off = old_off; return ret; } av_dict_free(&options); ffurl_close(old_hd); return off; }
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char* blacklist, URLContext *parent) { AVDictionary *tmp_opts = NULL; AVDictionaryEntry *e; int ret = ffurl_alloc(puc, filename, flags, int_cb); if (ret < 0) return ret; if (parent) av_opt_copy(*puc, parent); if (options && (ret = av_opt_set_dict(*puc, options)) < 0) goto fail; if (options && (*puc)->prot->priv_data_class && (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0) goto fail; if (!options) options = &tmp_opts; av_assert0(!whitelist || !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) || !strcmp(whitelist, e->value)); av_assert0(!blacklist || !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) || !strcmp(blacklist, e->value)); if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0) goto fail; if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0) goto fail; if ((ret = av_opt_set_dict(*puc, options)) < 0) goto fail; ret = ffurl_connect(*puc, options); if (!ret) return 0; fail: ffurl_close(*puc); *puc = NULL; return ret; }
int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { int ret = ffurl_alloc(puc, filename, flags, int_cb); if (ret) return ret; if (options && (*puc)->prot->priv_data_class && (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0) goto fail; ret = ffurl_connect(*puc, options); if (!ret) return 0; fail: ffurl_close(*puc); *puc = NULL; return ret; }
static int tls_close(URLContext *h) { TLSContext *c = h->priv_data; if (c->ssl) { SSL_shutdown(c->ssl); SSL_free(c->ssl); } if (c->ctx) SSL_CTX_free(c->ctx); if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if (c->url_bio_method) BIO_meth_free(c->url_bio_method); #endif ff_openssl_deinit(); return 0; }
int avio_check(const char *url, int flags) { URLContext *h; int ret = ffurl_alloc(&h, url, flags); if (ret) return ret; if (h->prot->url_check) { ret = h->prot->url_check(h, flags); } else { ret = ffurl_connect(h); if (ret >= 0) ret = flags; } ffurl_close(h); return ret; }
static void free_variant_list(HLSContext *c) { int i; for (i = 0; i < c->n_variants; i++) { struct variant *var = c->variants[i]; free_segment_list(var); av_free_packet(&var->pkt); av_free(var->pb.buffer); if (var->input) ffurl_close(var->input); if (var->ctx) { var->ctx->pb = NULL; avformat_close_input(&var->ctx); } av_free(var); } av_freep(&c->variants); c->n_variants = 0; }
static int http_close(URLContext *h) { int ret = 0; HTTPContext *s = h->priv_data; #if CONFIG_ZLIB inflateEnd(&s->inflate_stream); av_freep(&s->inflate_buffer); #endif /* CONFIG_ZLIB */ if (!s->end_chunked_post) /* Close the write direction by sending the end of chunked encoding. */ ret = http_shutdown(h, h->flags); if (s->hd) ffurl_close(s->hd); av_dict_free(&s->chained_options); return ret; }
static int tls_close(URLContext *h) { TLSContext *c = h->priv_data; tls_shutdown_client(h); DeleteSecurityContext(&c->ctxt_handle); FreeCredentialsHandle(&c->cred_handle); av_freep(&c->enc_buf); c->enc_buf_size = c->enc_buf_offset = 0; av_freep(&c->dec_buf); c->dec_buf_size = c->dec_buf_offset = 0; if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); return 0; }
static int applehttp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { AppleHTTPContext *c = s->priv_data; int i, j, ret; if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished) return AVERROR(ENOSYS); timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); ret = AVERROR(EIO); for (i = 0; i < c->n_variants; i++) { /* Reset reading */ struct variant *var = c->variants[i]; int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 : av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); if (var->input) { ffurl_close(var->input); var->input = NULL; } av_free_packet(&var->pkt); reset_packet(&var->pkt); var->pb.eof_reached = 0; /* Locate the segment that contains the target timestamp */ for (j = 0; j < var->n_segments; j++) { if (timestamp >= pos && timestamp < pos + var->segments[j]->duration) { var->cur_seq_no = var->start_seq_no + j; ret = 0; break; } pos += var->segments[j]->duration; } } return ret; }
static int crypto_close(URLContext *h) { CryptoContext *c = h->priv_data; uint8_t out_buf[BLOCKSIZE]; int ret, pad; if (c->aes_encrypt) { pad = BLOCKSIZE - c->pad_len; memset(&c->pad[c->pad_len], pad, pad); av_aes_crypt(c->aes_encrypt, out_buf, c->pad, 1, c->encrypt_iv, 0); if ((ret = ffurl_write(c->hd, out_buf, BLOCKSIZE)) < 0) return ret; } if (c->hd) ffurl_close(c->hd); av_freep(&c->aes_decrypt); av_freep(&c->aes_encrypt); return 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 open_url(var->parent->priv_data, &var->input, seg->url); } else if (seg->key_type == KEY_AES_128) { HLSContext *c = var->parent->priv_data; char iv[33], key[33], url[MAX_URL_SIZE]; int ret; if (strcmp(seg->key, var->key_url)) { URLContext *uc; if (open_url(var->parent->priv_data, &uc, seg->key) == 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) return ret; av_opt_set(var->input->priv_data, "key", key, 0); av_opt_set(var->input->priv_data, "iv", iv, 0); return url_connect(var, c->avio_opts); } return AVERROR(ENOSYS); }
static void free_playlist_list(HLSContext *c) { int i; for (i = 0; i < c->n_playlists; i++) { struct playlist *pls = c->playlists[i]; free_segment_list(pls); av_free_packet(&pls->pkt); av_free(pls->pb.buffer); if (pls->input) ffurl_close(pls->input); if (pls->ctx) { pls->ctx->pb = NULL; avformat_close_input(&pls->ctx); } av_free(pls); } av_freep(&c->playlists); av_freep(&c->cookies); av_freep(&c->user_agent); c->n_playlists = 0; }
static int64_t mmsh_read_seek(URLContext *h, int stream_index, int64_t timestamp, int flags) { MMSHContext *mmsh = h->priv_data; MMSContext *mms = &mmsh->mms; int ret; ret= mmsh_open_internal(h, mmsh->location, 0, FFMAX(timestamp, 0), 0); if(ret>=0){ if (mms->mms_hd) ffurl_close(mms->mms_hd); av_freep(&mms->streams); av_freep(&mms->asf_header); av_free(mmsh); mmsh = h->priv_data; mms = &mmsh->mms; mms->asf_header_read_size= mms->asf_header_size; }else h->priv_data= mmsh; return ret; }
static int CacheHttp_advanced_ffurl_open_h(URLContext ** h,const char * filename, int flags, const char * headers, int * http,CacheHttpContext* ctx) { if(ctx->ktype == KEY_NONE) { return CacheHttp_ffurl_open_h(h, filename, flags,headers, http); } else { //crypto streaming int ret = -1; URLContext* input = NULL; if ((ret = ffurl_alloc(&input, filename, AVIO_FLAG_READ|AVIO_FLAG_NONBLOCK)) < 0) { return ret; } av_set_string3(input->priv_data, "key", ctx->key, 0, NULL); av_set_string3(input->priv_data, "iv", ctx->iv, 0, NULL); if ((ret = ffurl_connect(input)) < 0) { ffurl_close(input); input = NULL; *h = NULL; return ret; } *h = input; } return 0; }
int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options) { URLContext *h = NULL; AVIODirContext *ctx = NULL; int ret; av_assert0(s); ctx = av_mallocz(sizeof(*ctx)); if (!ctx) { ret = AVERROR(ENOMEM); goto fail; } if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0) goto fail; if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) { if (options && h->prot->priv_data_class && (ret = av_opt_set_dict(h->priv_data, options)) < 0) goto fail; ret = h->prot->url_open_dir(h); } else ret = AVERROR(ENOSYS); if (ret < 0) goto fail; h->is_connected = 1; ctx->url_context = h; *s = ctx; return 0; fail: av_free(ctx); *s = NULL; ffurl_close(h); return ret; }
static int recheck_discard_flags(AVFormatContext *s, int first) { HLSContext *c = s->priv_data; int i, changed = 0; /* Check if any new streams are needed */ for (i = 0; i < c->n_variants; i++) c->variants[i]->cur_needed = 0; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; struct variant *var = c->variants[s->streams[i]->id]; if (st->discard < AVDISCARD_ALL) var->cur_needed = 1; } for (i = 0; i < c->n_variants; i++) { struct variant *v = c->variants[i]; if (v->cur_needed && !v->needed) { v->needed = 1; changed = 1; v->cur_seq_no = c->cur_seq_no; v->pb.eof_reached = 0; // __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Now receiving variant %d\n", i); // av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i); } else if (first && !v->cur_needed && v->needed) { if (v->input) ffurl_close(v->input); v->input = NULL; v->needed = 0; changed = 1; // __android_log_print(ANDROID_LOG_VERBOSE, TAG, "No longer receiving variant %d\n", i); // av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i); } } // __android_log_print(ANDROID_LOG_VERBOSE, TAG, "changed = %d", changed); return changed; }
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); }
static int CacheHttp_ffurl_close(URLContext * h) { return ffurl_close(h); }
static int subfile_close(URLContext *h) { SubfileContext *c = h->priv_data; return ffurl_close(c->h); }
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; }
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); }
int url_close(URLContext *h) { return ffurl_close(h); }
int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, AVStream *st, URLContext *handle, int packet_size, int idx) { AVFormatContext *rtpctx = NULL; int ret; AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); uint8_t *rtpflags; AVDictionary *opts = NULL; if (!rtp_format) { ret = AVERROR(ENOSYS); goto fail; } /* Allocate an AVFormatContext for each output stream */ rtpctx = avformat_alloc_context(); if (!rtpctx) { ret = AVERROR(ENOMEM); goto fail; } rtpctx->oformat = rtp_format; if (!avformat_new_stream(rtpctx, NULL)) { ret = AVERROR(ENOMEM); goto fail; } /* Pass the interrupt callback on */ rtpctx->interrupt_callback = s->interrupt_callback; /* Copy the max delay setting; the rtp muxer reads this. */ rtpctx->max_delay = s->max_delay; /* Copy other stream parameters. */ rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; rtpctx->flags |= s->flags & AVFMT_FLAG_BITEXACT; /* Get the payload type from the codec */ if (st->id < RTP_PT_PRIVATE) rtpctx->streams[0]->id = ff_rtp_get_payload_type(s, st->codecpar, idx); else rtpctx->streams[0]->id = st->id; if (av_opt_get(s, "rtpflags", AV_OPT_SEARCH_CHILDREN, &rtpflags) >= 0) av_dict_set(&opts, "rtpflags", rtpflags, AV_DICT_DONT_STRDUP_VAL); /* Set the synchronized start time. */ rtpctx->start_time_realtime = s->start_time_realtime; avcodec_parameters_copy(rtpctx->streams[0]->codecpar, st->codecpar); rtpctx->streams[0]->time_base = st->time_base; if (handle) { ret = ffio_fdopen(&rtpctx->pb, handle); if (ret < 0) ffurl_close(handle); } else ret = ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size); if (!ret) ret = avformat_write_header(rtpctx, &opts); av_dict_free(&opts); if (ret) { if (handle && rtpctx->pb) { avio_closep(&rtpctx->pb); } else if (rtpctx->pb) { ffio_free_dyn_buf(&rtpctx->pb); } avformat_free_context(rtpctx); return ret; } *out = rtpctx; return 0; fail: avformat_free_context(rtpctx); if (handle) ffurl_close(handle); return ret; }
static int read_data(void *opaque, uint8_t *buf, int buf_size) { struct variant *v = opaque; HLSContext *c = v->parent->priv_data; int ret, i; restart: if (!v->input) { /* If this is a live stream and the reload interval has elapsed since * the last playlist reload, reload the variant playlists now. */ int64_t reload_interval = v->n_segments > 0 ? v->segments[v->n_segments - 1]->duration : v->target_duration; reload_interval *= 1000000; reload: if (!v->finished && av_gettime() - v->last_load_time >= reload_interval) { if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) return ret; /* If we need to reload the playlist again below (if * there's still no more segments), switch to a reload * interval of half the target duration. */ reload_interval = v->target_duration * 500000LL; } if (v->cur_seq_no < v->start_seq_no) { av_log(NULL, AV_LOG_WARNING, "skipping %d segments ahead, expired from playlists\n", v->start_seq_no - v->cur_seq_no); v->cur_seq_no = v->start_seq_no; } if (v->cur_seq_no >= v->start_seq_no + v->n_segments) { if (v->finished) return AVERROR_EOF; while (av_gettime() - v->last_load_time < reload_interval) { if (ff_check_interrupt(c->interrupt_callback)) return AVERROR_EXIT; av_usleep(100*1000); } /* Enough time has elapsed since the last reload */ goto reload; } ret = open_input(v); if (ret < 0) return ret; } ret = ffurl_read(v->input, buf, buf_size); if (ret > 0) return ret; ffurl_close(v->input); v->input = NULL; v->cur_seq_no++; c->end_of_segment = 1; c->cur_seq_no = v->cur_seq_no; if (v->ctx && v->ctx->nb_streams && v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) { v->needed = 0; for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams; i++) { if (v->parent->streams[i]->discard < AVDISCARD_ALL) v->needed = 1; } } if (!v->needed) { av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n", v->index); return AVERROR_EOF; } goto restart; }
static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int timestamp, int64_t pos) { int i, port, err; char httpname[256], path[256], host[128]; char *stream_selection = NULL; char headers[1024]; MMSHContext *mmsh = h->priv_data; MMSContext *mms; mmsh->request_seq = h->is_streamed = 1; mms = &mmsh->mms; av_strlcpy(mmsh->location, uri, sizeof(mmsh->location)); av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, path, sizeof(path), mmsh->location); if (port<0) port = 80; // default mmsh protocol port ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path); if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ, &h->interrupt_callback) < 0) { return AVERROR(EIO); } snprintf(headers, sizeof(headers), "Accept: */*\r\n" USERAGENT "Host: %s:%d\r\n" "Pragma: no-cache,rate=1.000000,stream-time=0," "stream-offset=0:0,request-context=%u,max-duration=0\r\n" CLIENTGUID "Connection: Close\r\n", host, port, mmsh->request_seq++); av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); err = ffurl_connect(mms->mms_hd, NULL); if (err) { goto fail; } err = get_http_header_data(mmsh); if (err) { av_log(NULL, AV_LOG_ERROR, "Get http header data failed!\n"); goto fail; } // close the socket and then reopen it for sending the second play request. ffurl_close(mms->mms_hd); memset(headers, 0, sizeof(headers)); if ((err = ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ, &h->interrupt_callback)) < 0) { goto fail; } stream_selection = av_mallocz(mms->stream_num * 19 + 1); if (!stream_selection) return AVERROR(ENOMEM); for (i = 0; i < mms->stream_num; i++) { char tmp[20]; err = snprintf(tmp, sizeof(tmp), "ffff:%d:0 ", mms->streams[i].id); if (err < 0) goto fail; av_strlcat(stream_selection, tmp, mms->stream_num * 19 + 1); } // send play request err = snprintf(headers, sizeof(headers), "Accept: */*\r\n" USERAGENT "Host: %s:%d\r\n" "Pragma: no-cache,rate=1.000000,request-context=%u\r\n" "Pragma: xPlayStrm=1\r\n" CLIENTGUID "Pragma: stream-switch-count=%d\r\n" "Pragma: stream-switch-entry=%s\r\n" "Pragma: no-cache,rate=1.000000,stream-time=%u" "Connection: Close\r\n", host, port, mmsh->request_seq++, mms->stream_num, stream_selection, timestamp); av_freep(&stream_selection); if (err < 0) { av_log(NULL, AV_LOG_ERROR, "Build play request failed!\n"); goto fail; } av_log(NULL, AV_LOG_TRACE, "out_buffer is %s", headers); av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); err = ffurl_connect(mms->mms_hd, NULL); if (err) { goto fail; } err = get_http_header_data(mmsh); if (err) { av_log(NULL, AV_LOG_ERROR, "Get http header data failed!\n"); goto fail; } av_log(NULL, AV_LOG_TRACE, "Connection successfully open\n"); return 0; fail: av_freep(&stream_selection); mmsh_close(h); av_log(NULL, AV_LOG_TRACE, "Connection failed with error %d\n", err); return err; }