From 2ad690c70836b19ec6309c26ef569710f5ff6420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Tue, 4 Dec 2001 21:48:56 +0000 Subject: [PATCH] Add the ability to write VCD/SVCD disc's. It is still nessesary to supply the tracks as individual files, burncd can't read .cue files yet, but now the infrastructure to do it is present we just need a .cue file parser (hint hint)... --- usr.sbin/burncd/burncd.8 | 8 +++ usr.sbin/burncd/burncd.c | 132 ++++++++++++++++++++++----------------- 2 files changed, 82 insertions(+), 58 deletions(-) diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8 index 1729e6d18ee1..5c6b1f0f4675 100644 --- a/usr.sbin/burncd/burncd.8 +++ b/usr.sbin/burncd/burncd.8 @@ -58,6 +58,8 @@ set the device to use for the burning process. read a list of image files from filename. .It Fl m close disk in multisession mode (otherwise disk is closed as singlesession). +.It Fl n +dont write gaps between data tracks in DAO mode. .It Fl p use preemphasis on audio tracks. .It Fl q @@ -115,6 +117,12 @@ on the command line. .It Cm XAmode1 Set the write mode to produce data (XAmode1) tracks for the following image files on the command line. +.It Cm XAmode2 +Set the write mode to produce data (XAmode2) tracks for the following image +files on the command line. +.It Cm vcd +Set the write mode to produce VCD/SVCD tracks for the following image files +on the command line. This automagically sets DAO and nogap mode. .It Ar file All other arguments are treated as filenames of images to write to the media, or in case the diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c index 9a68f6ba1110..05dc7f0d856d 100644 --- a/usr.sbin/burncd/burncd.c +++ b/usr.sbin/burncd/burncd.c @@ -44,21 +44,20 @@ #define BLOCKS 16 - struct track_info { int file; char *file_name; int file_size; int block_size; int block_type; + int pregap; int addr; - int gap; }; static struct track_info tracks[100]; static int fd, quiet, verbose, saved_block_size, notracks; -void add_track(char *, int, int); -void do_DAO(int); +void add_track(char *, int, int, int); +void do_DAO(int, int); void do_TAO(int, int); int write_file(struct track_info *); int roundup_blocks(struct track_info *); @@ -71,11 +70,11 @@ main(int argc, char **argv) { int ch, arg, addr; int dao = 0, eject = 0, fixate = 0, list = 0, multi = 0, preemp = 0; - int speed = 4, test_write = 0; + int nogap = 0, speed = 4, test_write = 0; int block_size = 0, block_type = 0, cdopen = 0; char *devname = "/dev/acd0c"; - while ((ch = getopt(argc, argv, "def:lmpqs:tv")) != -1) { + while ((ch = getopt(argc, argv, "def:lmnpqs:tv")) != -1) { switch (ch) { case 'd': dao = 1; @@ -97,6 +96,10 @@ main(int argc, char **argv) multi = 1; break; + case 'n': + nogap = 1; + break; + case 'p': preemp = 1; break; @@ -141,11 +144,11 @@ main(int argc, char **argv) err_set_exit(cleanup); for (arg = 0; arg < argc; arg++) { - if (!strcmp(argv[arg], "fixate")) { + if (!strcasecmp(argv[arg], "fixate")) { fixate = 1; break; } - if (!strcmp(argv[arg], "msinfo")) { + if (!strcasecmp(argv[arg], "msinfo")) { struct ioc_read_toc_single_entry entry; bzero(&entry, sizeof(struct ioc_read_toc_single_entry)); @@ -159,10 +162,10 @@ main(int argc, char **argv) break; } - if (!strcmp(argv[arg], "erase") || !strcmp(argv[arg], "blank")){ + if (!strcasecmp(argv[arg], "erase") || !strcasecmp(argv[arg], "blank")){ int error, blank, percent; - if (!strcmp(argv[arg], "erase")) + if (!strcasecmp(argv[arg], "erase")) blank = CDR_B_ALL; else blank = CDR_B_MIN; @@ -187,31 +190,38 @@ main(int argc, char **argv) printf("\n"); continue; } - if (!strcmp(argv[arg], "audio") || !strcmp(argv[arg], "raw")) { + if (!strcasecmp(argv[arg], "audio") || !strcasecmp(argv[arg], "raw")) { block_type = CDR_DB_RAW; block_size = 2352; continue; } - if (!strcmp(argv[arg], "data") || !strcmp(argv[arg], "mode1")) { + if (!strcasecmp(argv[arg], "data") || !strcasecmp(argv[arg], "mode1")) { block_type = CDR_DB_ROM_MODE1; block_size = 2048; continue; } - if (!strcmp(argv[arg], "mode2")) { + if (!strcasecmp(argv[arg], "mode2")) { block_type = CDR_DB_ROM_MODE2; block_size = 2336; continue; } - if (!strcmp(argv[arg], "XAmode1")) { + if (!strcasecmp(argv[arg], "xamode1")) { block_type = CDR_DB_XA_MODE1; block_size = 2048; continue; } - if (!strcmp(argv[arg], "XAmode2")) { + if (!strcasecmp(argv[arg], "xamode2")) { block_type = CDR_DB_XA_MODE2_F2; block_size = 2324; continue; } + if (!strcasecmp(argv[arg], "vcd")) { + block_type = CDR_DB_XA_MODE2_F2; + block_size = 2352; + dao = 1; + nogap = 1; + continue; + } if (!block_size) err(EX_NOINPUT, "no data format selected"); if (list) { @@ -226,7 +236,7 @@ main(int argc, char **argv) continue; if ((eol = strchr(file_buf, '\n'))) *eol = NULL; - add_track(file_buf, block_size, block_type); + add_track(file_buf, block_size, block_type, nogap); } if (feof(fp)) fclose(fp); @@ -234,7 +244,7 @@ main(int argc, char **argv) err(EX_IOERR, "fgets(%s)", file_buf); } else - add_track(argv[arg], block_size, block_type); + add_track(argv[arg], block_size, block_type, nogap); } if (notracks) { if (ioctl(fd, CDIOCSTART, 0) < 0) @@ -245,7 +255,7 @@ main(int argc, char **argv) cdopen = 1; } if (dao) - do_DAO(test_write); + do_DAO(test_write, multi); else do_TAO(test_write, preemp); } @@ -269,7 +279,7 @@ main(int argc, char **argv) } void -add_track(char *name, int block_size, int block_type) +add_track(char *name, int block_size, int block_type, int nogap) { struct stat stat; int file; @@ -292,6 +302,16 @@ add_track(char *name, int block_size, int block_type) tracks[notracks].file_size = stat.st_size; tracks[notracks].block_size = block_size; tracks[notracks].block_type = block_type; + + if (nogap && notracks) + tracks[notracks].pregap = 0; + else { + if (tracks[notracks - (notracks > 0)].block_type == block_type) + tracks[notracks].pregap = 150; + else + tracks[notracks].pregap = 255; + } + if (verbose) { int pad = 0; @@ -308,12 +328,12 @@ add_track(char *name, int block_size, int block_type) } void -do_DAO(int test_write) +do_DAO(int test_write, int multi) { struct cdr_cuesheet sheet; struct cdr_cue_entry cue[100]; + int format = CDR_SESS_CDROM; int addr, i, j = 0; - int last_type; int bt2ctl[16] = { 0x0, -1, -1, -1, -1, -1, -1, -1, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, -1, -1 }; @@ -330,27 +350,16 @@ do_DAO(int test_write) (bt2df[tracks[0].block_type] & 0xf0) | (tracks[0].block_type < 8 ? 0x01 : 0x04), 0x00, addr); - last_type = tracks[0].block_type; - for (i = 0; i < notracks; i++) { if (bt2ctl[tracks[i].block_type] < 0 || bt2df[tracks[i].block_type] < 0) err(EX_IOERR, "track type not supported in DAO mode"); - if (tracks[i].block_type == last_type) - tracks[i].gap = 150; - else - tracks[i].gap = 255; - last_type = tracks[i].block_type; + if (tracks[i].block_type >= CDR_DB_XA_MODE1) + format = CDR_SESS_CDROM_XA; - if (i == 0) { /* gap uses no data */ - cue_ent(&cue[j++], bt2ctl[tracks[i].block_type], - 0x01, i+1, 0x0, - (bt2df[tracks[i].block_type] & 0xf0) | - (tracks[i].block_type < 8 ? 0x01 : 0x04), - 0x00, addr); - - addr += tracks[i].gap; + if (i == 0) { + addr += tracks[i].pregap; tracks[i].addr = addr; cue_ent(&cue[j++], bt2ctl[tracks[i].block_type], @@ -359,31 +368,33 @@ do_DAO(int test_write) } else { - if (tracks[i].block_type > 0x7) { - cue_ent(&cue[j++],bt2ctl[tracks[i].block_type], - 0x01, i+1, 0x0, - (bt2df[tracks[i].block_type] & 0xf0) | - (tracks[i].block_type < 8 ? 0x01 :0x04), - 0x00, addr); + if (tracks[i].pregap) { + if (tracks[i].block_type > 0x7) { + cue_ent(&cue[j++],bt2ctl[tracks[i].block_type], + 0x01, i+1, 0x0, + (bt2df[tracks[i].block_type] & 0xf0) | + (tracks[i].block_type < 8 ? 0x01 :0x04), + 0x00, addr); + } + else + cue_ent(&cue[j++],bt2ctl[tracks[i].block_type], + 0x01, i+1, 0x0, + bt2df[tracks[i].block_type], + 0x00, addr); } - else - cue_ent(&cue[j++],bt2ctl[tracks[i].block_type], - 0x01, i+1, 0x0, - bt2df[tracks[i].block_type], - 0x00, addr); - tracks[i].addr = tracks[i - 1].addr + roundup_blocks(&tracks[i - 1]); cue_ent(&cue[j++], bt2ctl[tracks[i].block_type], 0x01, i+1, 0x1, bt2df[tracks[i].block_type], - 0x00, addr + tracks[i].gap); + 0x00, addr + tracks[i].pregap); if (tracks[i].block_type > 0x7) - addr += tracks[i].gap; + addr += tracks[i].pregap; } addr += roundup_blocks(&tracks[i]); } + cue_ent(&cue[j++], bt2ctl[tracks[i - 1].block_type], 0x01, 0xaa, 0x01, (bt2df[tracks[i - 1].block_type] & 0xf0) | (tracks[i - 1].block_type < 8 ? 0x01 : 0x04), 0x00, addr); @@ -391,6 +402,8 @@ do_DAO(int test_write) sheet.len = j * 8; sheet.entries = cue; sheet.test_write = test_write; + sheet.session_type = multi ? CDR_SESS_MULTI : CDR_SESS_NONE; + sheet.session_format = format; if (verbose) { u_int8_t *ptr = (u_int8_t *)sheet.entries; @@ -405,14 +418,12 @@ do_DAO(int test_write) if (ioctl(fd, CDRIOCSENDCUE, &sheet) < 0) err(EX_IOERR, "ioctl(CDRIOCSENDCUE)"); -#if 0 - if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0) - err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)"); -#endif + for (i = 0; i < notracks; i++) { if (write_file(&tracks[i])) err(EX_IOERR, "write_file"); } + ioctl(fd, CDRIOCFLUSH); } @@ -456,8 +467,10 @@ write_file(struct track_info *track_info) if (track_info->addr >= 0) lseek(fd, track_info->addr * track_info->block_size, SEEK_SET); - fprintf(stderr, "addr = %d size = %d blocks = %d\n", - track_info->addr, track_info->file_size, roundup_blocks(track_info)); /* SOS */ + if (verbose) + fprintf(stderr, "addr = %d size = %d blocks = %d\n", + track_info->addr, track_info->file_size, + roundup_blocks(track_info)); if (!quiet) { if (track_info->file == STDIN_FILENO) @@ -472,7 +485,8 @@ write_file(struct track_info *track_info) filesize++; /* cheat, avoid divide by zero */ while ((count = read(track_info->file, buf, - track_info->block_size * BLOCKS)) > 0) { + MIN((track_info->file_size - size), + track_info->block_size * BLOCKS))) > 0) { int res; if (count % track_info->block_size) { @@ -499,6 +513,8 @@ write_file(struct track_info *track_info) } fprintf(stderr, " total %d KB\r", tot_size/1024); } + if (size >= track_info->file_size) + break; } if (!quiet) @@ -540,7 +556,7 @@ void usage(void) { fprintf(stderr, - "Usage: %s [-delmpqtv] [-f device] [-s speed] [command]" + "Usage: %s [-delmnpqtv] [-f device] [-s speed] [command]" " [command file ...]\n", getprogname()); exit(EX_USAGE); }