comparison libmpdemux/http.c @ 16013:4ee24ec6ac16

SHOUTcast and ultravox support
author reimar
date Tue, 19 Jul 2005 12:07:04 +0000
parents 52edb32f0c2a
children c2e78215f0d9
comparison
equal deleted inserted replaced
16012:f9e53883dfd2 16013:4ee24ec6ac16
31 extern mime_struct_t mime_type_table[]; 31 extern mime_struct_t mime_type_table[];
32 extern int stream_cache_size; 32 extern int stream_cache_size;
33 extern int network_bandwidth; 33 extern int network_bandwidth;
34 34
35 extern int http_seek(stream_t *stream, off_t pos); 35 extern int http_seek(stream_t *stream, off_t pos);
36
37 typedef struct {
38 unsigned metaint;
39 unsigned metapos;
40 int is_ultravox;
41 } scast_data_t;
42
43 /**
44 * \brief first read any data from sc->buffer then from fd
45 * \param fd file descriptor to read data from
46 * \param buffer buffer to read into
47 * \param len how many bytes to read
48 * \param sc streaming control containing buffer to read from first
49 * \return len unless there is a read error or eof
50 */
51 static unsigned my_read(int fd, char *buffer, int len, streaming_ctrl_t *sc) {
52 unsigned pos = 0;
53 unsigned cp_len = sc->buffer_size - sc->buffer_pos;
54 if (cp_len > len)
55 cp_len = len;
56 memcpy(buffer, &sc->buffer[sc->buffer_pos], cp_len);
57 sc->buffer_pos += cp_len;
58 pos += cp_len;
59 while (pos < len) {
60 int ret = read(fd, &buffer[pos], len - pos);
61 if (ret <= 0)
62 break;
63 pos += ret;
64 }
65 return pos;
66 }
67
68 static unsigned uvox_meta_read(int fd, streaming_ctrl_t *sc) {
69 unsigned metaint;
70 unsigned char info[6];
71 do {
72 my_read(fd, info, 1, sc);
73 if (info[0] == 0x00)
74 my_read(fd, info, 6, sc);
75 else
76 my_read(fd, &info[1], 5, sc);
77 if (info[0] != 0x5a || info[1] != 0x00) {
78 mp_msg(MSGT_DEMUXER, MSGL_ERR, "Invalid or unknown uvox metadata\n");
79 return 0;
80 }
81 metaint = info[4] << 8 | info[5];
82 if (info[3] == 0x02) {
83 char *metabuf = malloc(metaint);
84 my_read(fd, metabuf, metaint, sc);
85 free(metabuf);
86 }
87 } while (info[3] == 0x02);
88 return metaint;
89 }
90
91 /**
92 * \brief read one scast meta data entry and print it
93 */
94 static void scast_meta_read(int fd, streaming_ctrl_t *sc) {
95 unsigned char tmp = 0;
96 unsigned metalen;
97 my_read(fd, &tmp, 1, sc);
98 metalen = tmp * 16;
99 if (metalen > 0) {
100 char *info = (char *)malloc(metalen + 1);
101 unsigned nlen = my_read(fd, info, metalen, sc);
102 info[nlen] = 0;
103 mp_msg(MSGT_DEMUXER, MSGL_INFO, "\nICY Info: %s\n", info);
104 free(info);
105 }
106 }
107
108 static int scast_streaming_read(int fd, char *buffer, int size,
109 streaming_ctrl_t *sc) {
110 scast_data_t *sd = (scast_data_t *)sc->data;
111 unsigned block, ret;
112 unsigned done = 0;
113
114 // first read remaining data up to next metadata
115 block = sd->metaint - sd->metapos;
116 if (block > size)
117 block = size;
118 ret = my_read(fd, buffer, block, sc);
119 sd->metapos += ret;
120 done += ret;
121 if (ret != block) // read problems or eof
122 size = done;
123
124 while (done < size) { // now comes the metadata
125 if (sd->is_ultravox)
126 sd->metaint = uvox_meta_read(fd, sc);
127 else
128 scast_meta_read(fd, sc); // read and display metadata
129 sd->metapos = 0;
130 block = size - done;
131 if (block > sd->metaint)
132 block = sd->metaint;
133 ret = my_read(fd, &buffer[done], block, sc);
134 sd->metapos += ret;
135 done += ret;
136 if (ret != block) // read problems or eof
137 size = done;
138 }
139 return done;
140 }
141
142 static int scast_streaming_start(stream_t *stream) {
143 int metaint;
144 int fromhdr;
145 scast_data_t *scast_data;
146 HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
147 int is_ultravox = http_hdr && strcasecmp(http_hdr->protocol, "ICY") != 0;
148 if (!stream || stream->fd < 0 || !http_hdr)
149 return -1;
150 if (is_ultravox)
151 metaint = 0;
152 else {
153 metaint = atoi(http_get_field(http_hdr, "Icy-MetaInt"));
154 if (metaint <= 0)
155 return -1;
156 }
157 stream->streaming_ctrl->buffer = malloc(http_hdr->body_size);
158 stream->streaming_ctrl->buffer_size = http_hdr->body_size;
159 stream->streaming_ctrl->buffer_pos = 0;
160 memcpy(stream->streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size);
161 scast_data = malloc(sizeof(scast_data_t));
162 scast_data->metaint = metaint;
163 scast_data->metapos = 0;
164 scast_data->is_ultravox = is_ultravox;
165 http_free(http_hdr);
166 stream->streaming_ctrl->data = scast_data;
167 stream->streaming_ctrl->streaming_read = scast_streaming_read;
168 stream->streaming_ctrl->streaming_seek = NULL;
169 stream->streaming_ctrl->prebuffer_size = 64 * 1024; // 64 KBytes
170 stream->streaming_ctrl->buffering = 1;
171 stream->streaming_ctrl->status = streaming_playing_e;
172 return 0;
173 }
36 174
37 static int nop_streaming_start( stream_t *stream ) { 175 static int nop_streaming_start( stream_t *stream ) {
38 HTTP_header_t *http_hdr = NULL; 176 HTTP_header_t *http_hdr = NULL;
39 char *next_url=NULL; 177 char *next_url=NULL;
40 URL_t *rd_url=NULL; 178 URL_t *rd_url=NULL;
675 813
676 return -1; 814 return -1;
677 } 815 }
678 816
679 static int fixup_open(stream_t *stream,int seekable) { 817 static int fixup_open(stream_t *stream,int seekable) {
818 HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
819 int is_icy = http_hdr && strcasecmp(http_hdr->protocol, "ICY") == 0;
820 char *content_type = http_get_field( http_hdr, "Content-Type" );
821 int is_ultravox = http_hdr && content_type &&
822 strcasecmp(content_type, "misc/ultravox") == 0;
680 823
681 stream->type = STREAMTYPE_STREAM; 824 stream->type = STREAMTYPE_STREAM;
682 if(seekable) 825 if(!is_icy && !is_ultravox && seekable)
683 { 826 {
684 stream->flags |= STREAM_SEEK; 827 stream->flags |= STREAM_SEEK;
685 stream->seek = http_seek; 828 stream->seek = http_seek;
686 } 829 }
687 stream->streaming_ctrl->bandwidth = network_bandwidth; 830 stream->streaming_ctrl->bandwidth = network_bandwidth;
831 if ((!is_icy && !is_ultravox) || scast_streaming_start(stream))
688 if(nop_streaming_start( stream )) { 832 if(nop_streaming_start( stream )) {
689 mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n"); 833 mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
690 streaming_ctrl_free(stream->streaming_ctrl); 834 streaming_ctrl_free(stream->streaming_ctrl);
691 stream->streaming_ctrl = NULL; 835 stream->streaming_ctrl = NULL;
692 return STREAM_UNSUPORTED; 836 return STREAM_UNSUPORTED;
749 "http streaming", 893 "http streaming",
750 "null", 894 "null",
751 "Bertrand, Albeau, Reimar Doeffinger, Arpi?", 895 "Bertrand, Albeau, Reimar Doeffinger, Arpi?",
752 "plain http", 896 "plain http",
753 open_s1, 897 open_s1,
754 {"http", "http_proxy", NULL}, 898 {"http", "http_proxy", "unsv", NULL},
755 NULL, 899 NULL,
756 0 // Urls are an option string 900 0 // Urls are an option string
757 }; 901 };
758 902
759 stream_info_t stream_info_http2 = { 903 stream_info_t stream_info_http2 = {