| 71 | } |
| 72 | |
| 73 | static int tee_open(URLContext *h, const char *filename, int flags) |
| 74 | { |
| 75 | TeeContext *c = h->priv_data; |
| 76 | int ret, i; |
| 77 | |
| 78 | av_strstart(filename, "tee:", &filename); |
| 79 | |
| 80 | while (*filename) { |
| 81 | char *child_string = av_get_token(&filename, child_delim); |
| 82 | char *child_name = NULL; |
| 83 | void *tmp; |
| 84 | AVDictionary *options = NULL; |
| 85 | if (!child_string) { |
| 86 | ret = AVERROR(ENOMEM); |
| 87 | goto fail; |
| 88 | } |
| 89 | |
| 90 | tmp = av_realloc_array(c->child, c->child_count + 1, sizeof(*c->child)); |
| 91 | if (!tmp) { |
| 92 | ret = AVERROR(ENOMEM); |
| 93 | goto loop_fail; |
| 94 | } |
| 95 | c->child = tmp; |
| 96 | memset(&c->child[c->child_count], 0, sizeof(c->child[c->child_count])); |
| 97 | |
| 98 | ret = ff_tee_parse_slave_options(h, child_string, &options, &child_name); |
| 99 | if (ret < 0) |
| 100 | goto loop_fail; |
| 101 | |
| 102 | ret = ffurl_open_whitelist(&c->child[c->child_count].url_context, child_name, flags, |
| 103 | &h->interrupt_callback, &options, |
| 104 | h->protocol_whitelist, h->protocol_blacklist, |
| 105 | h); |
| 106 | loop_fail: |
| 107 | av_freep(&child_string); |
| 108 | av_dict_free(&options); |
| 109 | if (ret < 0) |
| 110 | goto fail; |
| 111 | c->child_count++; |
| 112 | |
| 113 | if (strspn(filename, child_delim)) |
| 114 | filename++; |
| 115 | } |
| 116 | |
| 117 | h->is_streamed = 0; |
| 118 | for (i=0; i<c->child_count; i++) { |
| 119 | h->is_streamed |= c->child[i].url_context->is_streamed; |
| 120 | } |
| 121 | |
| 122 | h->max_packet_size = 0; |
| 123 | for (i = 0; i < c->child_count; i++) { |
| 124 | int max = c->child[i].url_context->max_packet_size; |
| 125 | if (!max) |
| 126 | continue; |
| 127 | |
| 128 | if (!h->max_packet_size) |
| 129 | h->max_packet_size = max; |
| 130 | else if (h->max_packet_size > max) |
nothing calls this directly
no test coverage detected