diff --git a/lsdvd-0.16/lsdvd.c b/lsdvd-0.16/lsdvd.c index 6f4f79e..4ccf746 100644 --- a/lsdvd-0.16/lsdvd.c +++ b/lsdvd-0.16/lsdvd.c @@ -1,3 +1,4 @@ +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ /* * lsdvd.c * @@ -47,7 +48,7 @@ language[] = { { "pt", "Portugues" }, { "qu", "Quechua" }, { "rm", "Rhaeto-Romance" }, { "rn", "Kirundi" }, { "ro", "Romanian" }, { "ru", "Russian" }, { "rw", "Kinyarwanda" }, { "sa", "Sanskrit" }, { "sd", "Sindhi" }, { "sg", "Sangho" }, { "sh", "Serbo-Croatian" }, { "si", "Sinhalese" }, { "sk", "Slovak" }, { "sl", "Slovenian" }, { "sm", "Samoan" }, - { "sn", "Shona" }, { "so", "Somali" }, { "sq", "Albanian" }, { "sr", "Serbian" }, { "ss", "Siswati" }, + { "sn", "Shona" }, { "so", "Somali" }, { "sq", "Albanian" }, { "sr", "Serbian" }, { "ss", "Siswati" }, { "st", "Sesotho" }, { "su", "Sundanese" }, { "sv", "Svenska" }, { "sw", "Swahili" }, { "ta", "Tamil" }, { "te", "Telugu" }, { "tg", "Tajik" }, { "th", "Thai" }, { "ti", "Tigrinya" }, { "tk", "Turkmen" }, { "tl", "Tagalog" }, { "tn", "Setswana" }, { "to", "Tonga" }, { "tr", "Turkish" }, { "ts", "Tsonga" }, { "tt", "Tatar" }, { "tw", "Twi" }, @@ -75,8 +76,8 @@ char *sample_freq[2] = {"48000", "48000"}; char *audio_type[5] = {"Undefined", "Normal", "Impaired", "Comments1", "Comments2"}; char *subp_type[16] = {"Undefined", "Normal", "Large", "Children", "reserved", "Normal_CC", "Large_CC", "Children_CC", "reserved", "Forced", "reserved", "reserved", "reserved", "Director", "Large_Director", "Children_Director"}; -int subp_id_shift[4] = {24, 8, 8, 8}; double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97}; +int subp_id_shift[4] = {24, 8, 8, 8}; char* program_name; @@ -85,38 +86,79 @@ char* program_name; //extern void oruby_print(struct dvd_info *dvd_info); //extern void ohuman_print(struct dvd_info *dvd_info); -int dvdtime2msec(dvd_time_t *dt) -{ - double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6]; - long ms; - ms = (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600000; - ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000; - ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000; +/* Ticks + * + * Compute durations using rational arithmetic to avoid loss of precision + * when summing. The result of the sum will be exact prior to converting + * the sum. + */ +#define TICK_SCALE 1001 + +typedef struct { + unsigned ticks; + unsigned scale; +} dvd_ticks_t; + +dvd_ticks_t dvdtime2ticks(const dvd_time_t *dt) + { + unsigned scale = 0; + unsigned secs = 0; + unsigned ticks = 0; + + if (dt) { + static const unsigned tick_scale[4] = { + 0, 25 * TICK_SCALE, 0, 30 * (TICK_SCALE-1) }; + + scale = tick_scale[(dt->frame_u & 0xc0) >> 6]; - if(fps > 0) - ms += (((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f)) * 1000.0 / fps; + secs += (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600; + secs += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60; + secs += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1; - return ms; + ticks += ((dt->frame_u & 0x30)>> 3) * 5 + (dt->frame_u & 0x0f); + ticks *= TICK_SCALE; + } + + return (dvd_ticks_t) { + .scale = scale, + .ticks = secs * scale + ticks, + }; + } + +dvd_ticks_t addticks(dvd_ticks_t lhs, dvd_ticks_t rhs) + { + if (lhs.ticks == 0) + return rhs; + if (rhs.ticks == 0) + return lhs; + return (dvd_ticks_t) { + .ticks = lhs.ticks + rhs.ticks, + .scale = lhs.scale == rhs.scale ? lhs.scale : 0, + }; } -/* - * This is used to add up sets of times in the struct. it's not elegant at all - * but a quick way to easily add up 4 times at once. tracking the times in usec's - * constantly is easier, but without using math.h, it sucks to actually DO anything with it - * also it ***has*** to be better to return the playback_time, not just mess with it like this - */ -void converttime(playback_time_t *pt, dvd_time_t *dt) +playback_time_t ticks2playbacktime(dvd_ticks_t dt) { - double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6]; - - pt->usec = pt->usec + (((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f)) * 1000.0 / fps; - pt->second = pt->second + ((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f); - pt->minute = pt->minute + ((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f); - pt->hour = pt->hour + ((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f); + unsigned secs = dt.ticks / dt.scale; + unsigned frac = dt.ticks % dt.scale; + + return (playback_time_t) { + .hour = (secs / 3600), + .minute = (secs % 3600) / 60, + .second = (secs % 60), + .usec = (frac * (1000000 / dt.scale) + + frac * (1000000 % dt.scale) / dt.scale), + .ticks = (dt.ticks), + .scale = (dt.scale), + }; +} - if ( pt->usec >= 1000 ) { pt->usec -= 1000; pt->second++; } - if ( pt->second >= 60 ) { pt->second -= 60; pt->minute++; } - if ( pt->minute > 59 ) { pt->minute -= 60; pt->hour++; } +double playbacktime(playback_time_t pt) +{ + return pt.hour * 3600 + + pt.minute * 60 + + pt.second * 1 + + pt.usec / 1e6; } /* @@ -221,7 +263,7 @@ char output_option(char *arg) return '\0'; } } - + int main(int argc, char *argv[]) { @@ -235,8 +277,8 @@ int main(int argc, char *argv[]) video_attr_t *video_attr; subp_attr_t *subp_attr; pgc_t *pgc; - int i, j, k, c, titles, cell, vts_ttn, title_set_nr; - char lang_code[3]; + int i, j, k, c, titles, vts_ttn, title_set_nr; + char lang_code[3]; char *dvd_device = "/dev/dvd"; int has_title = 0, ret = 0; int max_length = 0, max_track = 0; @@ -272,13 +314,13 @@ int main(int argc, char *argv[]) } if (argv[optind]) { dvd_device = argv[optind]; } - + ret = stat(dvd_device, &dvd_stat); if ( ret < 0 ) { fprintf(stderr, "Can't find device %s\n", dvd_device); return 1; } - + dvd = DVDOpen(dvd_device); if( !dvd ) { fprintf( stderr, "Can't open disc %s!\n", dvd_device); @@ -312,12 +354,12 @@ int main(int argc, char *argv[]) vmgi_mat = ifo_zero->vmgi_mat; struct dvd_info dvd_info; - + dvd_info.discinfo.device = dvd_device; dvd_info.discinfo.disc_title = has_title ? "unknown" : title; dvd_info.discinfo.vmg_id = vmgi_mat->vmg_identifier; dvd_info.discinfo.provider_id = vmgi_mat->provider_identifier; - + dvd_info.title_count = titles; dvd_info.titles = calloc(titles, sizeof(*dvd_info.titles)); @@ -338,13 +380,16 @@ int main(int argc, char *argv[]) vmgi_mat = ifo_zero->vmgi_mat; title_set_nr = ifo_zero->tt_srpt->title[j].title_set_nr; pgc = vts_pgcit->pgci_srp[ifo[title_set_nr]->vts_ptt_srpt->title[vts_ttn - 1].ptt[0].pgcn - 1].pgc; - - dvd_info.titles[j].general.length = dvdtime2msec(&pgc->playback_time)/1000.0; - converttime(&dvd_info.titles[j].general.playback_time, &pgc->playback_time); + dvd_info.titles[j].general.length = + playbacktime( + ticks2playbacktime( + dvdtime2ticks(&pgc->playback_time))); + dvd_info.titles[j].general.playback_time = + ticks2playbacktime(dvdtime2ticks(&pgc->playback_time)); dvd_info.titles[j].general.vts_id = vtsi_mat->vts_identifier; - - if (dvdtime2msec(&pgc->playback_time) > max_length) { - max_length = dvdtime2msec(&pgc->playback_time); + + if (dvd_info.titles[j].general.length > max_length) { + max_length = dvd_info.titles[j].general.length; max_track = j+1; } @@ -353,12 +398,12 @@ int main(int argc, char *argv[]) dvd_info.titles[j].audiostream_count = 0; for (k=0; k < 8; k++) - if (pgc->audio_control[k] & 0x8000) + if (pgc->audio_control[k] & 0x8000) dvd_info.titles[j].audiostream_count++; dvd_info.titles[j].subtitle_count = 0; for (k=0; k < 32; k++) - if (pgc->subp_control[k] & 0x80000000) + if (pgc->subp_control[k] & 0x80000000) dvd_info.titles[j].subtitle_count++; if(opt_v) { @@ -376,7 +421,7 @@ int main(int argc, char *argv[]) // PALETTE if (opt_P) { dvd_info.titles[j].palette = malloc(16 * sizeof(int)); - for (i=0; i < 16; i++) { dvd_info.titles[j].palette[i] = pgc->palette[i]; } + for (i=0; i < 16; i++) { dvd_info.titles[j].palette[i] = pgc->palette[i]; } } else { dvd_info.titles[j].palette = NULL; } @@ -420,32 +465,38 @@ int main(int argc, char *argv[]) // CHAPTERS - cell = 0; if (opt_c) { + int cell = pgc->program_map[0] - 1; + int end = cell + pgc->nr_of_cells; + dvd_info.titles[j].chapter_count = pgc->nr_of_programs; dvd_info.titles[j].chapters = calloc(dvd_info.titles[j].chapter_count, sizeof(*dvd_info.titles[j].chapters)); - int ms; for (i=0; inr_of_programs; i++) - { - ms=0; - int next = pgc->program_map[i+1]; - if (i == pgc->nr_of_programs - 1) next = pgc->nr_of_cells + 1; - - while (cell < next - 1) + { + dvd_ticks_t ticks = dvdtime2ticks(NULL); + int next = + (i == pgc->nr_of_programs - 1) + ? end + : pgc->program_map[i+1] - 1; + while (cell < next) { // Only use first cell of multi-angle cells if (pgc->cell_playback[cell].block_mode <= 1) { - ms = ms + dvdtime2msec(&pgc->cell_playback[cell].playback_time); - converttime(&dvd_info.titles[j].chapters[i].playback_time, &pgc->cell_playback[cell].playback_time); + dvd_ticks_t dt = dvdtime2ticks( + &pgc->cell_playback[cell].playback_time); + ticks = addticks(ticks, dt); + dvd_info.titles[j].chapters[i].playback_time = + ticks2playbacktime(dt); } cell++; } dvd_info.titles[j].chapters[i].startcell = pgc->program_map[i]; - dvd_info.titles[j].chapters[i].length = ms * 0.001; - - + dvd_info.titles[j].chapters[i].lastcell = cell; + dvd_info.titles[j].chapters[i].length = + playbacktime( + ticks2playbacktime(ticks)); } } @@ -457,10 +508,18 @@ int main(int argc, char *argv[]) if (opt_d) { for (i=0; inr_of_cells; i++) { - dvd_info.titles[j].cells[i].length = dvdtime2msec(&pgc->cell_playback[i].playback_time)/1000.0; + dvd_ticks_t dt = dvdtime2ticks( + &pgc->cell_playback[i].playback_time); + playback_time_t pt = ticks2playbacktime(dt); + + dvd_info.titles[j].cells[i].playback_time = pt; + dvd_info.titles[j].cells[i].length = + playbacktime(pt); + dvd_info.titles[j].cells[i].block_mode = pgc->cell_playback[i].block_mode; dvd_info.titles[j].cells[i].block_type = pgc->cell_playback[i].block_type; - converttime(&dvd_info.titles[j].cells[i].playback_time, &pgc->cell_playback[i].playback_time); + dvd_info.titles[j].cells[i].first_sector = pgc->cell_playback[i].first_sector; + dvd_info.titles[j].cells[i].last_sector = pgc->cell_playback[i].last_sector; } } else { dvd_info.titles[j].cells = NULL; @@ -474,11 +533,11 @@ int main(int argc, char *argv[]) for (i=0, k=0; i<32; i++) { if ((pgc->subp_control[i] & 0x80000000) == 0) continue; - + subp_attr = &vtsi_mat->vts_subp_attr[i]; sprintf(lang_code, "%c%c", subp_attr->lang_code>>8, subp_attr->lang_code & 0xff); if (!isalpha(lang_code[0]) || !isalpha(lang_code[1])) { lang_code[0] = 'x'; lang_code[1] = 'x'; } - + dvd_info.titles[j].subtitles[k].langcode = strdup(lang_code); dvd_info.titles[j].subtitles[k].language = lang_name(lang_code); dvd_info.titles[j].subtitles[k].content = subp_type[subp_attr->lang_extension]; @@ -489,33 +548,33 @@ int main(int argc, char *argv[]) dvd_info.titles[j].subtitles = NULL; } - } // if vtsi_mat + } // if vtsi_mat } // if not -t } // for each title - + if (! opt_t) { dvd_info.longest_track = max_track; } if (opt_p) { ocode_print(&perl_syntax, &dvd_info); } else { switch(opt_O) { - case 'p': - ocode_print(&perl_syntax, &dvd_info); + case 'p': + ocode_print(&perl_syntax, &dvd_info); break; case 'y': - ocode_print(&python_syntax, &dvd_info); + ocode_print(&python_syntax, &dvd_info); break; case 'x': - oxml_print(&dvd_info); + oxml_print(&dvd_info); break; case 'r': - ocode_print(&ruby_syntax, &dvd_info); + ocode_print(&ruby_syntax, &dvd_info); break; case 'd': - ocode_print(&debug_syntax, &dvd_info); + ocode_print(&debug_syntax, &dvd_info); break; default : - ohuman_print(&dvd_info); + ohuman_print(&dvd_info); break; } } diff --git a/lsdvd-0.16/lsdvd.h b/lsdvd-0.16/lsdvd.h index 8ba1f22..9c873cc 100644 --- a/lsdvd-0.16/lsdvd.h +++ b/lsdvd-0.16/lsdvd.h @@ -1,7 +1,9 @@ - +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ #ifndef _LSDVD_H_ #define _LSDVD_H_ +#include + extern int opt_a, opt_c, opt_n, opt_p, opt_q; extern int opt_s, opt_t, opt_v, opt_x, opt_d; @@ -10,6 +12,8 @@ typedef struct { int minute; int second; int usec; + int ticks; + int scale; } playback_time_t; struct dvd_info { @@ -56,11 +60,14 @@ struct dvd_info { float length; playback_time_t playback_time; int startcell; + int lastcell; } *chapters; int cell_count; struct { float length; playback_time_t playback_time; + uint32_t first_sector; + uint32_t last_sector; int block_mode; int block_type; } *cells; diff --git a/lsdvd-0.16/ocode.c b/lsdvd-0.16/ocode.c index d993775..50a8c8a 100644 --- a/lsdvd-0.16/ocode.c +++ b/lsdvd-0.16/ocode.c @@ -1,5 +1,8 @@ +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ #include "ocode.h" +#include + /* Simple helper macros for generating Perl structures */ @@ -145,6 +148,12 @@ static void STOP_() { while(_lvl) RETURN; } +static void ocode_playback_time(const playback_time_t *pb) { + ARRAY("duration"); + ADEF("%d", pb->ticks); + ADEF("%d", pb->scale); + RETURN; +} void ocode_print(struct Syntax *syntax_, struct dvd_info *dvd_info) { int j, i; @@ -170,6 +179,7 @@ void ocode_print(struct Syntax *syntax_, struct dvd_info *dvd_info) { HASH(0); DEF("ix", "%d", j+1); DEF("length", "%.3f", dvd_info->titles[j].general.length); + ocode_playback_time(&dvd_info->titles[j].general.playback_time); DEF("vts_id", "'%.12s'", dvd_info->titles[j].general.vts_id); if (dvd_info->titles[j].parameter.format != NULL ) { @@ -227,7 +237,9 @@ void ocode_print(struct Syntax *syntax_, struct dvd_info *dvd_info) { HASH(0); DEF("ix", "%d", i+1); DEF("length", "%.3f", dvd_info->titles[j].chapters[i].length); + ocode_playback_time(&dvd_info->titles[j].chapters[i].playback_time); DEF("startcell", "%d", dvd_info->titles[j].chapters[i].startcell); + DEF("lastcell", "%d", dvd_info->titles[j].chapters[i].lastcell); RETURN; } RETURN; @@ -241,6 +253,9 @@ void ocode_print(struct Syntax *syntax_, struct dvd_info *dvd_info) { HASH(0); DEF("ix", "%d", i+1); DEF("length", "%.3f", dvd_info->titles[j].cells[i].length); + ocode_playback_time(&dvd_info->titles[j].cells[i].playback_time); + DEF("first_sector", "%" PRIu32, dvd_info->titles[j].cells[i].first_sector); + DEF("last_sector", "%" PRIu32, dvd_info->titles[j].cells[i].last_sector); DEF("block_mode", "%d", dvd_info->titles[j].cells[i].block_mode); DEF("block_type", "%d", dvd_info->titles[j].cells[i].block_type); RETURN; @@ -276,4 +291,3 @@ void ocode_print(struct Syntax *syntax_, struct dvd_info *dvd_info) { } - diff --git a/lsdvd-0.16/ocode.h b/lsdvd-0.16/ocode.h index 0bcc3c7..00e1328 100644 --- a/lsdvd-0.16/ocode.h +++ b/lsdvd-0.16/ocode.h @@ -1,3 +1,4 @@ +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ #ifndef _OCODE_H_ #define _OCODE_H_ @@ -29,4 +30,3 @@ extern struct Syntax debug_syntax; void ocode_print(struct Syntax *, struct dvd_info*); #endif /* _OCODE_H_ */ - diff --git a/lsdvd-0.16/ohuman.c b/lsdvd-0.16/ohuman.c index ad91326..a9baec9 100644 --- a/lsdvd-0.16/ohuman.c +++ b/lsdvd-0.16/ohuman.c @@ -1,3 +1,4 @@ +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ #include #include "lsdvd.h" @@ -8,10 +9,10 @@ void ohuman_print(struct dvd_info *dvd_info) { printf("Disc Title: %s\n", dvd_info->discinfo.disc_title); int i, j; - for (j=0; j < dvd_info->title_count; j++) + for (j=0; j < dvd_info->title_count; j++) { if ( opt_t == j+1 || opt_t == 0 ) { - + //GENERAL printf("Title: %02d, Length: %02d:%02d:%02d.%03d ", j+1, dvd_info->titles[j].general.playback_time.hour, @@ -24,8 +25,8 @@ void ohuman_print(struct dvd_info *dvd_info) { // dvd_info->titles[j].general.length); printf("Chapters: %02d, Cells: %02d, ", dvd_info->titles[j].chapter_count_reported, dvd_info->titles[j].cell_count); printf("Audio streams: %02d, Subpictures: %02d", dvd_info->titles[j].audiostream_count, dvd_info->titles[j].subtitle_count); - printf("\n"); - + printf("\n"); + if (dvd_info->titles[j].parameter.format != NULL ) { printf("\tVTS: %02d, TTN: %02d, ", dvd_info->titles[j].parameter.vts, dvd_info->titles[j].parameter.ttn); printf("FPS: %.2f, ", dvd_info->titles[j].parameter.fps); @@ -69,35 +70,38 @@ void ohuman_print(struct dvd_info *dvd_info) { if (dvd_info->titles[j].chapters != NULL) { for (i=0; ititles[j].chapter_count; i++) { -// printf("\tChapter: %02d, Length: %02d:%02d:%02d.%03d, Start Cell: %02d\n", i+1, +// printf("\tChapter: %02d, Length: %02d:%02d:%02d.%03d, Start Cell: %02d, Last Cell: %02d\n", i+1, // (int)dvd_info->titles[j].chapters[i].length / 3600, // (int)(dvd_info->titles[j].chapters[i].length / 60 ) % 60, // (int)(dvd_info->titles[j].chapters[i].length) % 60, // (int)(dvd_info->titles[j].chapters[i].length*1000) % 1000, // dvd_info->titles[j].chapters[i].startcell); - printf("\tChapter: %02d, Length: %02d:%02d:%02d.%03d, Start Cell: %02d\n", i+1, + printf("\tChapter: %02d, Length: %02d:%02d:%02d.%03d, Start Cell: %d, Last Cell: %d\n", i+1, dvd_info->titles[j].chapters[i].playback_time.hour, dvd_info->titles[j].chapters[i].playback_time.minute, dvd_info->titles[j].chapters[i].playback_time.second, dvd_info->titles[j].chapters[i].playback_time.usec, - dvd_info->titles[j].chapters[i].startcell); + dvd_info->titles[j].chapters[i].startcell, + dvd_info->titles[j].chapters[i].lastcell); } } // CELLS if (dvd_info->titles[j].cells != NULL) { - for (i=0; ititles[j].cell_count; i++) + for (i=0; ititles[j].cell_count; i++) { -// printf("\tCell: %02d, Length: %02d:%02d:%02d.%03d\n", i+1, +// printf("\tCell: %02d, Length: %02d:%02d:%02d.%03d\n", i+1, // (int)dvd_info->titles[j].cells[i].length / 3600, // (int)(dvd_info->titles[j].cells[i].length / 60 ) % 60, // (int)(dvd_info->titles[j].cells[i].length) % 60, // (int)(dvd_info->titles[j].cells[i].length*1000) % 1000); - printf("\tCell: %02d, Length: %02d:%02d:%02d.%03d\n", i+1, + printf("\tCell: %02d, Length: %02d:%02d:%02d.%03d, First Sector: %d, Last Sector: %d\n", i+1, dvd_info->titles[j].cells[i].playback_time.hour, dvd_info->titles[j].cells[i].playback_time.minute, dvd_info->titles[j].cells[i].playback_time.second, - dvd_info->titles[j].cells[i].playback_time.usec); + dvd_info->titles[j].cells[i].playback_time.usec, + dvd_info->titles[j].cells[i].first_sector, + dvd_info->titles[j].cells[i].last_sector); } } diff --git a/lsdvd-0.16/oxml.c b/lsdvd-0.16/oxml.c index bdd7cd5..84bdc02 100644 --- a/lsdvd-0.16/oxml.c +++ b/lsdvd-0.16/oxml.c @@ -1,5 +1,8 @@ +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ #include "oxml.h" +#include + static int _xlvl = 0; char *_xlvl_type[256]; @@ -9,7 +12,7 @@ int XMLDEF_(char *name, const char *format, ...) { va_list argp; XMLINDENT; printf("<%s>", name); - + va_start(argp, format); vprintf(format, argp); va_end(argp); @@ -20,14 +23,14 @@ int XMLDEF_(char *name, const char *format, ...) { // int XMLBOX_(char *name) { // XMLINDENT; // printf("<%s>\n", name); -// _xlvl++; +// _xlvl++; // _xlvl_type[_xlvl] = malloc(20 * sizeof(char)); // sprintf(_xlvl_type[_xlvl], "", name); // return 0; //} //void XMLRETURN_() { -// _xlvl--; +// _xlvl--; // XMLINDENT; // printf("%s\n", _xlvl_type[_xlvl+1] ); // free(_xlvl_type[_xlvl+1]); @@ -56,6 +59,10 @@ void XMLSTOP_() { while(_xlvl) XMLRETURN; } +static void oxml_playback_time(const playback_time_t *pb) { + XMLDEF("duration", "%d %d", pb->ticks, pb->scale); +} + void oxml_print(struct dvd_info *dvd_info) { int j, i; @@ -75,6 +82,7 @@ void oxml_print(struct dvd_info *dvd_info) { XMLBOX("track"); XMLDEF("ix", "%d", j+1); XMLDEF("length", "%.3f", dvd_info->titles[j].general.length); + oxml_playback_time(&dvd_info->titles[j].general.playback_time); XMLDEF("vts_id", "%.12s", dvd_info->titles[j].general.vts_id); if (dvd_info->titles[j].parameter.format != NULL ) { @@ -87,7 +95,7 @@ void oxml_print(struct dvd_info *dvd_info) { XMLDEF("height", "%s", dvd_info->titles[j].parameter.height); XMLDEF("df", "%s", permitted_df_xml[dvd_info->titles[j].parameter.df_code]); } - + // PALETTE if (dvd_info->titles[j].palette != NULL ) { XMLBOX("palette"); @@ -128,7 +136,9 @@ void oxml_print(struct dvd_info *dvd_info) { XMLBOX("chapter"); XMLDEF("ix", "%d", i+1); XMLDEF("length", "%.3f", dvd_info->titles[j].chapters[i].length); + oxml_playback_time(&dvd_info->titles[j].chapters[i].playback_time); XMLDEF("startcell", "%d", dvd_info->titles[j].chapters[i].startcell); + XMLDEF("lastcell", "%d", dvd_info->titles[j].chapters[i].lastcell); XMLRETURN; } } @@ -140,6 +150,9 @@ void oxml_print(struct dvd_info *dvd_info) { XMLBOX("cell"); XMLDEF("ix", "%d", i+1); XMLDEF("length", "%.3f", dvd_info->titles[j].cells[i].length); + oxml_playback_time(&dvd_info->titles[j].cells[i].playback_time); + XMLDEF("first_sector", "%" PRIu32, dvd_info->titles[j].cells[i].first_sector); + XMLDEF("last_sector", "%" PRIu32, dvd_info->titles[j].cells[i].last_sector); XMLDEF("block_mode", "%d", dvd_info->titles[j].cells[i].block_mode); XMLDEF("block_type", "%d", dvd_info->titles[j].cells[i].block_type); XMLRETURN; @@ -159,7 +172,7 @@ void oxml_print(struct dvd_info *dvd_info) { XMLRETURN; } } - XMLRETURN; + XMLRETURN; } } } diff --git a/lsdvd-0.16/oxml.h b/lsdvd-0.16/oxml.h index 7dfa15d..10a1e5f 100644 --- a/lsdvd-0.16/oxml.h +++ b/lsdvd-0.16/oxml.h @@ -1,4 +1,4 @@ - +/* -*- c-basic-offset:8; indent-tabs-mode:t -*- vi: set sw=8: */ #ifndef _OXML_H_ #define _OXML_H_