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

📄 real.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	stream_data_push_back(stream,header,8); /* push back header */	ret = real_process_header(stream);	if(ret < 0) {	    goto failed;	}		ret = read_data(stream,header,8);	if(ret < 8) {	    goto failed;	}    }        ret = real_process_media_packet(stream,header,buffer,max_size);    return ret;  failed:    return -1;}/* * process rtsp header coming among rtsp real media packet *  * return value:       status code ... normal proceed case *                               0 ... EOF packet (not possible) *                              -1 ... error */static int real_process_header(struct stream_t *stream){    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    struct rtsp_ctrl_t *rtsp_ctrl = stream_ctrl->rtsp_ctrl;    struct rtsp_header_t *rtsp_hdr = NULL;    int status_code = 0;    int bodylen = 0;    uint8_t *body = NULL;    char *field = NULL;    int got_cseq = 0;    rtsp_hdr = new_rtsp_header();    status_code = rtsp_recv_header(stream,rtsp_hdr);    if(status_code < 0) {	goto failed;    }            /* get content length data */    if((field = rtsp_get_field(rtsp_hdr,"Content-length")) != NULL) {	while(*field == ' ') field++;	bodylen = atoi(field);		body = xmalloc(bodylen);	bodylen = read_data(stream,body,bodylen);    }    /* get Cseq, for sending OK back */    if((field = rtsp_get_field(rtsp_hdr,"Cseq")) != NULL) {	while(*field == ' ') field++;	got_cseq = atoi(field);	    }    if(!strncasecmp(rtsp_hdr->protocol,"RTSP",4)) { /* RTSP/1.0 200 OK , ignore this */	/*	  somehow RTSP message reply can be found among rdt messages.	  send nothing.	*/	if(!got_cseq == rtsp_ctrl->cseq - 1) {	    display(MSDL_DBG,"CSeq mismatch: expected %d, got %d",		    rtsp_ctrl->cseq - 1,got_cseq);	}	/* DO NOT send RTSP OK */    }    else { /* not RTSP, whatever it is, send OK would be just fine  */	rtsp_200ok(stream,got_cseq,rtsp_ctrl->session);    }        if(rtsp_hdr) free_rtsp_header(rtsp_hdr);          if(body)     free(body);    return status_code;  failed:    if(body)     free(body);    if(rtsp_hdr) free_rtsp_header(rtsp_hdr);    return -1;}static int real_process_media_packet(struct stream_t *stream,uint8_t *header,				     uint8_t *buffer,size_t max_size){    int ret = 0;    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    struct rmff_pheader_t ph = {0};    int size = 0;    int seq = 0;    int flags1 = 0,flags2 = 0;    uint32_t ts = 0;    if(header[0] != 0x24) {	display(MSDL_ERR,"wrong rdt magic : [0x%02x]\n",header[0]);	/* dump header*/	dbgdump(header,8);	display(MSDL_DBG,"\n");	goto failed;    }    size = (header[1] << 16) + (header[2] << 8) + header[3];    flags1 = header[4];      if((flags1!=0x40) && (flags1!=0x42)) {	display(MSDL_DBG,"wrong rdt flags1 : [0x%02x]\n",flags1);	if(header[6] == 0x06) {	    display(MSDL_DBG,"got end of stream packet\n");	    stream_ctrl->status = STREAMING_FINISHED;	    return 0;	}	header[0] = header[5];	header[1] = header[6];	header[2] = header[7];		ret = read_data(stream,header + 3,5);	if(ret < 5) goto failed;    	ret = read_data(stream,header + 4,4);	if(ret < 4) goto failed;    	flags1 = header[4];	size -= 9;        }    flags2 = header[7];    seq = (header[5] << 8) + header[6];    ret = read_data(stream,header,6);    if(ret < 6) goto failed;      ts = get32_be(header);    stream_ctrl->packet_count++;    display(MSDL_DBG,"ts:%u size:%u, flags1:0x%02x, seq:%d, flags2:%x\n",	    ts,size,flags1,seq,flags2);        size += 2;      ph.object_version = 0;    ph.length = size;    ph.stream_number = (flags1>>1) & 1;    ph.timestamp = ts;    ph.reserved = 0;      if((flags2 & 1) == 0 &&       (stream_ctrl->rtsp_ctrl->prev_ts != ts ||	stream_ctrl->rtsp_ctrl->prev_stream_number != ph.stream_number)) {	stream_ctrl->rtsp_ctrl->prev_ts = ts;	stream_ctrl->rtsp_ctrl->prev_stream_number = ph.stream_number;	ph.flags = 2;    }    else {	ph.flags = 0;    }      /*     * Keep Alive SET_PARAMETER     */    /*if(!(stream_ctrl->packet_count % 200)) {	struct rtsp_header_t *rtsp_hdr;	rtsp_hdr = new_rtsp_header_with_standard_fields(stream_ctrl->rtsp_ctrl);	if(stream->dlopts->bandwidth) {	    char *buffer = xmalloc(BUFSIZE_1K);	    snprintf(buffer,BUFSIZE_1K - 1,		     "SetDeliveryBandwidth: Bandwidth=%d;BackOff=0",stream->dlopts->bandwidth);	    rtsp_set_field(rtsp_hdr,buffer);	    free(buffer);	}	rtsp_request_set_parameter(rtsp_hdr,stream_ctrl->rtsp_ctrl->mrl);	rtsp_send_request_and_free(stream,rtsp_hdr);	}*/        /* if buffering, do special thing */    if(stream_ctrl->status == STREAMING_RESUME_BUFFERING) {	display(MSDL_DBG,		"target ts: %d [0x%x], current packet ts: %d [0x%x]\n",		stream_ctrl->rtsp_ctrl->resume_start_ts,		stream_ctrl->rtsp_ctrl->resume_start_ts,		ph.timestamp,ph.timestamp);	if(ph.timestamp == stream_ctrl->rtsp_ctrl->resume_start_ts) {	    stream_ctrl->status = STREAMING_DOWNLOADING; /* fallthrouh */	}	else {	    int ret = 0;	    ret = read_data(stream,stream_ctrl->write_buffer,size - 12); /* trash data */	    if(ret <= 0) goto failed;	    return 0;	}    }    if(max_size > size) {	/* all data can go to buffer --> just do it!! */	rmff_dump_pheader(&ph,buffer);	size -= 12;	ret = read_data(stream,buffer + 12,size);	if(ret <= 0) goto failed;    	return ret + 12;    }    else {	/*	  buffer is not enough.. copy max_size data to 	  buffer and the rest goes to netsock->buffer.	*/	rmff_dump_pheader(&ph,stream_ctrl->write_buffer);    	ret = read_data(stream,stream_ctrl->write_buffer + 12,size - 12);	if(ret <= 0) goto failed;		/*	  it is guranteed that netsock->buffer is	  empty when it comes here!	  --> reset stream_ctrl->write_pos and so on...	*/    	memcpy(buffer,stream_ctrl->write_buffer,max_size);	stream_ctrl->write_data_len = size - max_size;	stream_ctrl->write_pos = max_size;    	return max_size;    }      failed:    return -1;}/* * prepare_resuming for real rtsp * return value:     1 ... success *                  -1 ... failed */int real_prepare_resuming(struct stream_t *stream){    uint32_t last_send_time = 0;    uint64_t seek_pos = 0;    int ret = 0;    ret = real_get_last_npt_of_file(stream->localfile,&last_send_time,&seek_pos);    if(ret < 0) {	goto failed;    }        if((last_send_time / 1000) < MINIMUM_RESUME_START_TIME) {	display(MSDL_ERR,		"file \"%s\" has only %d sec, just start from beginning\n",		stream->localfile,last_send_time / 1000);	goto failed;    }    stream->stream_ctrl->rtsp_ctrl->resume_start_ts = last_send_time;    if(stream->dlopts->range) {	free(stream->dlopts->range);    }    stream->dlopts->range =	rtsp_make_range_from_timestamp(last_send_time - RESUME_BUFFERING_TIME);    stream->resumeinfo->resume_start_offset = seek_pos;    stream->resumeinfo->resume_req_success = 1;        display(MSDL_DBG,	    "real resume: start ts: %d [0x%x]  pos: %lld [0x%llx]\n",	    last_send_time,last_send_time,seek_pos,seek_pos);        return 1;  failed:    stream->resumeinfo->resume_start_offset = 0;    stream->resumeinfo->resume_req_success  = 0;    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 real_get_last_npt_of_file(char *local_filename,uint32_t *send_time,uint64_t *seek_offset){    FILE *lfp = NULL;    uint32_t header_buffer_size = 400;    uint32_t header_buffer_filled = 0;    uint8_t *rmff_header_buffer = NULL;    int ret = 0;    uint64_t file_size = 0;    uint64_t rmff_data_start_pos = 0;    uint64_t curpos = 0;    uint8_t phbuf[18];    struct rmff_pheader_t ph = {0};    uint32_t last_ts = 0,this_ts = 0;    uint64_t last_ts_offset = 0;        if((lfp = fopen(local_filename,"rb")) == NULL) {	display(MSDL_ERR,		"resume \"%s\" : cannot open file for resume\n",local_filename);	goto failed;    }        rmff_header_buffer = (uint8_t *)xmalloc(header_buffer_size);    /* 1st read */    ret = fread(rmff_header_buffer,sizeof(uint8_t),header_buffer_size,lfp);    header_buffer_filled = ret;        if(ret < header_buffer_size) {	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(get32_be(rmff_header_buffer) != RMF_TAG) {	/* not the rmff file */	display(MSDL_ERR,"resume \"%s\": not an real file\n",local_filename);	goto failed;    }    ret = get_filesize(local_filename,&file_size);    if(ret < 0) {	/* stat() failed */	goto failed;    }    rmff_data_start_pos = get32_be(rmff_header_buffer + 60) + 18;    last_ts = 0;        for(curpos = rmff_data_start_pos;	curpos + sizeof(struct rmff_pheader_t) <= file_size;) {		fseek(lfp,curpos,SEEK_SET);	ret = fread(phbuf,sizeof(uint8_t),sizeof(struct rmff_pheader_t),lfp);	rmff_read_pheader(phbuf,&ph);	if(ret < sizeof(struct rmff_pheader_t)) {	    display(MSDL_ERR,"resume \"%s\": pheader read error",local_filename);	    goto failed;	}	this_ts = ph.timestamp;	/*	printf("this_ts = %d [%x] ph_length = %d %x,cur:%x last:%x (%d)\n",	this_ts,this_ts,	ph.length,ph.length,	curpos,	last_ts_offset,last_ts_offset);	*/	if(this_ts > last_ts) { /* renew ts */	    last_ts = this_ts;	    last_ts_offset = curpos;	    this_ts = 0;	}		curpos += ph.length;    }        fclose(lfp);    free(rmff_header_buffer);    *send_time = last_ts;    *seek_offset = last_ts_offset;    return 1;  failed:    if(lfp) fclose(lfp);    if(rmff_header_buffer) free(rmff_header_buffer);    *send_time = 0;    *seek_offset = 0;    return -1;}

⌨️ 快捷键说明

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