Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

xdvshow-ieee1394.c

Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H 00002 #include <config.h> 00003 #endif 00004 00005 #include <assert.h> 00006 #include <fcntl.h> 00007 #include <unistd.h> 00008 #include <stdio.h> 00009 #include <stdlib.h> 00010 #include <signal.h> 00011 #include <pthread.h> 00012 #include <string.h> 00013 #include <errno.h> 00014 00015 #include <semaphore.h> 00016 00017 #if (LINUX && HAVE_LIBRAW1394) 00018 #include <libraw1394/raw1394.h> 00019 #include <libraw1394/csr.h> 00020 #endif /* LINUX && HAVE_LIBRAW1394 */ 00021 00022 #ifdef FREEBSD_5 00023 #include <sys/ioctl.h> 00024 #include <sys/types.h> 00025 #include <sys/uio.h> 00026 #include <err.h> 00027 00028 #include <dev/firewire/firewire.h> 00029 #include "iec68113.h" 00030 #endif /* FREEBSD_5 */ 00031 00032 #include "xdvshow-shm.h" 00033 #include "xdvshow-flags.h" 00034 #include "xdvshow-ieee1394.h" 00035 #include "xdvshow-const.h" 00036 #include "xdvshow-defs.h" 00037 00038 #if (LINUX && HAVE_LIBRAW1394) 00039 00040 #define RAW_BUF_SIZE (10240) 00041 00042 int g_card = 0; 00043 int g_channel = 63; 00044 int g_frame_count = 100000; 00045 volatile int g_alldone = 0; 00046 volatile int g_reader_active; 00047 00048 unsigned char *g_frame; 00049 00050 raw1394handle_t open_1394_driver(int channel, iso_handler_t handler); 00051 void close_1394_driver(int channel, raw1394handle_t handle); 00052 00053 #endif /* LINUX && HAVE_LIBRAW1394 */ 00054 00055 #ifdef FREEBSD_5 00056 00057 char *system_name[] = {"NTSC", "PAL"}; 00058 int frame_rate[] = {30, 25}; 00059 00060 #define PSIZE 512 00061 #define DSIZE 480 00062 #define NCHUNK 8 00063 00064 #define NPACKET_R 256 00065 #define NPACKET_T 255 00066 00067 #define NPKT 50 00068 #define NVEC 50 00069 #define BLOCKSIZE 80 00070 00071 #define TNBUF 100 /* XXX too large value causes block noise */ 00072 #define NEMPTY 10 /* depends on TNBUF */ 00073 00074 #define RBUFSIZE (PSIZE * NPACKET_R) 00075 #define MAXBLOCKS (300) 00076 #define CYCLE_FRAC 0xc00 00077 00078 #endif /* FREEBSD_5 */ 00079 00080 00081 #if (LINUX && HAVE_LIBRAW1394) 00082 00083 int raw_iso_handler(raw1394handle_t handle, int channel, size_t length, 00084 quadlet_t *data) 00085 { 00086 if (length < RAW_BUF_SIZE) { 00087 *(int*)g_frame = length; 00088 memcpy(g_frame + 4, data, length); 00089 } 00090 return 0; 00091 } 00092 00093 void * 00094 xdvshow_capture_raw(void *data) 00095 { 00096 int frames_read; 00097 int length; 00098 raw1394handle_t handle; 00099 int found_first_frame; 00100 int skipped = 0; 00101 00102 int offset = 0; 00103 int ret; 00104 00105 u_char *dvdata; 00106 u_char *audio_dvdata; 00107 00108 #ifdef DEBUG 00109 int sem_value = 0; 00110 int iDebugSemVal; 00111 #endif /* DEBUG */ 00112 00113 ret = _xdvshow_alloc_shm(); 00114 if (ret < 0) { 00115 return((void *)1); 00116 } 00117 00118 ret = _xdvshow_attach_shm(); 00119 00120 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00121 audio_dvdata = _xdvshow_shm.audio_shm_frame->frame_buf->data; 00122 00123 g_frame = (unsigned char*)malloc(RAW_BUF_SIZE); 00124 00125 handle = open_1394_driver(g_channel, raw_iso_handler); 00126 00127 frames_read = 0; 00128 found_first_frame = 0; 00129 00130 printf("raw1394 - start capture\n"); 00131 while (!g_alldone) { 00132 raw1394_loop_iterate(handle); 00133 length = *(int*)g_frame; 00134 if (length >= 492) { 00135 if (!found_first_frame) { 00136 if (g_frame[16] == 0x1f && g_frame[17] == 0x07) 00137 found_first_frame = 1; 00138 else skipped++; 00139 } 00140 if (skipped > 500) { 00141 printf("skipped too many without finding frame\n"); 00142 break; 00143 } 00144 if (found_first_frame) { 00145 if (g_frame[16] == 0x1f && g_frame[17] == 0x07) 00146 frames_read++; 00147 if (frames_read > g_frame_count) 00148 break; 00149 if (offset < 144000){ 00150 memcpy(&dvdata[offset], (g_frame + 16), 480); 00151 offset += 480; 00152 } 00153 if (offset == 144000){ 00154 offset = 0; 00155 00156 _xdvshow_shm.shm_frame->frame_buf->lock = DVFRAME_DATA_READY; 00157 00158 #ifdef DEBUG 00159 DPRINT("RECEIVED frame no. %d\n", sem_value++); 00160 if(sem_getvalue(&video_ready, &iDebugSemVal)) { 00161 perror("Unable to get value of video_ready semaphore!"); 00162 exit(EXIT_FAILURE); 00163 } 00164 DPRINT("semaphore video_ready value: %d\n", iDebugSemVal); 00165 00166 if(sem_getvalue(&video_empty, &iDebugSemVal)) { 00167 perror("Unable to get value of video_empty semaphore!"); 00168 exit(EXIT_FAILURE); 00169 } 00170 DPRINT("semaphore video_empty value: %d\n", iDebugSemVal); 00171 #endif /* DEBUG */ 00172 00173 if (sem_post(&video_ready) < 0) 00174 perror("sem_post"); 00175 ts_sem_wait(&video_empty); 00176 00177 _xdvshow_shm.shm_frame = _xdvshow_shm.shm_frame->next; 00178 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00179 } 00180 } 00181 } 00182 } 00183 close_1394_driver(g_channel, handle); 00184 free(g_frame); 00185 00186 return 0; 00187 } 00188 00189 00190 int my_reset_handler(raw1394handle_t handle, unsigned int generation) 00191 { 00192 static int i = 0; 00193 00194 printf("reset %d\n", i++); 00195 if (i == 100) 00196 g_reader_active = 0; 00197 return 0; 00198 } 00199 00200 00201 raw1394handle_t open_1394_driver(int channel, iso_handler_t handler) 00202 { 00203 int numcards; 00204 struct raw1394_portinfo g_pinf[16]; 00205 raw1394handle_t handle; 00206 00207 if (!(handle = raw1394_new_handle())) { 00208 perror("raw1394 - couldn't get handle"); 00209 printf("This error usually means that the ieee1394 driver is not ready\n"); 00210 exit( -1); 00211 } 00212 00213 if ((numcards = raw1394_get_port_info(handle, g_pinf, 16)) < 0) { 00214 perror("raw1394 - couldn't get card info"); 00215 exit( -1); 00216 } 00217 00218 if (raw1394_set_port(handle, g_card) < 0) { 00219 perror("raw1394 - couldn't set port"); 00220 exit( -1); 00221 } 00222 raw1394_set_iso_handler(handle, g_channel, handler); 00223 /* raw1394_set_tag_handler(handle, my_tag_handler); */ 00224 raw1394_set_bus_reset_handler(handle, my_reset_handler); 00225 00226 /* Starting iso receive */ 00227 00228 if (raw1394_start_iso_rcv(handle, channel) < 0) { 00229 perror("raw1394 - couldn't start iso receive"); 00230 exit( -1); 00231 } 00232 printf("raw1394 - driver opened\n"); 00233 return handle; 00234 } 00235 00241 void close_1394_driver(int channel, raw1394handle_t handle) 00242 { 00243 raw1394_stop_iso_rcv(handle, channel); 00244 raw1394_destroy_handle(handle); 00245 } 00246 00247 #endif /* LINUX && HAVE_LIBRAW1394 */ 00248 00249 #ifdef FREEBSD_5 00250 00257 void * 00258 xdvshow_capture_raw(void *data) 00259 { 00260 char devname[] = "/dev/fw0"; 00261 int fd; 00262 00263 struct fw_isochreq isoreq; 00264 struct fw_isobufreq bufreq; 00265 struct dvdbc *dv; 00266 struct ciphdr *ciph; 00267 struct fw_pkt *pkt; 00268 char *pad, *buf; 00269 u_int32_t *ptr; 00270 int len, tlen, k, m, vec, nb, system = -1 ; 00271 #if FIX_FRAME 00272 int npad; 00273 #endif /* FIX_FRAME */ 00274 int nblocks[] = {250 /* NTSC */, 300 /* PAL */}; 00275 struct iovec wbuf[NPACKET_R]; 00276 00277 int iovec_iter; 00278 00279 int offset = 0; 00280 int ret; 00281 00282 u_char *dvdata; 00283 u_char *audio_dvdata; 00284 00285 #ifdef DEBUG 00286 int sem_value = 0; 00287 int iDebugSemVal; 00288 #endif /* DEBUG */ 00289 00290 #if 0 00291 int mode; 00292 #endif 00293 00294 fd = open(devname, O_RDWR); 00295 if (fd < 0) 00296 err(1, "open"); 00297 00298 buf = (char *)malloc(RBUFSIZE); 00299 pad = (char *)malloc(DSIZE*MAXBLOCKS); 00300 00301 memset(pad, 0xff, DSIZE*MAXBLOCKS); 00302 bzero(wbuf, sizeof(wbuf)); 00303 00304 00305 bufreq.rx.nchunk = NCHUNK; 00306 bufreq.rx.npacket = NPACKET_R; 00307 bufreq.rx.psize = PSIZE; 00308 bufreq.tx.nchunk = 0; 00309 bufreq.tx.npacket = 0; 00310 bufreq.tx.psize = 0; 00311 if (ioctl(fd, FW_SSTBUF, &bufreq) < 0) { 00312 err(1, "%s", "ioctl"); 00313 } 00314 00315 isoreq.ch = ((1<<6) | 63) & 0x3f; 00316 isoreq.tag = (((1<<6) | 63) >> 6) & 3; 00317 00318 if( ioctl(fd, FW_SRSTREAM, &isoreq) < 0) 00319 err(1, "%s", "ioctl"); 00320 00321 k = m = 0; 00322 00323 ret = _xdvshow_alloc_shm(); 00324 if (ret < 0) { 00325 return((void *)1); 00326 } 00327 00328 ret = _xdvshow_attach_shm(); 00329 00330 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00331 audio_dvdata = _xdvshow_shm.audio_shm_frame->frame_buf->data; 00332 00333 while (1) { 00334 #if 0 00335 tlen = 0; 00336 while ((len = read(d, buf + tlen, PSIZE)) > 0) { 00337 if (len < 0) { 00338 if (errno == EAGAIN) { 00339 fprintf(stderr, "(EAGAIN)\n"); 00340 fflush(stderr); 00341 if (len <= 0) 00342 continue; 00343 } else 00344 err(1, "read failed"); 00345 } 00346 tlen += len; 00347 if ((RBUFSIZE - tlen) < PSIZE) 00348 break; 00349 }; 00350 #else 00351 tlen = len = read(fd, buf, RBUFSIZE); 00352 if (len < 0) { 00353 if (errno == EAGAIN) { 00354 fprintf(stderr, "(EAGAIN)\n"); 00355 fflush(stderr); 00356 if (len <= 0) 00357 continue; 00358 } else 00359 err(1, "read failed"); 00360 } 00361 #endif 00362 00363 vec = 0; 00364 ptr = (u_int32_t *) buf; 00365 again: 00366 pkt = (struct fw_pkt *) ptr; 00367 00368 #if DEBUG 00369 DPRINT("%08x %08x %08x %08x\n", htonl(ptr[0]), htonl(ptr[1]), htonl(ptr[2]), htonl(ptr[3])); 00370 #endif /* DEBUG */ 00371 00372 ciph = (struct ciphdr *)(ptr + 1); /* skip iso header */ 00373 if (ciph->fmt != CIP_FMT_DVCR) 00374 errx(1, "unknown format 0x%x", ciph->fmt); 00375 ptr = (u_int32_t *) (ciph + 1); /* skip cip header */ 00376 00377 #if DEBUG 00378 if (ciph->fdf.dv.cyc != 0xffff && k == 0) { 00379 DPRINT("0x%04x\n", ntohs(ciph->fdf.dv.cyc)); 00380 } 00381 #endif /* DEBUG */ 00382 00383 if (pkt->mode.stream.len <= sizeof(struct ciphdr)) { 00384 /* no payload */ 00385 goto next; 00386 } 00387 00388 for (dv = (struct dvdbc *)ptr; (char *)dv < (char *)(ptr + ciph->len); dv+=6) { 00389 #if DEBUG 00390 DPRINT("(%d,%d) ", dv->sct, dv->dseq); 00391 #endif /* DEBUG */ 00392 if (dv->sct == DV_SCT_HEADER && dv->dseq == 0) { 00393 if (system < 0) { 00394 system = ciph->fdf.dv.fs; 00395 printf("%s\n", system_name[system]); 00396 } 00397 00398 /* Fix DSF bit */ 00399 if (system == 1 && (dv->payload[0] & DV_DSF_12) == 0) 00400 dv->payload[0] |= DV_DSF_12; 00401 nb = nblocks[system]; 00402 fprintf(stderr, "%d", k%10); 00403 00404 #if FIX_FRAME 00405 if (m > 0 && m != nb) { 00406 /* padding bad frame */ 00407 npad = ((nb - m) % nb); 00408 if (npad < 0) 00409 npad += nb; 00410 printf("(%d blocks padded)", npad); 00411 npad *= DSIZE; 00412 wbuf[vec].iov_base = pad; 00413 wbuf[vec++].iov_len = npad; 00414 00415 if (vec >= NPACKET_R) { 00416 memcpy(&dvdata, pad, npad * BLOCKSIZE); 00417 offset += npad * BLOCKSIZE; 00418 00419 vec = 0; 00420 00421 if (offset == 144000) { 00422 offset = 0; 00423 00424 _xdvshow_shm.shm_frame->frame_buf->lock = DVFRAME_DATA_READY; 00425 00426 #ifdef DEBUG 00427 DPRINT("READ frame no. %d\n", sem_value++); 00428 if(sem_getvalue(&video_ready, &iDebugSemVal)) { 00429 perror("Unable to get value of video_ready semaphore!"); 00430 exit(EXIT_FAILURE); 00431 } 00432 DPRINT("(with FIX_FRAME) semaphore video_ready value: %d\n", iDebugSemVal); 00433 00434 if(sem_getvalue(&video_empty, &iDebugSemVal)) { 00435 perror("Unable to get value of video_empty semaphore!"); 00436 exit(EXIT_FAILURE); 00437 } 00438 DPRINT("(with FIX_FRAME) semaphore video_empty value: %d\n", iDebugSemVal); 00439 #endif /* DEBUG */ 00440 00441 sem_post(&video_ready); 00442 ts_sem_wait(&video_empty); 00443 00444 _xdvshow_shm.shm_frame = _xdvshow_shm.shm_frame->next; 00445 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00446 } 00447 } 00448 } 00449 #endif /* FIX_FRAME */ 00450 k++; 00451 if (k % frame_rate[system] == 0) { /* every second */ 00452 printf("\n"); 00453 fflush(stdout); 00454 } 00455 m = 0; 00456 } 00457 00458 m++; 00459 wbuf[vec].iov_base = (char *) dv; 00460 wbuf[vec++].iov_len = DSIZE; 00461 00462 if (vec >= NPACKET_R) { 00463 for(iovec_iter = 0; iovec_iter < vec; iovec_iter++) { 00464 memcpy(&dvdata, wbuf[iovec_iter].iov_base, wbuf[iovec_iter].iov_len); 00465 offset += wbuf[iovec_iter].iov_len; 00466 } 00467 00468 vec = 0; 00469 00470 if (offset == 144000) { 00471 offset = 0; 00472 00473 _xdvshow_shm.shm_frame->frame_buf->lock = DVFRAME_DATA_READY; 00474 00475 #ifdef DEBUG 00476 DPRINT("READ frame no. %d\n", sem_value++); 00477 if(sem_getvalue(&video_ready, &iDebugSemVal)) { 00478 perror("Unable to get value of video_ready semaphore!"); 00479 exit(EXIT_FAILURE); 00480 } 00481 DPRINT("semaphore video_ready value: %d\n", iDebugSemVal); 00482 00483 if(sem_getvalue(&video_empty, &iDebugSemVal)) { 00484 perror("Unable to get value of video_empty semaphore!"); 00485 exit(EXIT_FAILURE); 00486 } 00487 DPRINT("semaphore video_empty value: %d\n", iDebugSemVal); 00488 #endif /* DEBUG */ 00489 00490 sem_post(&video_ready); 00491 ts_sem_wait(&video_empty); 00492 00493 _xdvshow_shm.shm_frame = _xdvshow_shm.shm_frame->next; 00494 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00495 } 00496 } 00497 00498 } 00499 ptr = (u_int32_t *)dv; 00500 next: 00501 if ((char *)ptr < buf + tlen) { 00502 goto again; 00503 } 00504 00505 if (vec > 0) { 00506 for(iovec_iter = 0; iovec_iter < vec + 1; iovec_iter++) { 00507 memcpy(&dvdata, wbuf[iovec_iter].iov_base, wbuf[iovec_iter].iov_len); 00508 offset += wbuf[iovec_iter].iov_len; 00509 } 00510 if (offset == 144000) { 00511 offset = 0; 00512 00513 _xdvshow_shm.shm_frame->frame_buf->lock = DVFRAME_DATA_READY; 00514 00515 #ifdef DEBUG 00516 DPRINT("READ frame no. %d\n", sem_value++); 00517 if(sem_getvalue(&video_ready, &iDebugSemVal)) { 00518 perror("Unable to get value of video_ready semaphore!"); 00519 exit(EXIT_FAILURE); 00520 } 00521 DPRINT("semaphore video_ready value: %d\n", iDebugSemVal); 00522 00523 if(sem_getvalue(&video_empty, &iDebugSemVal)) { 00524 perror("Unable to get value of video_empty semaphore!"); 00525 exit(EXIT_FAILURE); 00526 } 00527 DPRINT("semaphore video_empty value: %d\n", iDebugSemVal); 00528 #endif /* DEBUG */ 00529 00530 sem_post(&video_ready); 00531 ts_sem_wait(&video_empty); 00532 00533 _xdvshow_shm.shm_frame = _xdvshow_shm.shm_frame->next; 00534 dvdata = _xdvshow_shm.shm_frame->frame_buf->data; 00535 } 00536 } 00537 } 00538 printf("\n"); 00539 return NULL; 00540 00541 } 00542 #endif /* FREEBSD_5 */ 00543

Generated on Wed Nov 3 19:19:02 2004 for xdvshow by doxygen 1.3.7