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

📄 main.c

📁 gm8120的video控制
💻 C
📖 第 1 页 / 共 4 页
字号:
	int off = 41, i;

	if( get_field( d, 1, &off ) ) off += 7; // object layer identifier
	if( get_field( d, 4, &off ) == 15 ) // aspect ratio info
		off += 16; // extended par
	if( get_field( d, 1, &off ) ) // vol control parameters
	{
		off += 3; // chroma format, low delay
		if( get_field( d, 1, &off ) ) off += 79; // vbw parameters
	}
	off += 2; // video object layer shape
	if( ! get_field( d, 1, &off ) )
	{
		
		return;
	}
	i = out->vop_time_increment_resolution = get_field( d, 16, &off );
	
	if( ! get_field( d, 1, &off ) )
	{
		
		return;
	}
	for( out->vtir_bitlen = 0; i != 0; i >>= 1 ) ++out->vtir_bitlen;
	if( get_field( d, 1, &off ) )
	{
		out->vop_time_increment = get_field( d, out->vtir_bitlen, &off );
		
		printf("vop_time_increment=%d \n", out->vop_time_increment);
		
		if( out->vop_time_increment == 0 )
		{

			return;
		}
		
		
	} else out->vop_time_increment = 0;

}

static int parse_mpeg4_frame( struct frame_info *out, unsigned char *d, int len )
{
	unsigned int start_code;

	start_code = GET_32( d );


	if( start_code >= 0x00000120 && start_code <= 0x0000012F )
	{
		parse_video_object_layer( out, d, len );
		return 1;
	}
	else if( start_code == 0x000001B6 )
	{
		//parse_video_object_plane( out, d, len );
		return 2;
	}
	return 0;
}
static int mpeg4_process_frame( char *frame, int len, void *d )
{
	struct frame_info *out = (struct frame_info *)d;
	int flen, start, ret;


	for( start = 0; start < len; start += flen )
	{
		flen = find_next_code( frame + start, len - start );
		if( flen == 0 ) flen = len - start;
		if((ret = parse_mpeg4_frame( out, frame + start, flen )) > 0)
			return 1;
	}
	printf("not a valid frame\n");
	return -1;
}


void encode_video(int sig)
{

//	static int encode_video_cnt = 0;
	static int current_framerate;
	unsigned int blength;
 

//	fcap_frame_buff_t frame_sync;	

     	struct timeb tv;
     	AVFrame yuv_data;
	uint8_t *ptr;
 	

	if(stop_encode == 1)
		return;
	if(current_framerate != video_setting.framerate){
		current_framerate = video_setting.framerate;
		init_time(video_setting.framerate);
	}
    	/* Setup to capture the next frame */
	    if ((errno=ioctl(video_fd, VIDIOCMCAPTURE, &gb_buf)) < 0) 
	    {
	        if (errno == EAGAIN)
	            fprintf(stderr,"Cannot Sync\n");
	        else
	            perror("VIDIOCMCAPTURE");
	        return;
	    }
   


#ifdef NEW_VERSION
    	//printf("frame_num = %d gb_buffers.offsets[frame_num] =%d\n", frame_num, gb_buffers.offsets[frame_num]);
    	
    	while (ioctl(video_fd, VIDIOCSYNC, &frame_num) < 0 &&
           (errno == EAGAIN || errno == EINTR))
           printf("error\n");
    	
    	ptr = video_buf_virt + gb_buffers.offsets[frame_num];
    	//printf("gb_buf.frame=%d\n", gb_buf.frame);
    	frame_num = gb_buf.frame;

    
#else
    	while (ioctl(video_fd, VIDIOCSYNC, &frame_sync) < 0 &&
           (errno == EAGAIN || errno == EINTR));
    	ptr = (uint8_t *)frame_sync.mmapAddr;
#endif
		yuv_data.data[0] = (unsigned char *)(ptr);

	    	
	    	if(cap_height % 16 != 0)
	    		cap_height = 16 * ((cap_height / 16) + 1 );
	    			
	    	if(cap_width % 16 != 0)
	    		cap_width = 16 * ((cap_width / 16) + 1 );
	
	    	// UV    	
	    	yuv_data.data[1] = (unsigned char *) (ptr + (cap_width * cap_height));
	    	yuv_data.data[2] = (unsigned char *) (ptr + (cap_width * cap_height * 5 / 4));


	        		
		blength = xvid_encode(&video_setting, out_virt_buffer, (void *)&yuv_data);


		
	
		ftime(&tv);

		if(frame_count > video_setting.framerate + 1 && tv.time % 10 == 0 )
		{
			//printf("Time=%d, FPS=%d, V=%dKbps\n",(int)tv.time,(frame_count)/10,(V_bitrate/1250));
		
			V_bitrate = frame_count = 0;
			
		}

/*		if(!time_init)
		{
			tv_last.time = tv_init.time = tv.time;
			time_init = 1;
			longterm_frame_count = 1;
				
		}		
		if( tv.time - tv_last.time >= 1 && time_init == 1)
		{
			tv_last.time = tv.time;
			if((tv.time - tv_init.time) * video_setting.framerate > longterm_frame_count)
			{
				//printf("insert a frame\n");	
				insert_frame = 1;
				longterm_frame_count++;
				frame_count++;
			}
		}
*/	   	frame_count++;
	   	longterm_frame_count++;
	   	
	   	V_bitrate += blength;		
	   	/*if(blength > (video_setting.bit_rate * 400) /  video_setting.framerate )
	   	{
	   		printf("blength=%d\n", blength);
			return;
		}*/
		send_to_server(ctlfd, out_virt_buffer, blength);    
		  
//		if(frame_count % 15 == 0)    
		if(insert_frame)
		{
			insert_frame = 0;
			yuv_data.data[0] = 0;
			blength = xvid_encode(&video_setting, out_virt_buffer, (void *)&yuv_data);	
//			send_to_server( ctlfd, out_virt_buffer, blength );			
		}	
    	   	
}
//#define BUFSIZ 64
typedef struct msg_st{
	long int msg_type;
	char buf[64];
}MESSAGE;

void init_time( int framerate )
{ 
  struct itimerval value; 
  int ret;
//  int *framerate = (int*)data;

//++ Foster
/* 
	ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	if(ret != 0)
	{
		perror("thread pthread_setcancelstate failed\n");	
		
	}
	ret = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
	if(ret != 0)
	{
		perror("thread pthread_setcanceltype failed\n");
	}
*/
//-- Foster
  	value.it_value.tv_sec = 0; 
 
	if(framerate == 30)
	  	value.it_value.tv_usec = 900000 / framerate ; 
  	else if(framerate > 0)
  	  	value.it_value.tv_usec = 990000 / framerate ; 
  	else
  	{
  		value.it_value.tv_usec = 0;
  		printf("disable timer\n");
	} 
  	value.it_interval = value.it_value; 
  	/*       ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expiration. */
  	ret = setitimer(ITIMER_REAL,&value,NULL); 
	if(ret < 0)
	{
		printf("set timer error\n");
		return;
	}	

    return;	
} 


int main(int argc, char **argv)
{

     	char config_filename[128] = AV_CONFIGFILE;
     	char motion_filename[128] = MOTION_CONFIG_PATH;
     	int c, ret;    

#if 1

	signal(SIGTERM, external_exit);
	signal(SIGALRM, encode_video);

	  
	if((ctlfd=connect_to_server())<0) 
	    return -1;

    	for(;;) {
	        c = getopt(argc, argv, "h?f:m:");
	        if (c == -1)
	            break;
	        switch(c) {
	        case '?':
	        case 'h':
	            //show_help();
	            exit(1);
	        case 'f':
	            strcpy(config_filename, optarg);
	            break;
	        case 'm':
	            strcpy(motion_filename, optarg);

	            break;	            
	        default:
	            exit(2);
	        }
    	}
#endif    	

    //dout=fopen(dout_name,"wb");
    //printf("Use encoder output name %s\n",dout_name);
        	
    	//set the default value
		video_setting.qmax = 31;
		video_setting.qmin = 1;
		video_setting.quant = 0;
		video_setting.bit_rate = 512;
		video_setting.width = 640;
		video_setting.height = 480;
		video_setting.framerate = 15;
		video_setting.frame_rate_base = 1;
		video_setting.gop_size = 60;
		
#if 1
    	if (read_video_config(config_filename, &video_setting) < 0) {
        	fprintf(stderr, "Incorrect config file - video use the default value\n");

    	}
    	max_bitrate = initial_bitrate = video_setting.bit_rate;
		auto_bandwidth = 0;
    	
	if (read_motion_config(motion_filename) < 0) {
		fprintf(stderr, "Incorrect config file - motion use the default value\n");
	}
#endif
        video_running = 1;
          
#ifdef MAX_WIDTH_1280
   	out_virt_buffer = (unsigned char *) malloc(1280 * 1024 * 3/2);
#else    
   	out_virt_buffer = (unsigned char *) malloc(720 * 576 * 3/2);
#endif

	if((ret = v4l_init()) < 0)
		return -1;
	if((ret = mp4_init(video_setting)) < 0)
		return -1;			
	if((ret = enc_init(&video_setting)) < 0)
		return -1;	

	init_time(video_setting.framerate);
	stop_encode = 0;
//	fclose(dout);
	while(1)
	{
		select(0, NULL, NULL, NULL, NULL);  		
	}
	enc_close(&video_setting);
	free(out_virt_buffer);	

	close(video_fd);
	
	if(mdinfo)
	    free(mdinfo);
	return 0;
}



int fmpeg4_get_inter_quant_tbls(unsigned char *inter_qtbl)
{
    int item=0;
    unsigned char buf;
    unsigned char num;	
    unsigned char qin_name[30];
    FILE *qin;
    
    sprintf(qin_name,"/ffmpeg/inter_quant.txt");
    qin=fopen(qin_name,"r");
    if( !qin ) {
	printf("open %s fail\n",qin_name);
	return 0;
    }
	
    printf("Use inter quant tbl input name %s\n",qin_name);

    while( !feof(qin) ) {
    	
        if(fread(&buf, 1, sizeof(unsigned char), qin)<=0)
            break;

	    if ( (buf !=0x20) && (buf >=0x30) && (buf<=0x39) )
    	{
    		num = buf-0x30;
    		do {
    			if(fread(&buf, 1, sizeof(unsigned char), qin)<=0)
    			    break;
    			if ( buf != 0x20)
    				num = num*10 + (buf-0x30);
    		} while( buf != 0x20 ) ;
            
            		if((item>=0) && (item<64) ){		
    			inter_qtbl[item] = num;
    			item++;
            		} else  { 
                		printf("customer Quant Tbl number err\n");
            		}
    	}
    }	
  
    fclose(qin);	
    if ( item<63) {
	printf("the number of inter quant tbl's element err\n");	
	return 0;
    }
    return 1;	
}

int fmpeg4_get_intra_quant_tbls(unsigned char *intra_qtbl)
{
    int item=0;
    unsigned char buf;
    unsigned char num;	
    unsigned char qin_name[30];
    FILE *qin;
    
    sprintf(qin_name,"/ffmpeg/intra_quant.txt");
    qin=fopen(qin_name,"r");
    if( !qin ) {
	    printf("open %s fail\n",qin_name);
	    return 0;
    }
	
    printf("Use intra quant tbl input name %s\n",qin_name);
    while( !feof(qin) ) {
    	
        if(fread(&buf, 1, sizeof(unsigned char), qin)<=0)
            break;

    	if ( (buf !=0x20) && (buf >=0x30) && (buf<=0x39) )
    	{
    		num = buf-0x30;
    		do {
    			if(fread(&buf, 1, sizeof(unsigned char), qin)<=0)
    			    break;
    			if ( buf != 0x20)
    				num = num*10 + (buf-0x30);
    		} while( buf != 0x20 ) ;
            
            if((item>=0) && (item<64) ){		
    			intra_qtbl[item] = num;
        			item++;
            		} else  { 
                		printf("customer Quant Tbl number err\n");
            		}
    	}
    }	

    fclose(qin);	
    if ( item<63) {
	printf("the number of inter quant tbl's element err\n");	
	return 0;
    }
    return 1;	
}

⌨️ 快捷键说明

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