| 62 | } |
| 63 | |
| 64 | static int sap_read_header(AVFormatContext *s) |
| 65 | { |
| 66 | struct SAPState *sap = s->priv_data; |
| 67 | char host[1024], path[1024], url[1024]; |
| 68 | uint8_t recvbuf[RTP_MAX_PACKET_LENGTH]; |
| 69 | const AVInputFormat *infmt; |
| 70 | int port; |
| 71 | int ret, i; |
| 72 | |
| 73 | if (!ff_network_init()) |
| 74 | return AVERROR(EIO); |
| 75 | |
| 76 | av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, |
| 77 | path, sizeof(path), s->url); |
| 78 | if (port < 0) |
| 79 | port = 9875; |
| 80 | |
| 81 | if (!host[0]) { |
| 82 | /* Listen for announcements on sap.mcast.net if no host was specified */ |
| 83 | av_strlcpy(host, "224.2.127.254", sizeof(host)); |
| 84 | } |
| 85 | |
| 86 | ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d", |
| 87 | port); |
| 88 | ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_READ, |
| 89 | &s->interrupt_callback, NULL, |
| 90 | s->protocol_whitelist, s->protocol_blacklist, NULL); |
| 91 | if (ret) |
| 92 | goto fail; |
| 93 | |
| 94 | while (1) { |
| 95 | int addr_type, auth_len; |
| 96 | int pos; |
| 97 | |
| 98 | ret = ffurl_read(sap->ann_fd, recvbuf, sizeof(recvbuf) - 1); |
| 99 | if (ret == AVERROR(EAGAIN)) |
| 100 | continue; |
| 101 | if (ret < 0) |
| 102 | goto fail; |
| 103 | recvbuf[ret] = '\0'; /* Null terminate for easier parsing */ |
| 104 | if (ret < 8) { |
| 105 | av_log(s, AV_LOG_WARNING, "Received too short packet\n"); |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | if ((recvbuf[0] & 0xe0) != 0x20) { |
| 110 | av_log(s, AV_LOG_WARNING, "Unsupported SAP version packet " |
| 111 | "received\n"); |
| 112 | continue; |
| 113 | } |
| 114 | |
| 115 | if (recvbuf[0] & 0x04) { |
| 116 | av_log(s, AV_LOG_WARNING, "Received stream deletion " |
| 117 | "announcement\n"); |
| 118 | continue; |
| 119 | } |
| 120 | addr_type = recvbuf[0] & 0x10; |
| 121 | auth_len = recvbuf[1]; |
nothing calls this directly
no test coverage detected