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

📄 remux.c

📁 DVBstream is based on the ts-rtp package available at http://www.linuxtv.org. It broadcasts a (subs
💻 C
📖 第 1 页 / 共 2 页
字号:
		else {			off++;			aring_read( rem, b, 1);		}	}		if (!found) return -1;	rem->aframe = rem->aframen-1;		if (aring_peek(rem, buf, 3, 0) < 1) return -1;	headr = buf+2;	ai->layer = (buf[1] & 0x06) >> 1;        fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);	ai->bit_rate = bitrates[(3-ai->layer)][(headr[0] >> 4 )]*1000;	if (ai->bit_rate == 0)		fprintf (stderr,"  Bit rate: free");	else if (ai->bit_rate == 0xf)		fprintf (stderr,"  BRate: reserved");	else		fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);		ai->frequency = (headr[0] & 0x0c ) >> 2;	if (ai->frequency == 3)		fprintf (stderr, "  Freq: reserved\n");	else		fprintf (stderr,"  Freq: %2.1f kHz\n", 			 freq[ai->frequency]/10.);	return 0;}void init_remux(Remux *rem, int fin, int fout, int mult){	rem->video_info.framerate = 0;	rem->audio_info.layer = -1;	rem->fin = fin;	rem->fout = fout;	ring_init(&rem->vid_buffy, 40*BUFFYSIZE*mult);	ring_init(&rem->aud_buffy, BUFFYSIZE*mult);	init_ptsl(rem->vpts_list);	init_ptsl(rem->apts_list);	init_framel(rem->vframe_list);	init_framel(rem->aframe_list);	rem->vptsn     = 0;	rem->aptsn     = 0;	rem->vframen   = 0;	rem->aframen   = 0;	rem->vframe    = 0;	rem->aframe    = 0;	rem->vcframe   = 0;	rem->acframe   = 0;	rem->vpts      = 0;	rem->vdts      = 0;	rem->apts_off  = 0;	rem->vpts_off  = 0;	rem->apts_delay= 0;	rem->vpts_delay= 0;	rem->dts_delay = 0;	rem->apts      = 0;	rem->vpes      = 0;	rem->apes      = 0;	rem->vpts_old  = 0;	rem->apts_old  = 0;	rem->SCR       = 0;	rem->vwrite    = 0;	rem->awrite    = 0;	rem->vread     = 0;	rem->aread     = 0;	rem->group     = 0;	rem->groupframe= 0;	rem->pack_size = 0;	rem->muxr      = 0;	rem->time_off  = 0;}uint32_t bytes2pts(int bytes, int rate){	if (bytes < 0xFFFFFFFFUL/720000UL)		return (uint32_t)(bytes*720000UL/rate);	else		return (uint32_t)(bytes/rate*720000UL);}long pts2bytes( uint32_t pts, int rate){	if (pts < 0xEFFFFFFFUL/rate)		return (pts*rate/720000);	else 		return (pts* (rate/720000));}int write_audio_pes( Remux *rem, uint8_t *buf, int *alength){	int add;	int pos = 0;	int p   = 0;	uint32_t pts = 0;	int stuff = 0;	int length = *alength;	if (!length) return 0;	p = PS_HEADER_L1+PES_H_MIN;	if (rem->apts_old != rem->apts){		pts = (uint32_t)((u64)rem->apts + rem->apts_delay - rem->apts_off);		p += 5;	}	if ( length+p >= rem->pack_size){		length = rem->pack_size;	} else {		if (rem->pack_size-length-p <= PES_MIN){			stuff = rem->pack_size - length;			length = rem->pack_size;		} else 			length = length+p;	}	pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, 			      0, 0, 0, 0, 0, 0);	pos += write_pes_header( 0xC0, length-pos, pts, buf+pos, stuff);	add = aring_read( rem, buf+pos, length-pos);	*alength = add;	if (add < 0) return -1;	pos += add;	rem->apts_old = rem->apts;	rem->apts = rem->apts_list[0].PTS;	if (pos+PES_MIN < rem->pack_size){		pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,					 buf+pos, 0);		pos = rem->pack_size;	}			if (pos != rem->pack_size) {		fprintf(stderr,"apos: %d\n",pos);		exit(1);	}	return pos;}int write_video_pes( Remux *rem, uint8_t *buf, int *vlength){	int add;	int pos = 0;	int p   = 0;	uint32_t pts = 0;	uint32_t dts = 0;	int stuff = 0;	int length = *vlength;	long diff = 0;	if (! length) return 0;	p = PS_HEADER_L1+PES_H_MIN;	if (rem->vpts_old != rem->vpts){		pts = (uint32_t)((u64)rem->vpts + rem->vpts_delay - rem->vpts_off);		p += 5;	}	if ( length+p >= rem->pack_size){		length = rem->pack_size;	} else {		if (rem->pack_size - length - p <= PES_MIN){			stuff = rem->pack_size - length;			length = rem->pack_size;		} else 			length = length+p;	}	pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, 			      0, 0, 0, 0, 0, 0);	pos += write_pes_header( 0xE0, length-pos, pts, buf+pos, stuff);	add = vring_read( rem, buf+pos, length-pos);	*vlength = add;	if (add < 0) return -1;	pos += add;	rem->vpts_old = rem->vpts;	dts = rem->vdts;	rem->vpts = rem->vpts_list[0].PTS;	rem->vdts = rem->vpts_list[0].dts;	if ( diff > 0) rem->SCR += diff;	if (pos+PES_MIN < rem->pack_size){		//  fprintf(stderr,"vstuffing: %d   \n",rem->pack_size-pos);		pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,					 buf+pos, 0);		pos = rem->pack_size;	}			return pos;}void print_info( Remux *rem , int ret){	int newtime = 0;	static int time = 0;	int i = 0;	while(! newtime && i < rem->vframen) {		if( (newtime = rem->vframe_list[i].time)) break;		i++;	}	if (newtime) time = newtime;		fprintf(stderr,"SCR:");	printpts(rem->SCR);	fprintf(stderr," VDTS:");	printpts((uint32_t)((u64)rem->vdts - rem->vpts_off + rem->vpts_delay));	fprintf(stderr," APTS:");	printpts((uint32_t)((u64)rem->apts - rem->apts_off + rem->apts_delay));	fprintf(stderr," TIME:%2d:", time/3600);	fprintf(stderr,"%02d:", (time%3600)/60);	fprintf(stderr,"%02d", (time%3600)%60);	if (ret) fprintf(stderr,"\n");	else fprintf(stderr,"\r");}void remux(int fin, int fout, int pack_size, int mult){	Remux rem;	long ptsdiff;	uint8_t buf[MAX_PACK_L];	long pos = 0;	int r = 0;	int i, r1, r2;	long packets = 0;	uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };	uint32_t SCR_inc = 0;	int data_size;	long vbuf, abuf;	long vbuf_max, abuf_max;	PTS_List abufl[MAX_PTS];	PTS_List vbufl[MAX_PTS];	int abufn = 0;	int vbufn = 0;	u64 pts_d = 0;	int ok_audio; 	int ok_video; 	uint32_t apos = 0;	uint32_t vpos = 0;	int vpack_size = 0;	int apack_size = 0;	init_ptsl(abufl);	init_ptsl(vbufl);	init_remux(&rem, fin, fout, mult);	rem.pack_size = pack_size;	data_size = pack_size - MAX_H_SIZE;	fprintf(stderr,"pack_size: %d header_size: %d data size: %d\n",		pack_size, MAX_H_SIZE, data_size);	refill_buffy(&rem);	fprintf(stderr,"Package size: %d\n",pack_size);		if ( get_video_info(&rem) < 0 ){		fprintf(stderr,"ERROR: Can't find valid video stream\n");		exit(1);	}	i = 0;	while(! rem.time_off && i < rem.vframen) {		if( (rem.time_off = rem.vframe_list[i].time)) break;		i++;	}	if ( get_audio_info(&rem) < 0 ){		fprintf(stderr,"ERROR: Can't find valid audio stream\n");		exit(1);	}		rem.vpts = rem.vpts_list[0].PTS;	rem.vdts = rem.vpts;	rem.vpts_off = rem.vpts;	fprintf(stderr,"Video start PTS = %fs \n",rem.vpts_off/90000.);	rem.apts = rem.apts_list[0].PTS;	rem.apts_off = rem.apts;	ptsdiff = rem.vpts - rem.apts;	if (ptsdiff > 0) rem.vpts_off -= ptsdiff;	else rem.apts_off -= -ptsdiff;	fprintf(stderr,"Audio start PTS = %fs\n",rem.apts_off/90000.);	fprintf(stderr,"Difference Video - Audio = %fs\n",ptsdiff/90000.);	fprintf(stderr,"Time offset = %ds\n",rem.time_off);	rem.muxr = (rem.video_info.bit_rate + 		    rem.audio_info.bit_rate)/400;	fprintf(stderr,"MUXRATE: %.2f Mb/sec\n",rem.muxr/2500.);	SCR_inc = 1800 * pack_size / rem.muxr;		r = 0;	while ( rem.vptsn < 2 && !r) r = refill_buffy(&rem);	r = 0;	while ( rem.aptsn < 2 && !r) r = refill_buffy(&rem);	//rem.vpts_delay =  (uint32_t)(2*90000ULL* (u64)pack_size/rem.muxr);	rem.vpts_delay = rem.dts_delay;	rem.apts_delay = rem.vpts_delay;	vbuf_max = 29440;	abuf_max = 4096;	vbuf = 0;	abuf = 0;	pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, 			      0xC0, 0, 32, 0xE0, 1, 230);	pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, buf+pos,0);	pos = rem.pack_size;	write( fout, buf, pos);	apos = rem.aread;	vpos = rem.vread;	print_info( &rem, 1 );	while( ring_rest(&rem.aud_buffy) && ring_rest(&rem.vid_buffy) ){		uint32_t next_apts;		uint32_t next_vdts;		int asize, vsize;		r1 = 0;		r2 = 0;		while ( rem.aframen < 2 && !r1) 			r1 = refill_buffy(&rem);		while ( rem.vframen < 2 && !r2) 			r2 = refill_buffy(&rem);		if (r1 && r2) break;		if ( !r1 && apos <= rem.aread)			apos = rem.aframe_list[1].pos;		if ( !r2 && vpos <= rem.vread)			vpos = rem.vframe_list[1].pos;		apack_size = apos - rem.aread; 		vpack_size = vpos - rem.vread; 				next_vdts = (uint32_t)((u64)rem.vdts + rem.vpts_delay 				  - rem.vpts_off) ;		ok_video = ( rem.SCR < next_vdts);		next_apts = (uint32_t)((u64)rem.apts + rem.apts_delay 				  - rem.apts_off) ;		ok_audio = ( rem.SCR  < next_apts);		asize = (apack_size > data_size ? data_size: apack_size);		vsize = (vpack_size > data_size ? data_size: vpack_size);		fprintf(stderr,"vframen: %d  aframen: %d  v_ok: %d  a_ok: %d  v_buf: %d  a_buf: %d vpacks: %d  apacks: %d\n",rem.vframen,rem.aframen, ok_video, ok_audio, (int)vbuf,(int)abuf,vsize, asize);				if( vbuf+vsize  < vbuf_max && vsize && ok_audio ){			fprintf(stderr,"1 ");			pos = write_video_pes( &rem, buf, &vpack_size);			write( fout, buf, pos);			vbuf += vpack_size;			vbufn = add_pts( vbufl, rem.vdts, vpack_size, 					 0, vbufn, 0);			packets++;		} else if ( abuf+asize < abuf_max && asize &&			    ok_video  ){			fprintf(stderr,"2 ");			pos = write_audio_pes( &rem, buf, &apack_size);			write( fout, buf, pos);			abuf += apack_size;			abufn = add_pts( abufl, rem.apts, apack_size, 					 0, abufn, 0);			packets++;		} else if ( abuf+asize < abuf_max && asize &&			    !ok_audio){			fprintf(stderr,"3 ");			pos = write_audio_pes( &rem, buf, &apack_size);			write( fout, buf, pos);			abuf += apack_size;			abufn = add_pts( abufl, rem.apts, apack_size, 					 0, abufn, 0);			packets++;		} else if (vbuf+vsize  < vbuf_max && vsize &&			   !ok_video){			fprintf(stderr,"4 ");			pos = write_video_pes( &rem, buf, &vpack_size);			write( fout, buf, pos);			vbuf += vpack_size;			vbufn = add_pts( vbufl, rem.vdts, vpack_size, 					 0, vbufn, 0);			packets++;		} else {		fprintf(stderr,"5 ");			pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 					      1, 1, 1, 0, 0, 0, 0, 0, 0);			pos += write_pes_header( PADDING_STREAM, pack_size-pos,						 0, buf+pos, 0);			write( fout, buf, pos);		}		//fprintf(stderr,"vbufn: %d  abufn: %d  ", vbufn,abufn);		//fprintf(stderr,"vbuf: %5d  abuf: %4d\n", vbuf,abuf);		if (rem.SCR > rem.vdts+rem.vpts_off -rem.vpts_delay) 			rem.SCR = rem.vdts-rem.vpts_off;		rem.SCR = (uint32_t)((u64) rem.SCR + SCR_inc);		if ( rem.apts_off + rem.SCR < rem.apts_delay ) pts_d = 0;		else pts_d = (u64) rem.SCR + rem.apts_off - rem.apts_delay;		abuf -= del_ptss( abufl, (uint32_t) pts_d, &abufn);		if ( rem.vpts_off + rem.SCR < rem.vpts_delay ) pts_d = 0;		else pts_d = (u64) rem.SCR + rem.vpts_off - rem.vpts_delay;		vbuf -= del_ptss( vbufl, (uint32_t) pts_d, &vbufn);		print_info( &rem, 1);		//fprintf(stderr,"vbufn: %d  abufn: %d  ", vbufn,abufn);		//fprintf(stderr,"vbuf: %5d  abuf: %4d\n\n", vbuf,abuf);	}	pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, 			      0, 0, 0, 0, 0, 0);	pos += write_pes_header( PADDING_STREAM, pack_size-pos-4, 0, 				 buf+pos, 0);	pos = rem.pack_size-4;	write( fout, buf, pos);	write( fout, mpeg_end, 4);	fprintf(stderr,"\ndone\n");}typedef struct pes_buffer_s{	ringbuffy   pes_buffy;	uint8_t     type;	PTS_List    pts_list[MAX_PTS];	FRAME_List  frame_list[MAX_FRAME];	int         pes_size;	uint64_t    written;	uint64_t    read;} PESBuffer;void init_PESBuffer(PESBuffer *pbuf, int pes_size, int buf_size, uint8_t type){	init_framel( pbuf->frame_list);	init_ptsl( pbuf->pts_list);	ring_init( &pbuf->pes_buffy, buf_size);	pbuf->pes_size = pes_size;	pbuf->type = type; 	pbuf->written = 0;	pbuf->read = 0;}	#define MAX_PBUF 4typedefstruct remux_s{	PESBuffer pbuf_list[MAX_PBUF];	int num_pbuf;} REMUX;void init_REMUX(REMUX *rem){	rem->num_pbuf = 0;}#define REPACK      2048 #define ABUF_SIZE   REPACK*1024#define VBUF_SIZE   REPACK*10240void remux_main(uint8_t *buf, int count, p2p *p){	int i, b;	int bufsize = 0;	PESBuffer *pbuf;	REMUX *rem = (REMUX *) p->data;	uint8_t type = buf[3];	int *npbuf = &(rem->num_pbuf);	switch ( type ){	case PRIVATE_STREAM1:		bufsize = ABUF_SIZE;	case VIDEO_STREAM_S ... VIDEO_STREAM_E:		if (!bufsize) bufsize = VBUF_SIZE;	case AUDIO_STREAM_S ... AUDIO_STREAM_E:		if (!bufsize) bufsize = ABUF_SIZE;		b = -1;		for ( i = 0; i < *npbuf; i++){			if ( type == rem->pbuf_list[i].type ){				b = i;				break;			}		}		if (b < 0){			if ( *npbuf < MAX_PBUF ){				init_PESBuffer(&rem->pbuf_list[*npbuf], 					       p->repack+6, bufsize, type);				b = *npbuf;				(*npbuf)++;			} else {				fprintf(stderr,"Not enough PES buffers\n");				exit(1);			}		}		break;	default:		return;	}		pbuf = &(rem->pbuf_list[b]);	if (ring_write(&(pbuf->pes_buffy),(char *)buf,count) != count){		fprintf(stderr,"buffer overflow type 0x%2x\n",type);		exit(1);	} else {		pbuf->written += count;		if ((p->flag2 & PTS_DTS_FLAGS)){			uint32_t PTS = ntohl(trans_pts_dts(p->pts));			add_pts(pbuf->pts_list, PTS, pbuf->written, 				pbuf->written, 0, 0);		}		p->flag2 = 0;	}}void output_mux(p2p *p) {	int i, filling;	PESBuffer *pbuf;	ringbuffy   *pes_buffy;		REMUX *rem = (REMUX *) p->data;	int repack = p->repack;	int npbuf = rem->num_pbuf;	for ( i = 0; i < npbuf; i++){		pbuf = &(rem->pbuf_list[i]);		pes_buffy = &pbuf->pes_buffy;		filling = pes_buffy->size - ring_rest(pes_buffy);		if (filling/(2 *repack)){			pbuf->read += ring_read_file(pes_buffy, p->fd1, 						     (filling/repack)*repack);		}	}}#define SIZE 32768void remux2(int fdin, int fdout){	p2p p;	int count = 1;	uint8_t buf[SIZE];	uint64_t length = 0;	uint64_t l = 0;	int verb = 0;	REMUX rem;		init_p2p(&p, remux_main, REPACK);	p.fd1 = fdout;	p.data = (void *) &rem;		if (fdin != STDIN_FILENO) verb = 1; 	if (verb) {		length = lseek(fdin, 0, SEEK_END);		lseek(fdin,0,SEEK_SET);	}	while (count > 0){		count = read(fdin,buf,SIZE);		l += count;		if (verb)			fprintf(stderr,"Writing  %2.2f %%\r",				100.*l/length);		get_pes(buf,count,&p,pes_repack);		output_mux(&p);	}		}

⌨️ 快捷键说明

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