📄 main.c
字号:
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 + -