⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmsh.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	goto failed;	break;    }        /* allways comes here to free http_hdr */    if(http_hdr) free_http_header(http_hdr);    http_hdr = NULL;    close(sock);    sock = server_connect(stream->serverinfo->connect_host,stream->serverinfo->connect_port);    if(sock < 0) {	return sock; /* failure */    }    stream->netsock->sock = sock; /* set socket# to stream_t */        http_hdr = new_http_header();    mmsh_media_request(stream,http_hdr);    ret = http_send_header(stream,http_hdr);    free_http_header(http_hdr);    http_hdr = NULL;        http_hdr = new_http_header();    ret = mmsh_recv_header(stream,http_hdr);    if(ret < 0) {	display(MSDL_ERR,"MMSH connection failed\n");	goto failed;    }        if(!is_http_response_ok(ret)) { /* MMSH request error */	display(MSDL_ERR,"%d %s\n",http_hdr->status_code,http_hdr->reason_phrase);	goto failed;    }        free_http_header(http_hdr);    http_hdr = NULL;    if(mmsh_ctrl->streaming_type != ASF_Seekable_e &&       mmsh_ctrl->streaming_type != ASF_Nonseekable_e) {	display(MSDL_ERR,"mmsh request failed\n");	goto failed;    }        stream->stream_ctrl->status = STREAMING_DOWNLOADING;    return 1;  http_fallback:    free_http_header(http_hdr);    http_hdr = NULL;    return 1;      failed:    free_http_header(http_hdr);    if(sock) close(sock);    http_hdr = NULL;    return 0;}/* * read from media stream. *  * fill 'buffer' with data, and buffer size is 'max_size'. * receive one chunk from stream->sock, and fills 'max_size' bytes to buffer. * and if there are more bytes in the chunk, the data is stored to * stream->stream_ctrl->buffer. * *    return value: positive value ... bytes written to buffer. *                  0              ... END OF FILE *                              or ... Clear EVERYTHING!!! RESET!!! *                 -1              ... ERROR */static int mmsh_get_media_packet(struct stream_t *stream,				 uint8_t *buffer, size_t max_size){      static struct asf_stream_chunk_t chunk;    static struct asf_stream_chunk_extra_t chunk_extra;    int chunk_size = 0;    int chunk_type;    int ret;    int data_follows_f;    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    struct mmsh_ctrl_t *mmsh_ctrl = stream_ctrl->mmsh_ctrl;      do {	data_follows_f = 1;    	/* get chunk header from network. */	if(read_data(stream,&chunk,sizeof(chunk)) < sizeof(chunk)) {	    goto failed;	}	/* little endian. (asf streaming interpret as little endian.) */	chunk_type = asf_streaming(&chunk);	/*HTTP message packet ... continue */	if(!(memcmp((uint8_t *)&chunk,"HTTP",4))) {	    struct http_header_t *http_hdr;	    char *field = NULL;	    int len = 0;      	    stream_data_push_back(stream,(uint8_t *)&chunk,sizeof(chunk));	    http_hdr = new_http_header();	    http_recv_header(stream,http_hdr);	    if((field = http_get_field(http_hdr,"Content-Length")) != NULL) {		while(*field == ' ') field++;		len = atoi(field);	    }	    free_http_header(http_hdr);      	    if(len) {		uint8_t *buf = xmalloc(len);		read_data(stream,buf,len);		free(buf); /* Ignore all */	    }	    data_follows_f = 0; /* don't forget to clear this. as no data follows */	}	else if(chunk_type == ASF_STREAMING_END_TRANS) {      	    stream_ctrl->status = STREAMING_FINISHED;	    display(MSDL_DBG,"Transaction finished normally!\n");	    return 0;	}	else if(chunk_type == ASF_STREAMING_CLEAR) {	    stream_ctrl->status = STREAMING_REWIND;      	    /* reset every headerinfo data */	    free_asf_headerinfo_t(mmsh_ctrl->hinfo);	    mmsh_ctrl->hinfo = new_asf_headerinfo_t();	    display(MSDL_VER,"\nClear Configuration! reset!\n");	    data_follows_f = 0; /* loop again , and get header/data/eof packet */	}	else if(chunk_type == ASF_STREAMING_DATA   ||		chunk_type == ASF_STREAMING_DATA2  ||		chunk_type == ASF_STREAMING_HEADER) {	    if(read_data(stream,&chunk_extra,sizeof(chunk_extra)) < 0) {		goto failed;	    }	}	else if(chunk_type == ASF_STREAMING_IGNORE){	    char *buffer;	    buffer = xmalloc(chunk.size - 4);	    read_data(stream,buffer,chunk.size - 4);	    display(MSDL_DBG,"Metadata ----\n");	    dbgdump(buffer, chunk.size - 4);	    display(MSDL_DBG,"-(%d B)--------\n",chunk.size - 4);	    free(buffer);	    data_follows_f = 0;	}	else { /* ignore this*/	    display(MSDL_ERR,"unknown packet type!!\n");	}        } while(data_follows_f == 0);      /*        size of this chunk. ( media stream data )       >>> CAUTION <<<        chunk_size is size of chunk to get from network, but       have to write mmsh_ctrl->packet_size bytes in ASF file.       so 0 padding of 'mmsh_ctrl->packet_size - chunk_size' bytes       is necessary.    */    chunk_size = le2me_16(chunk.size) - sizeof(chunk);      stream_ctrl->packet_count++; /* increment received packet count */        /* header or data, as other packets are already processed */     if(chunk_type == ASF_STREAMING_HEADER) {	struct asf_headerinfo_t *hinfo = mmsh_ctrl->hinfo;    	display(MSDL_DBG,"ASF Header received\n");    	if(chunk_size <= max_size) { /* header can be stored in buffer */	    /* buffer is long enogh. */	    ret = read_data(stream,buffer,chunk_size);	    if(ret < 0) {		goto failed;	    }	    /* no padding, because this is ASF header */	}	else { /* buffer is not long enough for header. */	    /* data is to be written in file, so it goes to write_buffer */	    if(read_data(stream, stream->stream_ctrl->write_buffer, chunk_size) < 0) {		goto failed;	    }	    memcpy(buffer, stream_ctrl->write_buffer, max_size);	    stream_ctrl->write_pos = max_size;	    stream_ctrl->write_data_len = chunk_size - max_size;	    ret = max_size;	}        	/*	  interpret asf_header.	  it has to be done here and doing complecated stuff because      	  . there is "clear configuration" packet, thus header comes multiple times.	  . header we receive in 'mmsh_streaming_start' and one which we got in this	    function differs.	  . we don't know in how many packets the header will come.	  and there are necessary stuff after asf_header, so	  asf_header_len is not likely asfh.objh.size(pure header length, not	  including the "necessary stuff").	  	  :) it sucks...	*/    	/* copy asf header */	hinfo->asf_header = xrealloc(hinfo->asf_header,				     hinfo->asf_header_len + chunk_size);	memcpy(hinfo->asf_header + hinfo->asf_header_len,	       (chunk_size <= max_size) ? buffer : stream_ctrl->write_buffer,	       chunk_size);	hinfo->asf_header_len += chunk_size; /* accumulate */    	if(hinfo->asf_header_len >= sizeof(struct asf_header_t) && 	   hinfo->asf_header_len >=	   le2me_64(((struct asf_header_t *)hinfo->asf_header)->objh.size)) {	    asf_get_file_property(hinfo->asf_header,				  hinfo->asf_header_len,				  hinfo->fileh);	    	    if(ret < 0) { /* error */		display(MSDL_ERR,"asf_get_file_property error\n");		goto failed;	    }      	    stream_ctrl->packet_length = mmsh_ctrl->packet_size =		hinfo->fileh->max_packet_size;	    stream_ctrl->file_size = hinfo->fileh->file_size;	}	return ret;    }    else {	display(MSDL_DBG,"ASF Data received\n");	if(mmsh_ctrl->packet_size < chunk_size) {	    display(MSDL_ERR,"chunk size bigger than pakcet size..\n");	    goto failed;	}      	if(mmsh_ctrl->packet_size <= max_size) {	    /* buffer is bigger enough for this chunk. */	    if(read_data(stream, buffer, chunk_size) < 0) {		goto failed;	    }	    /*{		int j = 0;		for(;j < 16; j++) {		    printf("%02x ",buffer[j]);		}		printf("\n");		}*/	    	    memset(buffer + chunk_size, 0, /* padding */		   mmsh_ctrl->packet_size - chunk_size);	    ret = stream->stream_ctrl->mmsh_ctrl->packet_size;	}	else { /* max_size < packet_size .. cannot write in buffer. */	    if(read_data(stream, stream_ctrl->write_buffer, chunk_size) < 0) {		goto failed;	    }	    /*	      this is OK because netsock->buffer is empty	      when entered this function. 	    */	    memset(stream_ctrl->write_buffer + chunk_size, 0, /* padding */		   mmsh_ctrl->packet_size - chunk_size);	    memcpy(buffer,stream_ctrl->write_buffer, max_size);	    ret = stream_ctrl->write_pos = max_size;      	    stream_ctrl->write_data_len = mmsh_ctrl->packet_size - max_size;	}	return ret;    }    failed: /* probably timeout error */    return -1;  }/* * read mms over http stream. filles buffer, and buffer size is 'size'  * *        read cached data from stream->netsock->buffer *        check for to see if network access is necessary *        get chunk(media packet) from network. * *  return value: bytes written to buffer. -1 if error. */int mmsh_streaming_read(struct stream_t *stream,			uint8_t *buffer, size_t buffer_size){    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    size_t pos = 0; /* how many bytes are in 'buffer' */    int network_read = 0;    if(buffer_size == 0) {	display(MSDL_ERR,"buffer_size must be bigger than 0\n");	return -1;    }      if(stream_ctrl->write_data_len) { /* there are waiting data to be written */    	if(buffer_size <= stream_ctrl->write_data_len) {	    /*	      buffer_size < stream_ctrl->write_data_len...	      fill buffer, and return.	    */	    memcpy(buffer,stream_ctrl->write_buffer + stream_ctrl->write_pos,		   buffer_size);	    stream_ctrl->write_data_len -= buffer_size;	    stream_ctrl->write_pos += buffer_size;	    return buffer_size;	}	else { 	    /*	      stream_ctrl->write_data_len < buffer_size,	      have to read from network.	    */	    memcpy(buffer,stream_ctrl->write_buffer + stream_ctrl->write_pos,		   stream_ctrl->write_data_len);	    pos = stream_ctrl->write_data_len;	    /* and stream_ctrl->write_buffer is empty. */	    stream_ctrl->write_data_len = 0;	    stream_ctrl->write_pos = 0;	}    }        stream_ctrl->write_data_len = 0;    stream_ctrl->write_pos = 0;        /* still have to get data from network. */    if(stream_ctrl->status != STREAMING_FINISHED) { /* not finished */	network_read = mmsh_get_media_packet(stream, buffer + pos, buffer_size - pos);    }      if(network_read >= 0) { /* network read success */	return (network_read + pos);    }    else {        return -1; /* error */    }}struct stream_t *mmsh_streaming_init(){    struct stream_t *stream = streaming_init_common();    stream->stream_ctrl->mmsh_ctrl = new_mmsh_ctrl_t();      stream->start = mmsh_streaming_start;    stream->read  = mmsh_streaming_read;    stream->close = mmsh_streaming_close;       return stream;}void mmsh_streaming_close(struct stream_t *stream){    if(stream->netsock->sock > 0) {	close(stream->netsock->sock);    }    free_mmsh_ctrl_t(stream->stream_ctrl->mmsh_ctrl);    streaming_close_common(stream);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -