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

📄 mmst.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    "packet length    : %d bytes\n",	    asf_header_len,mmst_ctrl->hinfo->fileh->max_packet_size);      stream_ctrl->packet_length = mmst_ctrl->hinfo->fileh->max_packet_size;    mmst_ctrl->num_stream_ids = 	mmst_ctrl->hinfo->streams->n_audio + mmst_ctrl->hinfo->streams->n_video;      /*     * 0x33 command, not understood very well     */    memset(buffer,0,mmst_ctrl->num_stream_ids * 6 + 2);    pos = 0;    display(MSDL_VER,"number of audio stream : %d, video stream = %d\n"	    "best audio stream : %d, video stream : %d\n",	    mmst_ctrl->hinfo->streams->n_audio,	    mmst_ctrl->hinfo->streams->n_video,	    mmst_ctrl->hinfo->streams->audio_id,	    mmst_ctrl->hinfo->streams->video_id);        /*     * chunkLen : 4bytes     * MID      : 4bytes     * cStreamEntries : 4bytes  (num of entries)     * cStreamEntries : (variable, each 6 bytes)     *     * typedef struct {     *     WORD wSrcStreamNumber;     *     WORD wDstStreamNumber;     *     WORD wThinningLevel;     * } STREAM_SWITCH_ENTRY;     *     */        pos = 0;    for(i = 0 ; i < mmst_ctrl->hinfo->streams->n_audio; i++) {	buffer[pos + 0] = 0xFF;	buffer[pos + 1] = 0xFF;	buffer[pos + 2] = mmst_ctrl->hinfo->streams->audio_streams[i];	buffer[pos + 3] = mmst_ctrl->hinfo->streams->audio_streams[i] >> 8;	if(mmst_ctrl->hinfo->streams->audio_streams[i] ==  	   mmst_ctrl->hinfo->streams->audio_id) {	    display(MSDL_DBG,"enable audio stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id);	    buffer[pos + 4] = 0x00;	    buffer[pos + 5] = 0x00; 	}	else {	    display(MSDL_DBG,"disable audio stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id);	    buffer[pos + 4] = 0x02;	    buffer[pos + 5] = 0x00; 	}	pos += 6;    }    for(i = 0 ; i < mmst_ctrl->hinfo->streams->n_video; i++) {	buffer[pos + 0] = 0xFF;	buffer[pos + 1] = 0xFF;	buffer[pos + 2] = mmst_ctrl->hinfo->streams->video_streams[i];	buffer[pos + 3] = mmst_ctrl->hinfo->streams->video_streams[i] >> 8;	if(mmst_ctrl->hinfo->streams->video_streams[i] ==  	   mmst_ctrl->hinfo->streams->video_id) {	    display(MSDL_DBG,"enable video stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id);	    buffer[pos + 4] = 0x00;	    buffer[pos + 5] = 0x00; 	}	else {	    display(MSDL_DBG,"disable video stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id);	    buffer[pos + 4] = 0x02;	    buffer[pos + 5] = 0x00; 	}	pos += 6;    }            send_command(stream,0x33,		 mmst_ctrl->num_stream_ids,                                          /* cStreamEntries */		 buffer[0] | (buffer[1] << 8) | (buffer[2] <<16) | (buffer[3] <<24), /* dirty shift */		 pos - 4,		 buffer + 4);    mmst_get_command_packet(stream);        /*     * 0x07 command. includes ?session value and maximum media stream time     */    memset(buffer,0,40);    for(i = 8 ; i < 16 ; i++) {	buffer[i] = 0xFF;    }    buffer[20] = 0x04;    send_command(stream,0x07,		 1,		 0,		 24,		 buffer);      /**   now everything is done, wait for media packets !!!   **/      free(buffer);    free(buffer2);    /* set status */    stream_ctrl->status = STREAMING_DOWNLOADING;    stream_ctrl->protocol = MMST;    return 1; /* success */  failed:    free(buffer);    free(buffer2);    return 0;}/* * get COMMAND PACKET ONLY , ignore data in commands. * data (media) packets are all ignored, as they are not expected. * should be used only in mmst_streaming_start */static int mmst_get_command_packet(struct stream_t *stream){    uint8_t *pre_header[8];    uint32_t packet_len;    uint32_t command;    uint8_t *combuf;    while(1) {	combuf = NULL;	if(read_data(stream,pre_header,8) <= 0) { /* read_data() failed. */	    goto failed;	}    	if(read_data(stream,&packet_len,4) <= 0) {	    display(MSDL_ERR,"read_data for packet_len failed\n");	    goto failed;	}    	packet_len = get32_le(&packet_len) + 4;    	if(packet_len < 0 || BUF_SIZE < packet_len) {	    display(MSDL_ERR,"%x: invalid packet size\n",packet_len,BUF_SIZE);	    goto failed;	}      	combuf = xmalloc(packet_len);      	if(read_data(stream,combuf,packet_len) <= 0) {	    /* error */	    free(combuf);	    goto failed;	}		display(MSDL_DBG,"=-recv (command)-----------------------------------=\n");	dbgdump(combuf,packet_len);	display(MSDL_DBG,"\n=--------------------------------------------------=\n");	command = get32_le(combuf + 24) & 0xFFFF;	if(command == 0x1b) {	    send_command(stream,0x1b,			 0,			 0,			 0,			 combuf);	    free(combuf);	}	else {	    free(combuf);	    break;	}    }      return 0;  failed:    if(combuf) free(combuf);    return -1;}/* * get each media packet. * * when media packet: get 'packet_len' bytes of data from sock, and store them to buffer. *                    if max_size was smaller(buffer was too small), the rest goes to *                    netsock->buffer. * *    command packet: don't do anything to buffer. * *   return value   :  positive value ... bytes written to 'buffer'. *                     0 ... END OF FILE *                    -1 ... Error. */static int mmst_get_media_packet(struct stream_t *stream, uint8_t *buffer, size_t max_size){    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    uint8_t pre_header[8];    uint32_t packet_len;    uint32_t command;    int ret;      while (1) {    	stream_ctrl->write_data_len = 0;    	if(read_data(stream,pre_header,8) <= 0) {	    display(MSDL_ERR,"could not receive packet pre header\n");	    goto failed;	}  	if(pre_header[4] == 0x04) { /*   media packet   */	    packet_len = get16_le(((uint8_t *)&pre_header) + 6) - 8;      	    stream_ctrl->packet_count++; /* increment packet count */      	    if(packet_len < 0) {		display(MSDL_ERR,"%d: invalid packet size\n",packet_len);		goto failed;	    }      	    if(stream_ctrl->packet_length <= max_size) {		/* buffer is bigger than incoming packet (and padding) */		ret = read_data(stream, buffer, packet_len);		if(ret < 0) {		    display(MSDL_ERR,"couldn't read from netwrok failed\n");		    goto failed;		}		memset(buffer + ret, 0, stream_ctrl->packet_length - ret); /* padding */		ret = stream_ctrl->packet_length;	    }	    else { /* buffer is NOT big enough for incoming packet.. (and padding) */		ret = read_data(stream, stream_ctrl->write_buffer, packet_len);		if(ret < 0) {		    display(MSDL_ERR,"couldn't read from netwrok failed\n");		    goto failed;		}		/* this is OK because stream_ctrl->write_buffer is empty */		memset(stream_ctrl->write_buffer + packet_len, 0, /* padding */		       stream_ctrl->packet_length - packet_len);		memcpy(buffer,stream_ctrl->write_buffer, max_size);		ret = stream_ctrl->write_pos = max_size;		stream_ctrl->write_data_len = stream_ctrl->packet_length - max_size;	    }      	    return ret;	}    	else { /*   command packet    */	    uint8_t *combuf;      	    /* check command packet signiture */	    if(get32_le(((uint8_t *)&pre_header) + 4) != 0xB00BFACE) {		display(MSDL_ERR,"missing command signiture!\n");		goto failed;	    }      	    if(read_data(stream, &packet_len,4) <= 0) {		display(MSDL_ERR,"command packet length read failed\n");		goto failed;	    }    	    packet_len = get32_le(&packet_len) + 4;	    if(packet_len < 0 || packet_len > BUF_SIZE) {		display(MSDL_ERR,"%d: invalid packet size\n",packet_len);		goto failed;	    }	    combuf = xmalloc(packet_len);      	    /* get command packet */	    if(read_data(stream, combuf, packet_len) <= 0) {		display(MSDL_ERR,"command data read failed\n");		free(combuf);		goto failed;	    }	    command = get32_le(combuf + 24) & 0xFFFF;      	    if(command == 0x1B) {		send_command(stream,0x1B,			     0,			     0,			     0,			     combuf);	    }	    else if(command == 0x1E) { /* End Of Stream (EOS) */		stream_ctrl->status = STREAMING_FINISHED;		free(combuf);		return 0; /* End Of Stream!! */	    }	    else if(command == 0x05) {		; /* wired packet, ignore this (not UNKNOWN) */	    }		    else if(command == 0x21) {		; /* wired packet, ignroe this (not UNKNOWN) */	    }	    else {		display(MSDL_DBG,"unknown command %x (ignore this)\n",command);	    }	    free(combuf);	} /* command packet */    } /* while(1) */      return 0;    failed:    return -1;}/* * read mms over http stream. filles buffer, and buffer size is 'size'  * *        read cached data from stream->stream_ctrl->write_buffer *        check for to see if network access is necessary *        get chunk(media packet) from network. * *  return value: bytes written to buffer. */int mmst_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 written to buffer. */    int ret = 0;    if(stream_ctrl->write_data_len) {	/* there are some data to copy in stream_ctrl->write_buffer */	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;        if(stream_ctrl->status != STREAMING_FINISHED) {	/*	  still have to get data from network.	  there are buffer_size - pos bytes to be filled (max)	*/	ret = mmst_get_media_packet(stream, buffer + pos, buffer_size - pos);    }      if(ret >= 0) {	return ret + pos;    }    else {        return -1;    }}struct stream_t *mmst_streaming_init(){    struct stream_t *stream = streaming_init_common();    stream->stream_ctrl->mmst_ctrl = new_mmst_ctrl_t();        stream->start = mmst_streaming_start;    stream->read  = mmst_streaming_read;    stream->close = mmst_streaming_close;      return stream;}void mmst_streaming_close(struct stream_t *stream){    if(stream->netsock->sock > 0) { /* valid socket */	close(stream->netsock->sock);    }    free_mmst_ctrl_t(stream->stream_ctrl->mmst_ctrl);    streaming_close_common(stream);}

⌨️ 快捷键说明

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