00001
00002
00003
00004
00005
00006 #ifdef HAVE_CONFIG_H
00007 #include <config.h>
00008 #endif
00009
00010 #include <assert.h>
00011 #include <fcntl.h>
00012 #include <unistd.h>
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <signal.h>
00016 #include <pthread.h>
00017 #include <string.h>
00018
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <fcntl.h>
00022 #include <unistd.h>
00023
00024 #include "rtp_api.h"
00025 #include "rtp_highlevel.h"
00026
00027 #define tv2dbl(tv) ((tv).tv_sec + (tv).tv_usec / 1000000.0)
00028
00029 #define RAW_BUF_SIZE (10240)
00030
00031 enum { PAL_FORMAT, NTSC_FORMAT, AVI_DV1_FORMAT, AVI_DV2_FORMAT, QT_FORMAT, RAW_FORMAT, TEST_FORMAT, UNDEFINED };
00032
00033
00034 int g_buffer_underrun;
00035 volatile int g_reader_active;
00036 volatile int g_alldone;
00037 int g_filedone;
00038 char *g_dst_file_name;
00039 int g_frame_size;
00040
00041 int g_autosplit;
00042 int g_timestamp;
00043 int g_card;
00044 int g_channel;
00045 int g_file_format;
00046 int g_index_type;
00047 int g_frame_count;
00048 int g_frame_every;
00049 int g_frame_to_skip;
00050 int g_progress;
00051 int g_testmode;
00052
00053 #ifdef FREEBSD_5
00054 int device;
00055 #endif
00056
00057 pthread_mutex_t g_mutex;
00058 pthread_t g_thread;
00059
00060 char addr[20];
00061 int port = 12000;
00062
00063 context cid;
00064
00065 int dump_fd;
00066 int flags_dump = 0;
00067
00068 unsigned char ttl = 255;
00069 rtperror status;
00070
00071 struct evt_queue_elt {
00072 context cid;
00073 rtp_opaque_t event_opaque;
00074 double event_time;
00075 struct evt_queue_elt *next;
00076 };
00077
00078 static struct evt_queue_elt* evt_queue = NULL;
00079
00080 static void insert_in_evt_queue(struct evt_queue_elt *elt)
00081 {
00082 if (evt_queue == NULL || elt->event_time < evt_queue->event_time) {
00083 elt->next = evt_queue;
00084 evt_queue = elt;
00085 }
00086 else {
00087 struct evt_queue_elt *s = evt_queue;
00088 while (s != NULL) {
00089 if (s->next == NULL || elt->event_time < s->next->event_time) {
00090 elt->next = s->next;
00091 s->next = elt;
00092 break;
00093 }
00094 s = s->next;
00095 }
00096 }
00097 }
00098
00099 void RTPSchedule(context cid, rtp_opaque_t opaque, struct timeval *tp)
00100 {
00101 struct evt_queue_elt *elt;
00102
00103 elt = (struct evt_queue_elt *) malloc(sizeof(struct evt_queue_elt));
00104 if (elt == NULL)
00105 return;
00106
00107 elt->cid = cid;
00108 elt->event_opaque = opaque;
00109 elt->event_time = tv2dbl(*tp);
00110
00111 insert_in_evt_queue(elt);
00112
00113 return;
00114 }
00115
00116
00117 void getargs(int argc, char *argv[])
00118 {
00119 int i;
00120
00121 g_autosplit = 0;
00122 g_timestamp = 0;
00123 g_card = 0;
00124 g_channel = 63;
00125 g_frame_count = 100000;
00126 g_frame_every = 1;
00127 g_dst_file_name = NULL;
00128 g_progress = 0;
00129 g_testmode = 0;
00130
00131 for (i = 1; i < argc; ++i) {
00132 if (strcmp("--autosplit", argv[i]) == 0) {
00133 g_autosplit = 1;
00134 } else if ((strcmp("--format", argv[i]) == 0) && (i < argc)) {
00135 i++;
00136 if (strcmp("raw", argv[i]) == 0) {
00137 g_file_format = RAW_FORMAT;
00138 } else {
00139 exit(1);
00140 }
00141 } else if ((strcmp("--card", argv[i]) == 0) && (i < argc)) {
00142 i++;
00143 if (sscanf(argv[i], "%d", &g_card) != 1) {
00144 exit(1);
00145 }
00146 } else if ((strcmp("--channel", argv[i]) == 0) && (i < argc)) {
00147 i++;
00148 if (sscanf(argv[i], "%d", &g_channel) != 1) {
00149 exit(1);
00150 }
00151 } else if ((strcmp("--ip", argv[i]) == 0) && (i < argc)) {
00152 i++;
00153 strncpy(addr, argv[i], 20);
00154 } else if ((strcmp("--port", argv[i]) == 0) && (i < argc)) {
00155 i++;
00156 if (sscanf(argv[i], "%d", &port) != 1) {
00157 exit(1);
00158 }
00159 } else if ((strcmp("--dump", argv[i]) == 0) && (i < argc)) {
00160 flags_dump = 1;
00161 } else if (strcmp("--help", argv[i]) == 0) {
00162 printf("Usage: %s [options]\n", argv[0]);
00163 printf("\nOptions:\n\n");
00164 printf(" --autosplit start a new file when the frame count is exceeded, a new\n");
00165 printf(" recording is detected, or file becomes too big.\n");
00166 printf(" Note: will loop forever -- you need to press ctrl-c\n");
00167 printf(" at the end.\n");
00168 printf(" Default is autosplit when file is slightly less than\n");
00169 printf(" 1 GByte.\n");
00170 printf(" --format raw save only the raw DV information.\n");
00171 printf(" --dump dump dv data to file.\n");
00172 printf(" --card number card number (default %d).\n", g_card);
00173 printf(" --channel number iso channel number for listening (default %d).\n", g_channel);
00174 printf(" instead from camcorder.\n");
00175 printf(" --ip dest. ip address.\n");
00176 printf(" --port dest. ip port.\n");
00177 exit(0);
00178 } else {
00179 exit(1);
00180 }
00181 }
00182 if (addr == NULL) {
00183 exit(1);
00184 }
00185 }
00186
00187 #ifdef LINUX
00188 extern int capture_raw_linux();
00189 #endif
00190
00191 #ifdef FREEBSD_5
00192 extern int capture_raw_freebsd(int d, char ich);
00193 #endif
00194
00195 void signal_handler(int sig)
00196 {
00197
00198
00199 signal(SIGINT, SIG_IGN);
00200
00201
00202
00203 g_reader_active = 0;
00204 g_alldone = 1;
00205
00206 #ifdef FREEBSD_5
00207 close(device);
00208 #endif
00209
00210 status = RTPCloseConnection(cid, "Goodbye!");
00211 if (status != RTP_OK){
00212 printf("RTPCloseConnection: %s\n", RTPStrError(status));
00213 }
00214 status = RTPDestroy(cid);
00215 if (status != RTP_OK){
00216 printf("RTPDestroy: %s\n", RTPStrError(status));
00217 }
00218
00219 }
00220
00221
00222 int main(int argc, char *argv[])
00223 {
00224 #ifdef FREEBSD_5
00225 char devname[] = "/dev/fw0";
00226 #endif
00227
00228 getargs(argc, argv);
00229
00230 signal(SIGINT, signal_handler);
00231
00232 printf("Using host %s/%d\n",addr, port);
00233
00234 status = RTPCreate(&cid);
00235 if (status != RTP_OK){
00236 fprintf(stderr, "RTPCreate: %s\n", RTPStrError(status));
00237 }
00238
00239 status = RTPSessionAddSendAddr(cid, addr, port, ttl);
00240 if (status != RTP_OK){
00241 printf("RTPSessionAddSendAddr: %s\n", RTPStrError(status));
00242 }
00243
00244 status = RTPSessionSetReceiveAddr(cid, addr, port);
00245 if (status != RTP_OK){
00246 printf("RTPSessionSetReceiveAddr: %s\n", RTPStrError(status));
00247 }
00248
00249 status = RTPOpenConnection(cid);
00250 if (status != RTP_OK){
00251 printf("RTPOpenConnection: %s\n", RTPStrError(status));
00252 }
00253
00254 if (flags_dump) {
00255 #ifdef __USE_LARGEFILES64
00256 dump_fd = open("dump.dv", O_RDWR | O_CREAT | O_LARGEFILE, 00644);
00257 #else
00258 dump_fd = open("dump.dv", O_RDWR | O_CREAT, 00644);
00259 #endif
00260
00261 if (dump_fd < 0) {
00262 perror("open dump.dv");
00263 flags_dump = 0;
00264 }
00265 }
00266
00267 #ifdef LINUX
00268 capture_raw_linux();
00269 #endif
00270
00271 #ifdef FREEBSD_5
00272 device = open(devname, O_RDWR);
00273 if (device < 0) {
00274 perror("open");
00275
00276 exit(1);
00277 }
00278
00279 capture_raw_freebsd(device, (1<<6) | 63);
00280 #endif
00281
00282 return 0;
00283 }
00284