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

📄 remux.c

📁 DVBstream is based on the ts-rtp package available at http://www.linuxtv.org. It broadcasts a (subs
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "remux.h"unsigned int bitrates[3][16] ={{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};uint32_t freq[4] = {441, 480, 320, 0};static uint32_t samples[4] = { 384, 1152, 0, 0};char *frames[3] = {"I-Frame","P-Frame","B-Frame"};void copy_ptslm(PTS_List *a, PTS_List *b){	a->pos  = b->pos;	a->PTS  = b->PTS;	a->dts  = b->dts;	a->spos = b->spos;}void clear_ptslm(PTS_List *a){	a->pos  = 0;	a->PTS  = 0;	a->dts  = 0;	a->spos = 0;	}void init_ptsl(PTS_List *ptsl){	int i;	for (i=0;i< MAX_PTS;i++){		clear_ptslm(&ptsl[i]);	}}int del_pts(PTS_List *ptsl, int pos, int nr){	int i;	int del = 0;	for( i = 0; i < nr-1; i++){		if(pos > ptsl[i].pos && pos >= ptsl[i+1].pos) del++;	}	if(del)		for( i = 0; i < nr-del; i++){			copy_ptslm(&ptsl[i], &ptsl[i+del]);		}	return nr-del;}int del_ptss(PTS_List *ptsl, int pts, int *nb){	int i;	int del = 0;	int sum = 0;	int nr = *nb;	for( i = 0; i < nr; i++){		if(pts > ptsl[i].PTS){			del++;			sum += ptsl[i].pos;		}	}	if(del)		for( i = 0; i < nr-del; i++){			copy_ptslm(&ptsl[i], &ptsl[i+del]);		}	*nb = nr-del;	return sum;}int add_pts(PTS_List *ptsl, uint32_t pts, int pos, int spos, int nr, uint32_t dts){	int i;	for ( i=0;i < nr; i++) if (spos &&  ptsl[i].pos == pos) return nr;	if (nr == MAX_PTS) {		nr = del_pts(ptsl, ptsl[1].pos+1, nr);	} else nr++;	i = nr-1;		ptsl[i].pos  = pos;	ptsl[i].spos = spos;	ptsl[i].PTS  = pts;	ptsl[i].dts  = dts;	return nr;}void add_vpts(Remux *rem, uint8_t *pts){	uint32_t PTS = ntohl(trans_pts_dts(pts));	rem->vptsn = add_pts(rem->vpts_list, PTS, rem->vwrite, rem->awrite,			     rem->vptsn, PTS);}void add_apts(Remux *rem, uint8_t *pts){	uint32_t PTS = ntohl(trans_pts_dts(pts));	rem->aptsn = add_pts(rem->apts_list, PTS, rem->awrite, rem->vwrite,			     rem->aptsn, PTS);}void del_vpts(Remux *rem){	rem->vptsn = del_pts(rem->vpts_list, rem->vread, rem->vptsn);}void del_apts(Remux *rem){	rem->aptsn = del_pts(rem->apts_list, rem->aread, rem->aptsn);}void copy_framelm(FRAME_List *a, FRAME_List *b){	a->type  = b->type;	a->pos   = b->pos;	a->FRAME = b->FRAME;	a->time  = b->time;	a->pts   = b->pts;	a->dts   = b->dts;}void clear_framelm(FRAME_List *a){	a->type  = 0;	a->pos   = 0;	a->FRAME = 0;	a->time  = 0; 	a->pts   = 0; 	a->dts   = 0; }void init_framel(FRAME_List *framel){	int i;	for (i=0;i< MAX_FRAME;i++){		clear_framelm(&framel[i]);	}}int del_frame(FRAME_List *framel, int pos, int nr){	int i;	int del = 0;	for( i = 0; i < nr-1; i++){		if(pos > framel[i].pos && pos >= framel[i+1].pos) del++;	}	if(del)		for( i = 0; i < nr-del; i++){			copy_framelm(&framel[i], &framel[i+del]);		}	return nr-del;}int add_frame(FRAME_List *framel, uint32_t frame, int pos, int type, int nr, 	      uint32_t time, uint32_t pts, uint32_t dts){	int i;	if (nr == MAX_FRAME) {		nr = del_frame(framel, framel[1].pos+1, nr);	} else nr++;	i = nr-1;		framel[i].type  = type;	framel[i].pos   = pos;	framel[i].FRAME = frame;	framel[i].time  = time;	framel[i].pts   = pts;	framel[i].dts   = dts;	return nr;}void add_vframe(Remux *rem, uint32_t frame, long int pos, int type, int time, 		uint32_t pts, uint32_t dts){	rem->vframen = add_frame(rem->vframe_list, frame, pos, type,				 rem->vframen, time, pts, dts);}void add_aframe(Remux *rem, uint32_t frame, long int pos, uint32_t pts){	rem->aframen = add_frame(rem->aframe_list, frame, pos, 0, 				 rem->aframen, 0, pts, pts);}void del_vframe(Remux *rem){	rem->vframen = del_frame(rem->vframe_list, rem->vread, rem->vframen);}void del_aframe(Remux *rem){	rem->aframen = del_frame(rem->aframe_list, rem->aread, rem->aframen);}void printpts(uint32_t pts){	fprintf(stderr,"%2d:%02d:%02d.%03d",		(int)(pts/90000.)/3600,		((int)(pts/90000.)%3600)/60,		((int)(pts/90000.)%3600)%60,		(((int)(pts/90.)%3600000)%60000)%1000		);}void find_vframes( Remux *rem, uint8_t *buf, int l){ 	int c = 0;	int type;	uint32_t time = 0;	int hour;	int min;	int sec;	u64 pts=0;	u64 dts=0;	uint32_t tempref = 0;	while ( c < l - 6){		if (buf[c] == 0x00 && 		    buf[c+1] == 0x00 &&		    buf[c+2] == 0x01 && 		    buf[c+3] == 0xB8) {			c += 4;			hour = (int)((buf[c]>>2)& 0x1F);			min  = (int)(((buf[c]<<4)& 0x30)| 				     ((buf[c+1]>>4)& 0x0F));			sec  = (int)(((buf[c+1]<<3)& 0x38)|				      ((buf[c+2]>>5)& 0x07));  			time = 3600*hour + 60*min + sec;			if ( rem->time_off){				time = (uint32_t)((u64)time - rem->time_off);				hour = time/3600;				min  = (time%3600)/60;				sec  = (time%3600)%60;				/*				buf[c]   |= (hour & 0x1F) << 2;				buf[c]   |= (min & 0x30) >> 4;				buf[c+1] |= (min & 0x0F) << 4;				buf[c+1] |= (sec & 0x38) >> 3;				buf[c+2] |= (sec & 0x07) >> 5;*/			}			rem->group++;			rem->groupframe = 0;		}		if ( buf[c] == 0x00 && 		     buf[c+1] == 0x00 &&		     buf[c+2] == 0x01 && 		     buf[c+3] == 0x00) {			c += 4;			tempref = (buf[c+1]>>6) & 0x03;			tempref |= buf[c] << 2;						type = ((buf[c+1]&0x38) >>3);			if ( rem->video_info.framerate){				pts = ((u64)rem->vframe + tempref + 1 					- rem->groupframe ) * 90000ULL					    /rem->video_info.framerate 					+ rem->vpts_off;				dts = (u64)rem->vframe * 90000ULL/					rem->video_info.framerate 					+ rem->vpts_off;							/*	fprintf(stderr,"MYPTS:");printpts((uint32_t)pts-rem->vpts_off); fprintf(stderr,"   REALPTS:"); printpts(rem->vpts_list[rem->vptsn-1].PTS-rem->vpts_off); fprintf(stderr,"   DIFF:"); printpts(pts-(u64)rem->vpts_list[rem->vptsn-1].PTS); fprintf(stderr,"   DIST: %4d",-rem->vpts_list[rem->vptsn-1].pos+(rem->vwrite+c-4)); //fprintf(stderr,"   ERR: %3f",(double)(-rem->vpts_list[rem->vptsn-1].PTS+pts)/(rem->vframe+1)); fprintf(stderr,"\r");				*/												rem->vptsn = add_pts(rem->vpts_list,(uint32_t)pts						     ,rem->vwrite+c-4,						     rem->awrite,						     rem->vptsn,						     (uint32_t)dts);											}			rem->vframe++;			rem->groupframe++;			add_vframe( rem, rem->vframe, rem->vwrite+c, type, 				    time, pts, dts);		} else c++;	}}void find_aframes( Remux *rem, uint8_t *buf, int l){ 	int c = 0;	u64 pts = 0;	int sam;	uint32_t fr;	while ( c < l - 2){		if ( buf[c] == 0xFF && 		     (buf[c+1] & 0xF8) == 0xF8) {			c += 2;			if ( rem->audio_info.layer >= 0){				sam = samples[3-rem->audio_info.layer];				fr = freq[rem->audio_info.frequency] ;					  pts = ( (u64)rem->aframe * sam * 900ULL)/fr				  + rem->apts_off;							  /*  	  fprintf(stderr,"MYPTS:");printpts((uint32_t)pts-rem->apts_off); fprintf(stderr," REALPTS:"); printpts(rem->apts_list[rem->aptsn-1].PTS-rem->apts_off); fprintf(stderr," DIFF:"); printpts((uint32_t)((u64)rem->apts_list[rem->aptsn-1].PTS-pts)); fprintf(stderr," DIST: %4d",-rem->apts_list[rem->aptsn-1].pos+(rem->awrite+c-2)); fprintf(stderr,"\r");			  */			  rem->aptsn = add_pts(rem->apts_list,(uint32_t)pts					     ,rem->awrite+c-2,					     rem->vwrite,					     rem->aptsn,					     (uint32_t)pts);		}			rem->aframe++;			add_aframe( rem, rem->aframe, rem->awrite+c, pts);					} else c++;	}}int refill_buffy(Remux *rem){	pes_packet pes;	int count = 0;	int acount, vcount;	ringbuffy *vbuf = &rem->vid_buffy;	ringbuffy *abuf = &rem->aud_buffy;	int fin = rem->fin;	acount = abuf->size-ring_rest(abuf);	vcount = vbuf->size-ring_rest(vbuf);			while ( acount > MAX_PLENGTH && vcount > MAX_PLENGTH && count < 10){		int neof;		count++;		init_pes(&pes);		if ((neof = read_pes(fin,&pes)) <= 0) return -1;		switch(pes.stream_id){		case AUDIO_STREAM_S ... AUDIO_STREAM_E:			rem->apes++;			if( rem->audio_info.layer < 0 &&			    (pes.flags2 & PTS_DTS) )				add_apts(rem, pes.pts);			find_aframes( rem, pes.pes_pckt_data, pes.length);			ring_write(abuf,(char *)pes.pes_pckt_data,pes.length);			rem->awrite += pes.length;			break;		case VIDEO_STREAM_S ... VIDEO_STREAM_E:			rem->vpes++;			if( !rem->video_info.framerate &&			    (pes.flags2 & PTS_DTS) )				add_vpts(rem, pes.pts);			find_vframes( rem, pes.pes_pckt_data, pes.length);			ring_write(vbuf,(char *)pes.pes_pckt_data,pes.length);			rem->vwrite += pes.length;			break;		}		acount = abuf->size-ring_rest(abuf);		vcount = vbuf->size-ring_rest(vbuf);		kill_pes(&pes);	}	if (count < 10)	return 0;	return 1;}int vring_read( Remux *rem, uint8_t *buf, int l){	int c = 0;	int r = 0;	if (ring_rest(&rem->vid_buffy) <= l)		r = refill_buffy(rem);	if (r) return -1;	c = ring_read(&rem->vid_buffy, (char *) buf, l);	rem->vread += c;	del_vpts(rem);	del_vframe(rem);	return c;}int aring_read( Remux *rem, uint8_t *buf, int l){	int c = 0;	int r = 0;	if (ring_rest(&rem->aud_buffy) <= l)		r = refill_buffy(rem);	if (r) return -1;		c = ring_read(&rem->aud_buffy, (char *)buf, l);	rem->aread += c;	del_apts(rem);	del_aframe(rem);	return c;}int vring_peek( Remux *rem, uint8_t *buf, int l, long off){	int c = 0;		if (ring_rest(&rem->vid_buffy) <= l)		refill_buffy(rem);	c = ring_peek(&rem->vid_buffy, (char *) buf, l, off);	return c;}int aring_peek( Remux *rem, uint8_t *buf, int l, long off){	int c = 0;	if (ring_rest(&rem->aud_buffy) <= l)		refill_buffy(rem);	c = ring_peek(&rem->aud_buffy, (char *)buf, l, off);	return c;}int get_video_info(Remux *rem){	uint8_t buf[12];	uint8_t *headr;	int found = 0;        int sw;	long off = 0;	int form = -1;	ringbuffy *vid_buffy = &rem->vid_buffy;	VideoInfo *vi = &rem->video_info;	while (found < 4 && ring_rest(vid_buffy)){		uint8_t b[3];		vring_peek( rem, b, 4, 0);		if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01		     && b[3] == 0xb3) found = 4;		else {			off++;			vring_read( rem, b, 1);		}	}	rem->vframe = rem->vframen-1;	if (! found) return -1;	buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x01; buf[3] = 0xb3;	headr = buf+4;	if(vring_peek(rem, buf, 12, 0) < 12) return -1;	vi->horizontal_size	= ((headr[1] &0xF0) >> 4) | (headr[0] << 4);	vi->vertical_size	= ((headr[1] &0x0F) << 8) | (headr[2]);            sw = (int)((headr[3]&0xF0) >> 4) ;        switch( sw ){	case 1:		fprintf(stderr,"Videostream: ASPECT: 1:1");		vi->aspect_ratio = 100;        		break;	case 2:		fprintf(stderr,"Videostream: ASPECT: 4:3");                vi->aspect_ratio = 133;        		break;	case 3:		fprintf(stderr,"Videostream: ASPECT: 16:9");                vi->aspect_ratio = 177;        		break;	case 4:		fprintf(stderr,"Videostream: ASPECT: 2.21:1");                vi->aspect_ratio = 221;        		break;        case 5 ... 15:		fprintf(stderr,"Videostream: ASPECT: reserved");                vi->aspect_ratio = 0;        		break;        default:                vi->aspect_ratio = 0;                        return -1;	}        fprintf(stderr,"  Size = %dx%d",vi->horizontal_size,vi->vertical_size);        sw = (int)(headr[3]&0x0F);        switch ( sw ) {	case 1:		fprintf(stderr,"  FRate: 23.976 fps");                vi->framerate = 24000/1001.;		form = -1;		break;	case 2:		fprintf(stderr,"  FRate: 24 fps");                vi->framerate = 24;		form = -1;		break;	case 3:		fprintf(stderr,"  FRate: 25 fps");                vi->framerate = 25;		form = VIDEO_MODE_PAL;		break;	case 4:		fprintf(stderr,"  FRate: 29.97 fps");                vi->framerate = 30000/1001.;		form = VIDEO_MODE_NTSC;		break;	case 5:		fprintf(stderr,"  FRate: 30 fps");                vi->framerate = 30;		form = VIDEO_MODE_NTSC;		break;	case 6:		fprintf(stderr,"  FRate: 50 fps");                vi->framerate = 50;		form = VIDEO_MODE_PAL;		break;	case 7:		fprintf(stderr,"  FRate: 60 fps");                vi->framerate = 60;		form = VIDEO_MODE_NTSC;		break;	}	rem->dts_delay = (int)(7.0/vi->framerate/2.0*90000);	vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) 			    | ((headr[5] << 2) & 0x000003FCUL) | 			    (((headr[6] & 0xC0) >> 6) & 0x00000003UL));	        fprintf(stderr,"  BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);	        fprintf(stderr,"\n");        vi->video_format = form;	/*	marker_bit (&video_bs, 1);	vi->vbv_buffer_size	= getbits (&video_bs, 10);	vi->CSPF		= get1bit (&video_bs);	*/	return form;}int get_audio_info( Remux *rem){	uint8_t *headr;	uint8_t buf[3];	long off = 0;	int found = 0;	ringbuffy *aud_buffy = &rem->aud_buffy;	AudioInfo *ai = &rem->audio_info;		while(!ring_rest(aud_buffy) && !refill_buffy(rem));	while (found < 2 && ring_rest(aud_buffy)){		uint8_t b[2];		refill_buffy(rem);		aring_peek( rem, b, 2, 0);		if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)			found = 2;

⌨️ 快捷键说明

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