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

📄 asf.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    break;      	case ASF_FILE_TRANSFER_MEDIA_STREAM: /* File transfer media stream... 						I don't know what the heck this is.*/	    display(MSDL_VER,"File transfer stream detected, but ignore this.\n");	    break;      	}    }    a_rates = xmalloc(streams->n_audio * sizeof(int));    v_rates = xmalloc(streams->n_video * sizeof(int));      pos = find_asf_guid(header,start,asf_stream_group_guid,asf_header_size);    if(pos >= 0) {	/* stream bitrate proterties object */	int stream_count = 0;	uint8_t *ptr = (uint8_t *)header + pos;		display(MSDL_VER,"stream bitrate properties object\n");    	stream_count = get16_le(ptr); /* little endian. */	ptr += sizeof(uint16_t);	if(ptr > header + asf_header_size) goto failed;	display(MSDL_VER,"stream count = [0x%x] [%u]\n",stream_count,stream_count);	display(MSDL_VER,"audio streams: %d, video streams: %d\n",		streams->n_audio,streams->n_video);	for(i = 0; i < stream_count; i++) {	    uint32_t rate = 0;	    int id = 0;	    int j = 0;      	    id = get16_le(ptr);	    ptr += sizeof(uint16_t);	    if(ptr > header + asf_header_size) goto failed;	    rate = get32_le(ptr);	    ptr += sizeof(uint32_t);	    if(ptr > header + asf_header_size) goto failed;      	    display(MSDL_VER,		    "stream_id   = [0x%x] [%u]\n"		    "max bitrate = [0x%x] [%u]\n",		    id,id,rate,rate);      	    for(j = 0; j < streams->n_audio; j++) {		if(id == streams->audio_streams[j]) {		    display(MSDL_VER,"is audio stream\n");		    a_rates[j] = rate;		    break;		}	    }	    for(j = 0; j < streams->n_video; j++) {		if(id == streams->video_streams[j]) {		    display(MSDL_VER,"is video stream\n");		    v_rates[j] = rate;		    break;		}	    }	}    }    /* just to make sure bw is not Zero! */    if(bw == 0) {	bw = INT_MAX_BANDWIDTH;    }    if(streams->n_audio) {	/* find lowest-bitrate audio stream */	a_rate = a_rates[0];	a_idx = 0;	for(i = 0; i < streams->n_audio; i++) {	    if(a_rates[i] < a_rate) {		a_rate = a_rates[i];		a_idx = i;	    }	}	if(max_idx(streams->n_video,v_rates,bw - a_rate) < 0) {	    /* both audio and video are not possible, try video only next */	    a_idx = -1;	    a_rate = 0;	}    }      /* find best video stream */    v_idx = max_idx(streams->n_video,v_rates,bw - a_rate);    if(v_idx >= 0) {	v_rate = v_rates[v_idx];    }      /* find best auido stream */    a_idx = max_idx(streams->n_audio,a_rates,bw - v_rate);    free(v_rates);    v_rates = NULL;    free(a_rates);    a_rates = NULL;    if(a_idx < 0 && v_idx < 0) {	display(MSDL_ERR,"bandwidth too low ... cannot get streams.");	return -1;    }        if(a_idx >= 0) {	streams->audio_id = streams->audio_streams[a_idx];    }    else if(streams->n_audio) {	display(MSDL_ERR,"Bandwidth too too small so deselected audio....sad.\n");    }      if(v_idx >= 0) {	streams->video_id = streams->video_streams[v_idx];    }    else if(streams->n_video) {	display(MSDL_ERR,"Bandwidth too too small so deselected video....sad.\n");    }        return 1;  failed:    free(v_rates);    free(a_rates);    return -1;}/* * get send_time of ASF data packet * return value: 1 */int asf_data_packet_get_send_time(uint8_t *packet,uint32_t *send_time){    struct asf_data_packet_header_t adph;        asf_parse_data_packet_header(packet,&adph);    *send_time = adph.ppi.send_time;    return 1;}/* * get info for resuming * @send_time  : last packet npt    (out) * @seek_offset: last packet offset (out) * return value:   1 ... success *                -1 ... failure */int asf_get_npt_of_last_packet(char *local_filename,uint32_t *send_time,uint64_t *seek_offset){    FILE *lfp = NULL;    uint8_t *asf_header_buffer = NULL;    uint32_t header_buffer_size = ASF_HEADER_READ_AT_ONCE;    uint32_t header_buffer_filled = 0;    uint8_t *last_packet_buffer = NULL;        size_t ret = 0;    uint64_t asf_header_object_size = 0;    uint64_t asf_packet_start_offset = 0;    struct asf_file_header_t *fileh = NULL;    int packet_size = 0;    uint64_t file_size = 0;    uint64_t last_data_packet_offset = 0;    uint32_t last_send_time = 0;    enum {	ASF_DATA_OBJECT_HEADER_SIZE = 16 + 8 + 16 + 8 + 2,    };    if((lfp = fopen(local_filename,"rb")) == NULL) {	display(MSDL_ERR,		"resume \"%s\" : cannot open file for resume\n",local_filename);	goto failed;    }        asf_header_buffer = (uint8_t *)xmalloc(header_buffer_size);    /* read */    ret = fread(asf_header_buffer,sizeof(uint8_t),header_buffer_size,lfp);    if(!ret) {	if(ferror(lfp)) {	    display(MSDL_ERR,"resume \"%s\": asf_header_buffer_read_failed\n");	    goto failed;	}    }        header_buffer_filled = ret;    if(ret < ASF_HEADER_READ_AT_ONCE) {	if(ferror(lfp)) {	    display(MSDL_ERR,"resume \"%s\": cannot read file \n",local_filename);	}	else {	    display(MSDL_ERR,"resume \"%s\": too small for resume\n",local_filename);	}	/* couldn't read, or just only very small amount of data in file*/	goto failed;    }        if(memcmp(asf_header_buffer,asf_header_object_guid,ASF_GUID_LENGTH)) {	/* not the asf file */	display(MSDL_ERR,"resume \"%s\": not an asf file\n",local_filename);	goto failed;    }    asf_header_object_size = get64_le(asf_header_buffer + ASF_GUID_LENGTH);        /* fill header buffer */    if(asf_header_object_size + ASF_DATA_OBJECT_HEADER_SIZE > header_buffer_size) {	header_buffer_size = asf_header_object_size + ASF_DATA_OBJECT_HEADER_SIZE;	asf_header_buffer = (uint8_t *)xrealloc(asf_header_buffer,header_buffer_size);		ret = fread(asf_header_buffer + header_buffer_filled,		    sizeof(uint8_t),		    header_buffer_size - header_buffer_filled,		    lfp);	if(!ret) {	    if(ferror(lfp)) {		display(MSDL_ERR,"resume \"%s\": asf_header_buffer_read_failed\n");		goto failed;	    }	}    }        /* make sure all file properties object is read in memory */    fileh = new_asf_file_header_t();    packet_size = asf_get_file_property(asf_header_buffer,					asf_header_object_size,					fileh);    if(packet_size < 0) {	display(MSDL_ERR,"resume \"%s\": asf file header error\n",local_filename);	goto failed;    }    if(memcmp(asf_header_buffer + asf_header_object_size,asf_data_object_guid,ASF_GUID_LENGTH)) {	display(MSDL_ERR,"resume \"%s\": could not find ASF_data_object\n",local_filename);	goto failed;    }    asf_packet_start_offset = asf_header_object_size + ASF_DATA_OBJECT_HEADER_SIZE;        ret = get_filesize(local_filename,&file_size);    if(ret < 0) {	/* stat() failed */	goto failed;    }        if(file_size < (packet_size * 2)) { /* not likely, but this will cause problem below */	display(MSDL_ERR,"resume \"%s\": not enough data for getting resume info\n",local_filename);	goto failed;    }    last_data_packet_offset = file_size - ((file_size - asf_packet_start_offset) % packet_size) - packet_size;    display(MSDL_DBG,	    "resume \"%s\": last asf data packet is at 0x%x\n",local_filename,	    last_data_packet_offset);        last_packet_buffer = xmalloc(packet_size);    fseek(lfp,last_data_packet_offset,SEEK_SET);    ret = fread(last_packet_buffer,sizeof(uint8_t),packet_size,lfp);    if(ret < packet_size) {	display(MSDL_ERR,"resume \"%s\": coulnd't read last packet\n",local_filename);	goto failed;    }        asf_data_packet_get_send_time(last_packet_buffer,&last_send_time);        if(lfp) fclose(lfp);    if(asf_header_buffer) free(asf_header_buffer);    if(last_packet_buffer) free(last_packet_buffer);    if(fileh) free_asf_file_header_t(fileh);        display(MSDL_NOR,	    "resume \"%s\": try to resume from %ds\n",local_filename,last_send_time / 1000);    *send_time = last_send_time;    *seek_offset = last_data_packet_offset;    return 1;      failed:    if(lfp) fclose(lfp);    if(asf_header_buffer) free(asf_header_buffer);    if(last_packet_buffer) free(last_packet_buffer);    if(fileh) free_asf_file_header_t(fileh);    display(MSDL_ERR,"just get file from beginning.\n");    *send_time = 0;    *seek_offset = 0;    return -1;}int asf_parse_data_packet_header(uint8_t *packet,struct asf_data_packet_header_t *adph){    uint8_t ecd_flags = packet[0];    uint8_t length_type_flags = 0;    uint8_t property_flags = 0;    int ppi_offset = 0;    int next_offset = 0; /* length type dependent stuff */    const int length_type_table[4] = {0,1,2,4};    adph->ecd.error_correction_data_length = ecd_flags & 0x0f;    adph->ecd.opaque_data_present          = (ecd_flags >> 4) & 0x01;    adph->ecd.error_correction_length_type = (ecd_flags >> 5) & 0x03;    adph->ecd.error_correction_present     = (ecd_flags >> 7) & 0x01;        if(adph->ecd.error_correction_present) {	ppi_offset = 1 + adph->ecd.error_correction_data_length;    }    else {	ppi_offset = 1;    }        length_type_flags = packet[ppi_offset];    property_flags    = packet[ppi_offset + 1];    adph->ppi.multiple_payloads_present = length_type_flags & 0x01;    adph->ppi.sequence_type             = (length_type_flags >> 1) & 0x03;    adph->ppi.padding_length_type       = (length_type_flags >> 3) & 0x03;    adph->ppi.packet_length_type        = (length_type_flags >> 5) & 0x03;    adph->ppi.error_correction_present  = (length_type_flags >> 7) & 0x01;        adph->ppi.replicated_data_length_type          = property_flags & 0x03;    adph->ppi.offset_into_media_object_length_type = (property_flags >> 2) & 0x03;    adph->ppi.media_object_number_length_type      = (property_flags >> 4) & 0x03;    adph->ppi.stream_number_length_type            = (property_flags >> 6) & 0x03;        next_offset = ppi_offset + 2;    /* packet length  */    adph->ppi.packet_length = 	getnb_le(packet + next_offset,length_type_table[adph->ppi.packet_length_type]);    next_offset += length_type_table[adph->ppi.packet_length_type];    /* sequence       */    adph->ppi.sequence = 	getnb_le(packet + next_offset,length_type_table[adph->ppi.sequence_type]);    next_offset += length_type_table[adph->ppi.sequence_type];    /* padding length */    adph->ppi.padding_length = 	getnb_le(packet + next_offset,length_type_table[adph->ppi.padding_length_type]);    next_offset += length_type_table[adph->ppi.padding_length_type];        adph->ppi.send_time = get32_le(packet + next_offset);    next_offset += sizeof(uint32_t);        adph->ppi.duration = get16_le(packet + next_offset);    next_offset += sizeof(uint16_t);        return next_offset;}

⌨️ 快捷键说明

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