📄 mmsh.c
字号:
lprintf("second http request\n"); if (mmsh_tcp_connect(io, this)) { goto fail; } /* stream selection string */ /* The same selection is done with mmst */ /* 0 means selected */ /* 2 means disabled */ offset = 0; for (i = 0; i < this->num_stream_ids; i++) { int size; if ((this->stream_ids[i] == audio_stream) || (this->stream_ids[i] == video_stream)) { size = snprintf(stream_selection + offset, sizeof(stream_selection) - offset, "ffff:%d:0 ", this->stream_ids[i]); } else { lprintf ("disabling stream %d\n", this->stream_ids[i]); size = snprintf(stream_selection + offset, sizeof(stream_selection) - offset, "ffff:%d:2 ", this->stream_ids[i]); } if (size < 0) goto fail; offset += size; } switch (this->stream_type) { case MMSH_SEEKABLE: snprintf (this->str, SCRATCH_SIZE, mmsh_SeekableRequest, this->uri, this->http_host, this->http_port, 0, 0, 0, 2, 0, this->num_stream_ids, stream_selection); break; case MMSH_LIVE: snprintf (this->str, SCRATCH_SIZE, mmsh_LiveRequest, this->uri, this->http_host, this->http_port, 2, this->num_stream_ids, stream_selection); break; } if (!send_command (io, this, this->str)) goto fail; lprintf("before read \n"); if (!get_answer (io, this)) goto fail; if (!get_header(io, this)) goto fail; interp_header(io, this); for (i = 0; i < this->num_stream_ids; i++) { if ((this->stream_ids[i] != audio_stream) && (this->stream_ids[i] != video_stream)) { lprintf("disabling stream %d\n", this->stream_ids[i]); /* forces the asf demuxer to not choose this stream */ if (this->bitrates_pos[this->stream_ids[i]]) { this->asf_header[this->bitrates_pos[this->stream_ids[i]]] = 0; this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 1] = 0; this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 2] = 0; this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 3] = 0; } } } return 1;fail: return 0;}mmsh_t *mmsh_connect (mms_io_t *io, void *data, const char *url, int bandwidth) { mmsh_t *this; GURI *uri = NULL; GURI *proxy_uri = NULL; char *proxy_env; if (!url) return NULL;// report_progress (stream, 0); /* * initializatoin is essential here. the fail: label depends * on the various char * in our this structure to be * NULL if they haven't been assigned yet. */ this = (mmsh_t*) malloc (sizeof (mmsh_t)); this->url=NULL; this->proxy_url = NULL; this->proto = NULL; this->connect_host = NULL; this->http_host = NULL; this->proxy_user = NULL; this->proxy_password = NULL; this->host_user = NULL; this->host_password = NULL; this->uri = NULL; this->custom_data = data; this->url = strdup(url); if ((proxy_env = getenv("http_proxy")) != NULL) this->proxy_url = strdup(proxy_env); else this->proxy_url = NULL; this->s = -1; this->asf_header_len = 0; this->asf_header_read = 0; this->num_stream_ids = 0; this->packet_length = 0; this->buf_size = 0; this->buf_read = 0; this->has_audio = 0; this->has_video = 0; this->current_pos = 0; this->user_bandwidth = bandwidth;// report_progress (stream, 0); if (this->proxy_url) { proxy_uri = gnet_uri_new(this->proxy_url); if (!proxy_uri) { lprintf("invalid proxy url\n"); goto fail; } if (! proxy_uri->port ) { proxy_uri->port = 3128; //default squid port } } uri = gnet_uri_new(this->url); if (!uri) { lprintf ("invalid url\n"); goto fail; } if (! uri->port ) { //checked in tcp_connect, but it's better to initialize it here uri->port = MMSH_PORT; } if (this->proxy_url) { this->proto = (uri->scheme) ? strdup(uri->scheme) : NULL; this->connect_host = (proxy_uri->hostname) ? strdup(proxy_uri->hostname) : NULL; this->connect_port = proxy_uri->port; this->http_host = (uri->scheme) ? strdup(uri->hostname) : NULL; this->http_port = uri->port; this->proxy_user = (proxy_uri->user) ? strdup(proxy_uri->user) : NULL; this->proxy_password = (proxy_uri->passwd) ? strdup(proxy_uri->passwd) : NULL; this->host_user = (uri->user) ? strdup(uri->user) : NULL; this->host_password = (uri->passwd) ? strdup(uri->passwd) : NULL; gnet_uri_set_scheme(uri,"http"); char * uri_string = gnet_uri_get_string(uri); this->uri = strdup(uri_string); g_free(uri_string); } else { this->proto = (uri->scheme) ? strdup(uri->scheme) : NULL; this->connect_host = (uri->hostname) ? strdup(uri->hostname) : NULL; this->connect_port = uri->port; this->http_host = (uri->hostname) ? strdup(uri->hostname) : NULL; this->http_port = uri->port; this->proxy_user = NULL; this->proxy_password = NULL; this->host_user =(uri->user) ? strdup(uri->user) : NULL; this->host_password = (uri->passwd) ? strdup(uri->passwd) : NULL; this->uri = (uri->path) ? strdup(uri->path) : NULL; } if (proxy_uri) { gnet_uri_delete(proxy_uri); proxy_uri = NULL; } if (uri) { gnet_uri_delete(uri); uri = NULL; } if (!mmsh_valid_proto(this->proto)) { lprintf ("unsupported protocol\n"); goto fail; } if (mmsh_tcp_connect(io, this)) { goto fail; }// report_progress (stream, 30); if (!mmsh_connect_int(io, this, this->user_bandwidth)) goto fail;// report_progress (stream, 100); lprintf("mmsh_connect: passed\n" ); return this;fail: lprintf("mmsh_connect: failed\n" ); if (proxy_uri) gnet_uri_delete(proxy_uri); if (uri) gnet_uri_delete(uri); if (this->s != -1) close(this->s); if (this->url) free(this->url); if (this->proxy_url) free(this->proxy_url); if (this->proto) free(this->proto); if (this->connect_host) free(this->connect_host); if (this->http_host) free(this->http_host); if (this->proxy_user) free(this->proxy_user); if (this->proxy_password) free(this->proxy_password); if (this->host_user) free(this->host_user); if (this->host_password) free(this->host_password); if (this->uri) free(this->uri); free(this); lprintf("mmsh_connect: failed return\n" ); return NULL;}/* * returned value: * 0: error * 1: data packet read * 2: new header read */static int get_media_packet (mms_io_t *io, mmsh_t *this) { int len = 0; lprintf("get_media_packet: this->packet_length: %d\n", this->packet_length); if (get_chunk_header(io, this)) { switch (this->chunk_type) { case CHUNK_TYPE_END: /* this->chunk_seq_number: * 0: stop * 1: a new stream follows */ if (this->chunk_seq_number == 0) return 0; close (this->s); if (mmsh_tcp_connect (io, this)) return 0; if (!mmsh_connect_int (io, this, this->user_bandwidth)) return 0; /* mmsh_connect_int reads the first data packet */ /* this->buf_size is set by mmsh_connect_int */ return 2; case CHUNK_TYPE_DATA: /* nothing to do */ break; case CHUNK_TYPE_RESET: /* next chunk is an ASF header */ if (this->chunk_length != 0) { /* that's strange, don't know what to do */ return 0; } if (!get_header (io, this)) return 0; interp_header(io, this); this->buf_size = this->packet_length; return 2; default: lprintf ("mmsh: unexpected chunk type\n"); return 0; } len = io_read (io, this->s, this->buf, this->chunk_length); if (len == this->chunk_length) { /* explicit padding with 0 */ if (this->chunk_length > this->packet_length) { lprintf ("mmsh: chunk_length(%d) > packet_length(%d)\n", this->chunk_length, this->packet_length); return 0; } { char *base = (char *)(this->buf); char *start = base + this->chunk_length; char *end = start + this->packet_length - this->chunk_length; if ((start > base) && (start < (base+CHUNK_SIZE-1)) && (start < end) && (end < (base+CHUNK_SIZE-1))) { memset(start, 0, this->packet_length - this->chunk_length); } if (this->packet_length > CHUNK_SIZE) { this->buf_size = CHUNK_SIZE; } else { this->buf_size = this->packet_length; } } return 1; } else { lprintf ("mmsh: read error, %d != %d\n", len, this->chunk_length); return 0; } } else { return 0; }}int mmsh_peek_header (mmsh_t *this, char *data, int maxsize) { int len; lprintf("mmsh_peek_header\n"); len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize; memcpy(data, this->asf_header, len); return len;}int mmsh_read (mms_io_t *io, mmsh_t *this, char *data, int len) { int total; total = 0; lprintf ("mmsh_read: len: %d\n", len); while (total < len) { if (this->asf_header_read < this->asf_header_len) { int n, bytes_left ; bytes_left = this->asf_header_len - this->asf_header_read ; if ((len-total) < bytes_left) n = len-total; else n = bytes_left; memcpy (&data[total], &this->asf_header[this->asf_header_read], n); this->asf_header_read += n; total += n; this->current_pos += n; } else { int n, bytes_left ; bytes_left = this->buf_size - this->buf_read; if (bytes_left == 0) { int packet_type; this->buf_size=this ->buf_read = 0; packet_type = get_media_packet (io, this); if (packet_type == 0) { lprintf ("mmsh: get_media_packet failed\n"); return total; } else if (packet_type == 2) { continue; } bytes_left = this->buf_size; } if ((len-total) < bytes_left) n = len-total; else n = bytes_left; memcpy (&data[total], &this->buf[this->buf_read], n); this->buf_read += n; total += n; this->current_pos += n; } } return total;}void mmsh_close (mmsh_t *this) { lprintf("mmsh_close\n"); if (this->s != -1) close(this->s); if (this->url) free(this->url); if (this->proxy_url) free(this->proxy_url); if (this->proto) free(this->proto); if (this->connect_host) free(this->connect_host); if (this->http_host) free(this->http_host); if (this->proxy_user) free(this->proxy_user); if (this->proxy_password) free(this->proxy_password); if (this->host_user) free(this->host_user); if (this->host_password) free(this->host_password); if (this->uri) free(this->uri); if (this) free (this);}uint32_t mmsh_get_length (mmsh_t *this) { return this->file_length;}off_t mmsh_get_current_pos (mmsh_t *this) { return this->current_pos;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -