📄 fame.c
字号:
/* * fame.c * * Copyright (C) Vivien Chappelier - 2000-2001 * * This file is part of fame, a free MPEG encoder. * * fame is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * fame is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <stdio.h>#include <string.h>#include <getopt.h>#include <signal.h>#include <unistd.h>#include <fcntl.h>#include <pthread.h>#ifdef HAS_LAME#include <lame/lame.h>#endif#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <termio.h> /* for ioctl functions */struct termio ostate; /* saved tty state */struct termio nstate; /* values for editor mode */#include <fame.h>#include <netinet/in.h>#include <netdb.h>#include <sys/socket.h>#include <sys/param.h>#include <arpa/inet.h>#include "types.h"#include "dsp.h"#include "v4l.h"#define DEFAULT_BUFFER_SIZE 1024*1024#define CHUNK_SIZE 1024fuint32_t video_frame;fuint32_t audio_frame;fuint32_t sync_frame, start_frame, ev_frame, ea_frame;volatile fbool_t quit, pause_record;char *profile = "mpeg1";char *motion = "pmvfast";char video_device[MAXPATHLEN] = "/dev/video\0";pthread_t video_thread, audio_thread;pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER;fame_parameters_t fp = FAME_PARAMETERS_INITIALIZER;int buffer_size = DEFAULT_BUFFER_SIZE;int video_fd = 1;int audio_fd = 0;int audiobitrate = 64;static fbool_t init();static fbool_t cleanup();static void *audio_callback(void *args);static void *video_callback(void *args);static void break_handler(int signal);/* * parse command line */int parse(int argc, char *argv[]){ int index = -1; int c; /* options */#ifdef _GNU_SOURCE const struct option longopts[]={ {"picture",1,0,'p'}, /* picture size: widthxheight or CIF,SIF,QCIF */ {"coding",1,0,'c'}, /* coding sequence: for example "IBBPBBPBB" */ {"quality",1,0,'q'}, /* quality: percentage of video quality */ {"bitrate",1,0,'b'}, /* bitrate: in bits/s, K for kilo, M for mega */ {"audiorate",1,0,'u'},/* audiobitrate: in bits/s, K for kile, M for mega */ {"buffer",1,0,'B'}, /* buffer size: in bytes, K for kilo, M for mega */ {"alpha",1,0,'a'}, /* shape quality: percentage of shape accuracy */ {"search",1,0,'s'}, /* search range: motion estimation range */ {"fps",1,0,'f'}, /* framerate: fractional number of frames/sec */ {"refresh",1,0,'r'}, /* refresh: number of frames before a new sequence */ {"options",1,0,'o'}, /* options: intra_only, lossless_shape */ {"profile",1,0,'P'}, /* profile name: name of the profile to use */ {"motion",1,0,'M'}, /* motion: motion estimation algorithm */ {"device",1,0,'d'}, /* video device */ {"verbose",0,0,'v'}, /* verbose: when set, print messages */ {"help",0,0,'h'}, /* help: display help message */ {0,0,0,0} };#endif const char * shortopts = "p:c:d:q:b:B:a:s:f:r:o:P:M:u:vh";#ifdef _GNU_SOURCE while((c = getopt_long(argc,argv,shortopts,longopts,&index)) != -1)#else while((c = getopt(argc,argv,shortopts)) != -1)#endif { switch(c) { case 'p': /* picture size: widthxheight or CIF,SIF,QCIF,QSIF */ if(!strcmp("CIF", optarg)) { fp.width = 352; fp.height = 288; } else if(!strcmp("SIF", optarg)) { fp.width = 352; fp.height = 240; } else if(!strcmp("QCIF", optarg)) { fp.width = 176; fp.height = 144; } else if(strchr(optarg, 'x')) { fp.width = atoi(optarg); fp.height = atoi(strchr(optarg, 'x')+1); } else { return(index); } break; /* coding sequence: for example "IBBPBBPBB" */ case 'c': fp.coding = optarg; break; /* coding sequence: for example "IBBPBBPBB" */ case 'd': strcpy(video_device, optarg); break; /* quality percentage */ case 'q': fp.quality = atoi(optarg); break; /* bitrate: in bits/s, K for kilo, M for mega */ case 'b': fp.bitrate = atoi(optarg); if(optarg[strlen(optarg)-1] == 'K' || optarg[strlen(optarg)-1] == 'k') fp.bitrate *= 1024; if(optarg[strlen(optarg)-1] == 'M' || optarg[strlen(optarg)-1] == 'm') fp.bitrate *= 1024*1024; break; /* bitrate of audio stream */ case 'u': audiobitrate = atoi(optarg); if(optarg[strlen(optarg)-1] == 'K' || optarg[strlen(optarg)-1] == 'k') audiobitrate *= 1024; if(optarg[strlen(optarg)-1] == 'M' || optarg[strlen(optarg)-1] == 'm') audiobitrate *= 1024*1024; break; /* buffer size: in bytes, K for kilo, M for mega */ case 'B': buffer_size = atoi(optarg); if(optarg[strlen(optarg)-1] == 'K' || optarg[strlen(optarg)-1] == 'k') buffer_size *= 1024; if(optarg[strlen(optarg)-1] == 'M' || optarg[strlen(optarg)-1] == 'm') buffer_size *= 1024*1024; break; /* shape quality percentage */ case 'a': fp.shape_quality = atoi(optarg); break; /* search range: motion estimation range */ case 's': fp.search_range = atoi(optarg); break; /* framerate: fractional number of frames/sec */ case 'f': fp.frame_rate_num = atoi(optarg); if(strchr(optarg, '/') != NULL) fp.frame_rate_den = atoi(strchr(optarg, '/') + 1); else fp.frame_rate_den = 1; break; /* refresh: number of frames before a new sequence */ case 'r': fp.frames_per_sequence = atoi(optarg); break; /* profile name: name of the profile to use */ case 'P': profile = optarg; break; /* motion: motion estimation algorithm */ case 'M': motion = optarg; break; /* verbose: when set, print messages */ case 'v': fp.verbose = 1; break; /* help */ case 'h': return(-1); break; default: return(index); } } /* force at least one argument */ if(argc < optind+1) return(-1); /* output file */ if(argc >= optind+1) { /* use stdout */ if(!strncmp(argv[optind+0], "-", strlen("-"))) { video_fd = 1; } else /* use udp */ if(!strncmp(argv[optind+0], "udp://", strlen("udp://"))) { char * host; int port; int sock; port = 10000; host = argv[optind+0] + strlen("udp://"); if(strchr(host, ':') != NULL) { port = atoi(strchr(host, ':') + 1); *strchr(host, ':') = 0; } video_fd = udp_open(host, port); } else video_fd = open(argv[optind+0], O_WRONLY | O_CREAT | O_TRUNC, 0666); if(video_fd < 0) { char error[256]; sprintf(error, "Error opening %s for writing", argv[optind+0]); perror(error); exit(1); } } /* audio file */ if(argc >= optind+2) {#ifndef HAS_LAME fprintf(stderr, "Error, audio sound support not compiled\n"); exit(1);#endif /* use stdout */ if(!strncmp(argv[optind+0], "-", strlen("-"))) { video_fd = 1; } else /* use udp */ if(!strncmp(argv[optind+1], "udp://", strlen("udp://"))) { char * host; int port; int sock; port = 10001; host = argv[optind+1] + strlen("udp://"); if(strchr(host, ':') != NULL) { port = atoi(strchr(host, ':') + 1); *strchr(host, ':') = 0; } audio_fd = udp_open(host, port); } else audio_fd = open(argv[optind+1], O_WRONLY | O_CREAT | O_TRUNC, 0666); if(audio_fd < 0) { char error[256]; sprintf(error, "Error opening %s for writing", argv[optind+1]); perror(error); exit(1); } } return(0);}void usage(char const *name){ fprintf(stderr, "usage: %s options video [audio]\n", name); fprintf(stderr, "options are\n"); fprintf(stderr, "\t%s\t%s\n", "-p --picture", "picture size: widthxheight or CIF,SIF,QCIF"); fprintf(stderr, "\t%s\t%s\n", "-c --coding", "coding sequence: for example \"IPPPP\""); fprintf(stderr, "\t%s\t%s\n", "-d --device", "video device: for example \"/dev/video0\""); fprintf(stderr, "\t%s\t%s\n", "-q --quality", "quality: percentage of video quality"); fprintf(stderr, "\t%s\t%s\n", "-b --bitrate", "bitrate: video bitrate in bits/s [K kilo, M mega]"); fprintf(stderr, "\t%s\t%s\n", "-u --audiorate", "audiobitrate: mp3 bitrate in bits/s [K kilo, M mega]"); fprintf(stderr, "\t%s\t%s\n", "-B --buffer", "buffer size: in bytes [K kilo, M mega]"); fprintf(stderr, "\t%s\t%s\n", "-a --alpha", "shape quality: percentage of shape accuracy"); fprintf(stderr, "\t%s\t%s\n", "-s --search", "search range: motion estimation range"); fprintf(stderr, "\t%s\t%s\n", "-f --fps", "framerate: fractional number of frames/sec"); fprintf(stderr, "\t%s\t%s\n", "-r --refresh", "number of frames before a new sequence"); fprintf(stderr, "\t%s\t%s\n", "-P --profile", "profile: name of the profile to use"); fprintf(stderr, "\t%s\t%s\n", "-M --motion", "motion: motion estimation algorithm"); fprintf(stderr, "\t%s\t%s\n", "-v --verbose", "verbose: when set, print messages"); fprintf(stderr, "\t%s\t%s\n", "-h --help", "display this message");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -