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
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
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
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
00072 #define NEMPTY 10
00073
00074 #define RBUFSIZE (PSIZE * NPACKET_R)
00075 #define MAXBLOCKS (300)
00076 #define CYCLE_FRAC 0xc00
00077
00078
#endif
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
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
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
00224 raw1394_set_bus_reset_handler(handle,
my_reset_handler);
00225
00226
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
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
00274
int nblocks[] = {250 , 300 };
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
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
00371
00372 ciph = (
struct ciphdr *)(ptr + 1);
00373
if (ciph->fmt !=
CIP_FMT_DVCR)
00374 errx(1,
"unknown format 0x%x", ciph->fmt);
00375 ptr = (u_int32_t *) (ciph + 1);
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
00382
00383
if (pkt->mode.stream.len <=
sizeof(
struct ciphdr)) {
00384
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
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
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
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
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
00450 k++;
00451
if (k %
frame_rate[system] == 0) {
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
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
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
00543