comparison libdvdread/ifo_print.c @ 367:1274107d0eac src

moved dvdread to libdvdread; it's the first step for the separation of the lib from dvdnav
author nicodvb
date Sat, 31 May 2008 12:29:19 +0000
parents dvdread/ifo_print.c@638d87492170
children 1ab4b25afca3
comparison
equal deleted inserted replaced
366:5b8539cacebf 367:1274107d0eac
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 * $Id$
17 *
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <inttypes.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <assert.h>
27
28 #include "ifo_types.h"
29 #include "ifo_read.h"
30 #include "ifo_print.h"
31 #include "vmcmd.h"
32
33 /* Put this in some other file / package? It's used in nav_print too. */
34 static void ifo_print_time(int level, dvd_time_t *dtime) {
35 const char *rate;
36 assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
37 assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
38 assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
39 assert((dtime->frame_u&0xf) < 0xa);
40
41 printf("%02x:%02x:%02x.%02x",
42 dtime->hour,
43 dtime->minute,
44 dtime->second,
45 dtime->frame_u & 0x3f);
46 switch((dtime->frame_u & 0xc0) >> 6) {
47 case 1:
48 rate = "25.00";
49 break;
50 case 3:
51 rate = "29.97";
52 break;
53 default:
54 if(dtime->hour == 0 && dtime->minute == 0
55 && dtime->second == 0 && dtime->frame_u == 0)
56 rate = "no";
57 else
58 rate = "(please send a bug report)";
59 break;
60 }
61 printf(" @ %s fps", rate);
62 }
63
64 /* Put this in some other file / package? It's used in nav_print too.
65 Possibly also by the vm / navigator. */
66 static void ifo_print_cmd(int row, vm_cmd_t *command) {
67 int i;
68
69 printf("(%03d) ", row + 1);
70 for(i=0;i<8;i++)
71 printf("%02x ", command->bytes[i]);
72 printf("| ");
73 #if 0
74 //disabled call of dvdnav function
75 vm_print_mnemonic(command);
76 #endif
77 printf("\n");
78 }
79
80 static void ifo_print_video_attributes(int level, video_attr_t *attr) {
81
82 /* The following test is shorter but not correct ISO C,
83 memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */
84 if(attr->mpeg_version == 0
85 && attr->video_format == 0
86 && attr->display_aspect_ratio == 0
87 && attr->permitted_df == 0
88 && attr->unknown1 == 0
89 && attr->line21_cc_1 == 0
90 && attr->line21_cc_2 == 0
91 && attr->video_format == 0
92 && attr->letterboxed == 0
93 && attr->film_mode == 0) {
94 printf("-- Unspecified --");
95 return;
96 }
97
98 switch(attr->mpeg_version) {
99 case 0:
100 printf("mpeg1, ");
101 break;
102 case 1:
103 printf("mpeg2, ");
104 break;
105 default:
106 printf("(please send a bug report), ");
107 }
108
109 switch(attr->video_format) {
110 case 0:
111 printf("ntsc, ");
112 break;
113 case 1:
114 printf("pal, ");
115 break;
116 default:
117 printf("(please send a bug report), ");
118 }
119
120 switch(attr->display_aspect_ratio) {
121 case 0:
122 printf("4:3, ");
123 break;
124 case 3:
125 printf("16:9, ");
126 break;
127 default:
128 printf("(please send a bug report), ");
129 }
130
131 // Wide is allways allowed..!!!
132 switch(attr->permitted_df) {
133 case 0:
134 printf("pan&scan+letterboxed, ");
135 break;
136 case 1:
137 printf("only pan&scan, "); //??
138 break;
139 case 2:
140 printf("only letterboxed, ");
141 break;
142 case 3:
143 printf("not specified, ");
144 break;
145 default:
146 printf("(please send a bug report), ");
147 }
148
149 printf("U%x, ", attr->unknown1);
150 assert(!attr->unknown1);
151
152 if(attr->line21_cc_1 || attr->line21_cc_2) {
153 printf("NTSC CC ");
154 if(attr->line21_cc_1)
155 printf("1, ");
156 if(attr->line21_cc_2)
157 printf("2, ");
158 }
159
160 {
161 int height = 480;
162 if(attr->video_format != 0)
163 height = 576;
164 switch(attr->picture_size) {
165 case 0:
166 printf("720x%d, ", height);
167 break;
168 case 1:
169 printf("704x%d, ", height);
170 break;
171 case 2:
172 printf("352x%d, ", height);
173 break;
174 case 3:
175 printf("352x%d, ", height/2);
176 break;
177 default:
178 printf("(please send a bug report), ");
179 }
180 }
181
182 if(attr->letterboxed) {
183 printf("source letterboxed, ");
184 }
185
186 if(attr->film_mode) {
187 printf("film. ");
188 } else {
189 printf("video. "); //camera
190 }
191 }
192
193 static void ifo_print_audio_attributes(int level, audio_attr_t *attr) {
194
195 if(attr->audio_format == 0
196 && attr->multichannel_extension == 0
197 && attr->lang_type == 0
198 && attr->application_mode == 0
199 && attr->quantization == 0
200 && attr->sample_frequency == 0
201 && attr->channels == 0
202 && attr->lang_extension == 0
203 && attr->unknown1 == 0
204 && attr->unknown3 == 0) {
205 printf("-- Unspecified --");
206 return;
207 }
208
209 switch(attr->audio_format) {
210 case 0:
211 printf("ac3 ");
212 if(attr->quantization != 3)
213 printf("(please send a bug report) ac3 quant/drc not 3 (%d)", attr->quantization);
214 break;
215 case 1:
216 printf("(please send a bug report) ");
217 break;
218 case 2:
219 printf("mpeg1 ");
220 case 3:
221 printf("mpeg2ext ");
222 switch(attr->quantization) {
223 case 0:
224 printf("no drc ");
225 break;
226 case 1:
227 printf("drc ");
228 break;
229 default:
230 printf("(please send a bug report) mpeg reserved quant/drc (%d)", attr->quantization);
231 }
232 break;
233 case 4:
234 printf("lpcm ");
235 switch(attr->quantization) {
236 case 0:
237 printf("16bit ");
238 break;
239 case 1:
240 printf("20bit ");
241 break;
242 case 2:
243 printf("24bit ");
244 break;
245 case 3:
246 printf("(please send a bug report) lpcm reserved quant/drc (%d)", attr->quantization);
247 break;
248 }
249 break;
250 case 5:
251 printf("(please send a bug report) ");
252 break;
253 case 6:
254 printf("dts ");
255 if(attr->quantization != 3)
256 printf("(please send a bug report) dts quant/drc not 3 (%d)", attr->quantization);
257 break;
258 default:
259 printf("(please send a bug report) ");
260 }
261
262 if(attr->multichannel_extension)
263 printf("multichannel_extension ");
264
265 switch(attr->lang_type) {
266 case 0:
267 // not specified
268 assert(attr->lang_code == 0 || attr->lang_code == 0xffff);
269 break;
270 case 1:
271 printf("%c%c ", attr->lang_code>>8, attr->lang_code & 0xff);
272 break;
273 default:
274 printf("(please send a bug report) ");
275 }
276
277 switch(attr->application_mode) {
278 case 0:
279 // not specified
280 break;
281 case 1:
282 printf("karaoke mode ");
283 break;
284 case 2:
285 printf("surround sound mode ");
286 break;
287 default:
288 printf("(please send a bug report) ");
289 }
290
291 switch(attr->quantization) {
292 case 0:
293 printf("16bit ");
294 break;
295 case 1:
296 printf("20bit ");
297 break;
298 case 2:
299 printf("24bit ");
300 break;
301 case 3:
302 printf("drc ");
303 break;
304 default:
305 printf("(please send a bug report) ");
306 }
307
308 switch(attr->sample_frequency) {
309 case 0:
310 printf("48kHz ");
311 break;
312 case 1:
313 printf("??kHz ");
314 break;
315 default:
316 printf("sample_frequency %i (please send a bug report) ",
317 attr->sample_frequency);
318 }
319
320 printf("%dCh ", attr->channels + 1);
321
322 switch(attr->lang_extension) {
323 case 0:
324 printf("Not specified ");
325 break;
326 case 1: // Normal audio
327 printf("Normal Caption ");
328 break;
329 case 2: // visually imparied
330 printf("Audio for visually impaired ");
331 break;
332 case 3: // Directors 1
333 printf("Director's comments 1 ");
334 break;
335 case 4: // Directors 2
336 printf("Director's comments 2 ");
337 break;
338 //case 4: // Music score ?
339 default:
340 printf("(please send a bug report) ");
341 }
342
343 printf("%d ", attr->unknown1);
344 printf("%d ", attr->unknown3);
345 }
346
347 static void ifo_print_subp_attributes(int level, subp_attr_t *attr) {
348
349 if(attr->type == 0
350 && attr->lang_code == 0
351 && attr->zero1 == 0
352 && attr->zero2 == 0
353 && attr->lang_extension== 0) {
354 printf("-- Unspecified --");
355 return;
356 }
357
358 printf("type %02x ", attr->type);
359
360 if(isalpha((int)(attr->lang_code >> 8))
361 && isalpha((int)(attr->lang_code & 0xff))) {
362 printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff);
363 } else {
364 printf("%02x%02x ", 0xff & (unsigned)(attr->lang_code >> 8),
365 0xff & (unsigned)(attr->lang_code & 0xff));
366 }
367
368 printf("%d ", attr->zero1);
369 printf("%d ", attr->zero2);
370
371 switch(attr->lang_extension) {
372 case 0:
373 printf("Not specified ");
374 break;
375 case 1:
376 printf("Caption with normal size character ");
377 break;
378 case 2:
379 printf("Caption with bigger size character ");
380 break;
381 case 3:
382 printf("Caption for children ");
383 break;
384 case 4:
385 printf("reserved ");
386 break;
387 case 5:
388 printf("Closed Caption with normal size character ");
389 break;
390 case 6:
391 printf("Closed Caption with bigger size character ");
392 break;
393 case 7:
394 printf("Closed Caption for children ");
395 break;
396 case 8:
397 printf("reserved ");
398 break;
399 case 9:
400 printf("Forced Caption");
401 break;
402 case 10:
403 printf("reserved ");
404 break;
405 case 11:
406 printf("reserved ");
407 break;
408 case 12:
409 printf("reserved ");
410 break;
411 case 13:
412 printf("Director's comments with normal size character ");
413 break;
414 case 14:
415 printf("Director's comments with bigger size character ");
416 break;
417 case 15:
418 printf("Director's comments for children ");
419 break;
420 default:
421 printf("(please send a bug report) ");
422 }
423
424 }
425
426
427 static void ifo_print_USER_OPS(user_ops_t *user_ops) {
428 uint32_t uops;
429 unsigned char *ptr = (unsigned char *)user_ops;
430
431 uops = (*ptr++ << 24);
432 uops |= (*ptr++ << 16);
433 uops |= (*ptr++ << 8);
434 uops |= (*ptr++);
435
436 if(uops == 0) {
437 printf("None\n");
438 } else if(uops == 0x01ffffff) {
439 printf("All\n");
440 } else {
441 if(user_ops->title_or_time_play)
442 printf("Title or Time Play, ");
443 if(user_ops->chapter_search_or_play)
444 printf("Chapter Search or Play, ");
445 if(user_ops->title_play)
446 printf("Title Play, ");
447 if(user_ops->stop)
448 printf("Stop, ");
449 if(user_ops->go_up)
450 printf("Go Up, ");
451 if(user_ops->time_or_chapter_search)
452 printf("Time or Chapter Search, ");
453 if(user_ops->prev_or_top_pg_search)
454 printf("Prev or Top PG Search, ");
455 if(user_ops->next_pg_search)
456 printf("Next PG Search, ");
457 if(user_ops->forward_scan)
458 printf("Forward Scan, ");
459 if(user_ops->backward_scan)
460 printf("Backward Scan, ");
461 if(user_ops->title_menu_call)
462 printf("Title Menu Call, ");
463 if(user_ops->root_menu_call)
464 printf("Root Menu Call, ");
465 if(user_ops->subpic_menu_call)
466 printf("SubPic Menu Call, ");
467 if(user_ops->audio_menu_call)
468 printf("Audio Menu Call, ");
469 if(user_ops->angle_menu_call)
470 printf("Angle Menu Call, ");
471 if(user_ops->chapter_menu_call)
472 printf("Chapter Menu Call, ");
473 if(user_ops->resume)
474 printf("Resume, ");
475 if(user_ops->button_select_or_activate)
476 printf("Button Select or Activate, ");
477 if(user_ops->still_off)
478 printf("Still Off, ");
479 if(user_ops->pause_on)
480 printf("Pause On, ");
481 if(user_ops->audio_stream_change)
482 printf("Audio Stream Change, ");
483 if(user_ops->subpic_stream_change)
484 printf("SubPic Stream Change, ");
485 if(user_ops->angle_change)
486 printf("Angle Change, ");
487 if(user_ops->karaoke_audio_pres_mode_change)
488 printf("Karaoke Audio Pres Mode Change, ");
489 if(user_ops->video_pres_mode_change)
490 printf("Video Pres Mode Change, ");
491 printf("\n");
492 }
493 }
494
495
496 void ifo_print_VMGI_MAT(vmgi_mat_t *vmgi_mat) {
497
498 printf("VMG Identifier: %.12s\n", vmgi_mat->vmg_identifier);
499 printf("Last Sector of VMG: %08x\n", vmgi_mat->vmg_last_sector);
500 printf("Last Sector of VMGI: %08x\n", vmgi_mat->vmgi_last_sector);
501 printf("Specification version number: %01x.%01x\n",
502 vmgi_mat->specification_version >> 4,
503 vmgi_mat->specification_version & 0xf);
504 /* Byte 2 of 'VMG Category' (00xx0000) is the Region Code */
505 printf("VMG Category: %08x (Region Code=%02x)\n", vmgi_mat->vmg_category, ((vmgi_mat->vmg_category >> 16) & 0xff) ^0xff);
506 printf("VMG Number of Volumes: %i\n", vmgi_mat->vmg_nr_of_volumes);
507 printf("VMG This Volume: %i\n", vmgi_mat->vmg_this_volume_nr);
508 printf("Disc side %i\n", vmgi_mat->disc_side);
509 printf("VMG Number of Title Sets %i\n", vmgi_mat->vmg_nr_of_title_sets);
510 printf("Provider ID: %.32s\n", vmgi_mat->provider_identifier);
511 printf("VMG POS Code: %08x", (uint32_t)(vmgi_mat->vmg_pos_code >> 32));
512 printf("%08x\n", (uint32_t)vmgi_mat->vmg_pos_code);
513 printf("End byte of VMGI_MAT: %08x\n", vmgi_mat->vmgi_last_byte);
514 printf("Start byte of First Play PGC (FP PGC): %08x\n",
515 vmgi_mat->first_play_pgc);
516 printf("Start sector of VMGM_VOBS: %08x\n", vmgi_mat->vmgm_vobs);
517 printf("Start sector of TT_SRPT: %08x\n", vmgi_mat->tt_srpt);
518 printf("Start sector of VMGM_PGCI_UT: %08x\n", vmgi_mat->vmgm_pgci_ut);
519 printf("Start sector of PTL_MAIT: %08x\n", vmgi_mat->ptl_mait);
520 printf("Start sector of VTS_ATRT: %08x\n", vmgi_mat->vts_atrt);
521 printf("Start sector of TXTDT_MG: %08x\n", vmgi_mat->txtdt_mgi);
522 printf("Start sector of VMGM_C_ADT: %08x\n", vmgi_mat->vmgm_c_adt);
523 printf("Start sector of VMGM_VOBU_ADMAP: %08x\n",
524 vmgi_mat->vmgm_vobu_admap);
525 printf("Video attributes of VMGM_VOBS: ");
526 ifo_print_video_attributes(5, &vmgi_mat->vmgm_video_attr);
527 printf("\n");
528 printf("VMGM Number of Audio attributes: %i\n",
529 vmgi_mat->nr_of_vmgm_audio_streams);
530 if(vmgi_mat->nr_of_vmgm_audio_streams > 0) {
531 printf("\tstream %i status: ", 1);
532 ifo_print_audio_attributes(5, &vmgi_mat->vmgm_audio_attr);
533 printf("\n");
534 }
535 printf("VMGM Number of Sub-picture attributes: %i\n",
536 vmgi_mat->nr_of_vmgm_subp_streams);
537 if(vmgi_mat->nr_of_vmgm_subp_streams > 0) {
538 printf("\tstream %2i status: ", 1);
539 ifo_print_subp_attributes(5, &vmgi_mat->vmgm_subp_attr);
540 printf("\n");
541 }
542 }
543
544
545 void ifo_print_VTSI_MAT(vtsi_mat_t *vtsi_mat) {
546 int i;
547
548 printf("VTS Identifier: %.12s\n", vtsi_mat->vts_identifier);
549 printf("Last Sector of VTS: %08x\n", vtsi_mat->vts_last_sector);
550 printf("Last Sector of VTSI: %08x\n", vtsi_mat->vtsi_last_sector);
551 printf("Specification version number: %01x.%01x\n",
552 vtsi_mat->specification_version>>4,
553 vtsi_mat->specification_version&0xf);
554 printf("VTS Category: %08x\n", vtsi_mat->vts_category);
555 printf("End byte of VTSI_MAT: %08x\n", vtsi_mat->vtsi_last_byte);
556 printf("Start sector of VTSM_VOBS: %08x\n", vtsi_mat->vtsm_vobs);
557 printf("Start sector of VTSTT_VOBS: %08x\n", vtsi_mat->vtstt_vobs);
558 printf("Start sector of VTS_PTT_SRPT: %08x\n", vtsi_mat->vts_ptt_srpt);
559 printf("Start sector of VTS_PGCIT: %08x\n", vtsi_mat->vts_pgcit);
560 printf("Start sector of VTSM_PGCI_UT: %08x\n", vtsi_mat->vtsm_pgci_ut);
561 printf("Start sector of VTS_TMAPT: %08x\n", vtsi_mat->vts_tmapt);
562 printf("Start sector of VTSM_C_ADT: %08x\n", vtsi_mat->vtsm_c_adt);
563 printf("Start sector of VTSM_VOBU_ADMAP: %08x\n",vtsi_mat->vtsm_vobu_admap);
564 printf("Start sector of VTS_C_ADT: %08x\n", vtsi_mat->vts_c_adt);
565 printf("Start sector of VTS_VOBU_ADMAP: %08x\n", vtsi_mat->vts_vobu_admap);
566
567 printf("Video attributes of VTSM_VOBS: ");
568 ifo_print_video_attributes(5, &vtsi_mat->vtsm_video_attr);
569 printf("\n");
570
571 printf("VTSM Number of Audio attributes: %i\n",
572 vtsi_mat->nr_of_vtsm_audio_streams);
573 if(vtsi_mat->nr_of_vtsm_audio_streams > 0) {
574 printf("\tstream %i status: ", 1);
575 ifo_print_audio_attributes(5, &vtsi_mat->vtsm_audio_attr);
576 printf("\n");
577 }
578
579 printf("VTSM Number of Sub-picture attributes: %i\n",
580 vtsi_mat->nr_of_vtsm_subp_streams);
581 if(vtsi_mat->nr_of_vtsm_subp_streams > 0) {
582 printf("\tstream %2i status: ", 1);
583 ifo_print_subp_attributes(5, &vtsi_mat->vtsm_subp_attr);
584 printf("\n");
585 }
586
587 printf("Video attributes of VTS_VOBS: ");
588 ifo_print_video_attributes(5, &vtsi_mat->vts_video_attr);
589 printf("\n");
590
591 printf("VTS Number of Audio attributes: %i\n",
592 vtsi_mat->nr_of_vts_audio_streams);
593 for(i = 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) {
594 printf("\tstream %i status: ", i);
595 ifo_print_audio_attributes(5, &vtsi_mat->vts_audio_attr[i]);
596 printf("\n");
597 }
598
599 printf("VTS Number of Subpicture attributes: %i\n",
600 vtsi_mat->nr_of_vts_subp_streams);
601 for(i = 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) {
602 printf("\tstream %2i status: ", i);
603 ifo_print_subp_attributes(5, &vtsi_mat->vts_subp_attr[i]);
604 printf("\n");
605 }
606 }
607
608
609 static void ifo_print_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) {
610 int i;
611
612 if(cmd_tbl == NULL) {
613 printf("No Command table present\n");
614 return;
615 }
616
617 printf("Number of Pre commands: %i\n", cmd_tbl->nr_of_pre);
618 for(i = 0; i < cmd_tbl->nr_of_pre; i++) {
619 ifo_print_cmd(i, &cmd_tbl->pre_cmds[i]);
620 }
621
622 printf("Number of Post commands: %i\n", cmd_tbl->nr_of_post);
623 for(i = 0; i < cmd_tbl->nr_of_post; i++) {
624 ifo_print_cmd(i, &cmd_tbl->post_cmds[i]);
625 }
626
627 printf("Number of Cell commands: %i\n", cmd_tbl->nr_of_cell);
628 for(i = 0; i < cmd_tbl->nr_of_cell; i++) {
629 ifo_print_cmd(i, &cmd_tbl->cell_cmds[i]);
630 }
631 }
632
633
634 static void ifo_print_PGC_PROGRAM_MAP(pgc_program_map_t *program_map, int nr) {
635 int i;
636
637 if(program_map == NULL) {
638 printf("No Program map present\n");
639 return;
640 }
641
642 for(i = 0; i < nr; i++) {
643 printf("Program %3i Entry Cell: %3i\n", i + 1, program_map[i]);
644 }
645 }
646
647
648 static void ifo_print_CELL_PLAYBACK(cell_playback_t *cell_playback, int nr) {
649 int i;
650
651 if(cell_playback == NULL) {
652 printf("No Cell Playback info present\n");
653 return;
654 }
655
656 for(i=0;i<nr;i++) {
657 printf("Cell: %3i ", i + 1);
658
659 ifo_print_time(5, &cell_playback[i].playback_time);
660 printf("\t");
661
662 if(cell_playback[i].block_mode || cell_playback[i].block_type) {
663 const char *s;
664 switch(cell_playback[i].block_mode) {
665 case 0:
666 s = "not a"; break;
667 case 1:
668 s = "the first"; break;
669 case 2:
670 default:
671 s = ""; break;
672 case 3:
673 s = "last"; break;
674 }
675 printf("%s cell in the block ", s);
676
677 switch(cell_playback[i].block_type) {
678 case 0:
679 printf("not part of the block ");
680 break;
681 case 1:
682 printf("angle block ");
683 break;
684 case 2:
685 case 3:
686 printf("(send bug repport) ");
687 break;
688 }
689 }
690 if(cell_playback[i].seamless_play)
691 printf("presented seamlessly ");
692 if(cell_playback[i].interleaved)
693 printf("cell is interleaved ");
694 if(cell_playback[i].stc_discontinuity)
695 printf("STC_discontinuty ");
696 if(cell_playback[i].seamless_angle)
697 printf("only seamless angle ");
698 if(cell_playback[i].playback_mode)
699 printf("only still VOBUs ");
700 if(cell_playback[i].restricted)
701 printf("restricted cell ");
702 if(cell_playback[i].unknown2)
703 printf("Unknown 0x%x ", cell_playback[i].unknown2);
704 if(cell_playback[i].still_time)
705 printf("still time %d ", cell_playback[i].still_time);
706 if(cell_playback[i].cell_cmd_nr)
707 printf("cell command %d", cell_playback[i].cell_cmd_nr);
708
709 printf("\n\tStart sector: %08x\tFirst ILVU end sector: %08x\n",
710 cell_playback[i].first_sector,
711 cell_playback[i].first_ilvu_end_sector);
712 printf("\tEnd sector: %08x\tLast VOBU start sector: %08x\n",
713 cell_playback[i].last_sector,
714 cell_playback[i].last_vobu_start_sector);
715 }
716 }
717
718 static void ifo_print_CELL_POSITION(cell_position_t *cell_position, int nr) {
719 int i;
720
721 if(cell_position == NULL) {
722 printf("No Cell Position info present\n");
723 return;
724 }
725
726 for(i=0;i<nr;i++) {
727 printf("Cell: %3i has VOB ID: %3i, Cell ID: %3i\n", i + 1,
728 cell_position[i].vob_id_nr, cell_position[i].cell_nr);
729 }
730 }
731
732
733 void ifo_print_PGC(pgc_t *pgc) {
734 int i;
735
736 if (!pgc) {
737 printf("None\n");
738 return;
739 }
740 printf("Number of Programs: %i\n", pgc->nr_of_programs);
741 printf("Number of Cells: %i\n", pgc->nr_of_cells);
742 /* Check that time is 0:0:0:0 also if nr_of_programs==0 */
743 printf("Playback time: ");
744 ifo_print_time(5, &pgc->playback_time); printf("\n");
745
746 /* If no programs/no time then does this mean anything? */
747 printf("Prohibited user operations: ");
748 ifo_print_USER_OPS(&pgc->prohibited_ops);
749
750 for(i = 0; i < 8; i++) {
751 if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */
752 printf("Audio stream %i control: %04x\n",
753 i, pgc->audio_control[i]);
754 }
755 }
756
757 for(i = 0; i < 32; i++) {
758 if(pgc->subp_control[i] & 0x80000000) { /* The 'is present' bit */
759 printf("Subpicture stream %2i control: %08x: 4:3=%d, Wide=%d, Letterbox=%d, Pan-Scan=%d\n",
760 i, pgc->subp_control[i],
761 (pgc->subp_control[i] >>24) & 0x1f,
762 (pgc->subp_control[i] >>16) & 0x1f,
763 (pgc->subp_control[i] >>8) & 0x1f,
764 (pgc->subp_control[i] ) & 0x1f);
765 }
766 }
767
768 printf("Next PGC number: %i\n", pgc->next_pgc_nr);
769 printf("Prev PGC number: %i\n", pgc->prev_pgc_nr);
770 printf("GoUp PGC number: %i\n", pgc->goup_pgc_nr);
771 if(pgc->nr_of_programs != 0) {
772 printf("Still time: %i seconds (255=inf)\n", pgc->still_time);
773 printf("PG Playback mode %02x\n", pgc->pg_playback_mode);
774 }
775
776 if(pgc->nr_of_programs != 0) {
777 for(i = 0; i < 16; i++) {
778 printf("Color %2i: %08x\n", i, pgc->palette[i]);
779 }
780 }
781
782 /* Memmory offsets to div. tables. */
783 ifo_print_PGC_COMMAND_TBL(pgc->command_tbl);
784 ifo_print_PGC_PROGRAM_MAP(pgc->program_map, pgc->nr_of_programs);
785 ifo_print_CELL_PLAYBACK(pgc->cell_playback, pgc->nr_of_cells);
786 ifo_print_CELL_POSITION(pgc->cell_position, pgc->nr_of_cells);
787 }
788
789
790 void ifo_print_TT_SRPT(tt_srpt_t *tt_srpt) {
791 int i;
792
793 printf("Number of TitleTrack search pointers: %i\n",
794 tt_srpt->nr_of_srpts);
795 for(i=0;i<tt_srpt->nr_of_srpts;i++) {
796 printf("Title Track index %i\n", i + 1);
797 printf("\tTitle set number (VTS): %i",
798 tt_srpt->title[i].title_set_nr);
799 printf("\tVTS_TTN: %i\n", tt_srpt->title[i].vts_ttn);
800 printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts);
801 printf("\tNumber of angles: %i\n",
802 tt_srpt->title[i].nr_of_angles);
803
804 printf("\tTitle playback type: (%02x)\n",
805 *(uint8_t *)&(tt_srpt->title[i].pb_ty));
806 printf("\t\t%s\n",
807 tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ? "Random or Shuffle" : "Sequencial");
808 if (tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd) printf("\t\tJump/Link/Call exists in cell cmd\n");
809 if (tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd) printf("\t\tJump/Link/Call exists in pre/post cmd\n");
810 if (tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd) printf("\t\tJump/Link/Call exists in button cmd\n");
811 if (tt_srpt->title[i].pb_ty.jlc_exists_in_tt_dom) printf("\t\tJump/Link/Call exists in tt_dom cmd\n");
812 printf("\t\tTitle or time play:%d\n", tt_srpt->title[i].pb_ty.title_or_time_play);
813 printf("\t\tChapter search or play:%d\n", tt_srpt->title[i].pb_ty.chapter_search_or_play);
814
815 printf("\tParental ID field: %04x\n",
816 tt_srpt->title[i].parental_id);
817 printf("\tTitle set starting sector %08x\n",
818 tt_srpt->title[i].title_set_sector);
819 }
820 }
821
822
823 void ifo_print_VTS_PTT_SRPT(vts_ptt_srpt_t *vts_ptt_srpt) {
824 int i, j;
825 printf(" nr_of_srpts %i last byte %i\n",
826 vts_ptt_srpt->nr_of_srpts,
827 vts_ptt_srpt->last_byte);
828 for(i=0;i<vts_ptt_srpt->nr_of_srpts;i++) {
829 for(j=0;j<vts_ptt_srpt->title[i].nr_of_ptts;j++) {
830 printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
831 i + 1, j + 1,
832 vts_ptt_srpt->title[i].ptt[j].pgcn,
833 vts_ptt_srpt->title[i].ptt[j].pgn );
834 }
835 }
836 }
837
838
839 static void hexdump(uint8_t *ptr, int len) {
840 while(len--)
841 printf("%02x ", *ptr++);
842 }
843
844 void ifo_print_PTL_MAIT(ptl_mait_t *ptl_mait) {
845 int i, j;
846
847 printf("Number of Countries: %i\n", ptl_mait->nr_of_countries);
848 printf("Number of VTSs: %i\n", ptl_mait->nr_of_vtss);
849 //printf("Last byte: %i\n", ptl_mait->last_byte);
850
851 for(i = 0; i < ptl_mait->nr_of_countries; i++) {
852 printf("Country code: %c%c\n",
853 ptl_mait->countries[i].country_code >> 8,
854 ptl_mait->countries[i].country_code & 0xff);
855 /*
856 printf("Start byte: %04x %i\n",
857 ptl_mait->countries[i].pf_ptl_mai_start_byte,
858 ptl_mait->countries[i].pf_ptl_mai_start_byte);
859 */
860 /* This seems to be pointing at a array with 8 2byte fields per VTS
861 ? and one extra for the menu? always an odd number of VTSs on
862 all the dics I tested so it might be padding to even also.
863 If it is for the menu it probably the first entry. */
864 for(j=0;j<8;j++) {
865 hexdump( (uint8_t *)ptl_mait->countries - PTL_MAIT_COUNTRY_SIZE
866 + ptl_mait->countries[i].pf_ptl_mai_start_byte
867 + j*(ptl_mait->nr_of_vtss+1)*2, (ptl_mait->nr_of_vtss+1)*2);
868 printf("\n");
869 }
870 }
871 }
872
873 void ifo_print_VTS_TMAPT(vts_tmapt_t *vts_tmapt) {
874 unsigned int timeunit;
875 int i, j;
876
877 printf("Number of VTS_TMAPS: %i\n", vts_tmapt->nr_of_tmaps);
878 printf("Last byte: %i\n", vts_tmapt->last_byte);
879
880 for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
881 printf("TMAP %i (number matches title PGC number.)\n", i + 1);
882 printf(" offset %d relative to VTS_TMAPTI\n", vts_tmapt->tmap_offset[i]);
883 printf(" Time unit (seconds): %i\n", vts_tmapt->tmap[i].tmu);
884 printf(" Number of entries: %i\n", vts_tmapt->tmap[i].nr_of_entries);
885 timeunit = vts_tmapt->tmap[i].tmu;
886 for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
887 unsigned int ac_time = timeunit * (j + 1);
888 printf("Time: %2i:%02i:%02i VOBU Sector: 0x%08x %s\n",
889 ac_time / (60 * 60), (ac_time / 60) % 60, ac_time % 60,
890 vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
891 (vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "");
892 }
893 }
894 }
895
896 void ifo_print_C_ADT(c_adt_t *c_adt) {
897 int i, entries;
898
899 printf("Number of VOBs in this VOBS: %i\n", c_adt->nr_of_vobs);
900 //entries = c_adt->nr_of_vobs;
901 entries = (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(c_adt_t);
902
903 for(i = 0; i < entries; i++) {
904 printf("VOB ID: %3i, Cell ID: %3i ",
905 c_adt->cell_adr_table[i].vob_id, c_adt->cell_adr_table[i].cell_id);
906 printf("Sector (first): 0x%08x (last): 0x%08x\n",
907 c_adt->cell_adr_table[i].start_sector,
908 c_adt->cell_adr_table[i].last_sector);
909 }
910 }
911
912
913 void ifo_print_VOBU_ADMAP(vobu_admap_t *vobu_admap) {
914 int i, entries;
915
916 entries = (vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4;
917 for(i = 0; i < entries; i++) {
918 printf("VOBU %5i First sector: 0x%08x\n", i + 1,
919 vobu_admap->vobu_start_sectors[i]);
920 }
921 }
922
923 const char *ifo_print_menu_name(int type) {
924 const char *menu_name;
925 menu_name="";
926 switch (type) {
927 case 2:
928 menu_name="Title";
929 break;
930 case 3:
931 menu_name = "Root";
932 break;
933 case 4:
934 menu_name = "Sub-Picture";
935 break;
936 case 5:
937 menu_name = "Audio";
938 break;
939 case 6:
940 menu_name = "Angle";
941 break;
942 case 7:
943 menu_name = "PTT (Chapter)";
944 break;
945 default:
946 menu_name = "Unknown";
947 break;
948 }
949 return &menu_name[0];
950 }
951
952 /* pgc_type=1 for menu, 0 for title. */
953 void ifo_print_PGCIT(pgcit_t *pgcit, int pgc_type) {
954 int i;
955
956 printf("\nNumber of Program Chains: %3i\n", pgcit->nr_of_pgci_srp);
957 for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
958 printf("\nProgram (PGC): %3i\n", i + 1);
959 if (pgc_type) {
960 printf("PGC Category: Entry PGC %d, Menu Type=0x%02x:%s (Entry id 0x%02x), ",
961 pgcit->pgci_srp[i].entry_id >> 7,
962 pgcit->pgci_srp[i].entry_id & 0xf,
963 ifo_print_menu_name(pgcit->pgci_srp[i].entry_id & 0xf),
964 pgcit->pgci_srp[i].entry_id);
965 } else {
966 printf("PGC Category: %s VTS_TTN:0x%02x (Entry id 0x%02x), ",
967 pgcit->pgci_srp[i].entry_id >> 7 ? "At Start of" : "During",
968 pgcit->pgci_srp[i].entry_id & 0xf,
969 pgcit->pgci_srp[i].entry_id);
970 }
971 printf("Parental ID mask 0x%04x\n", pgcit->pgci_srp[i].ptl_id_mask);
972 ifo_print_PGC(pgcit->pgci_srp[i].pgc);
973 }
974 }
975
976
977 void ifo_print_PGCI_UT(pgci_ut_t *pgci_ut) {
978 int i, menu;
979
980 printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_of_lus);
981 for(i = 0; i < pgci_ut->nr_of_lus; i++) {
982 printf("\nMenu Language Unit %d\n", i+1);
983 printf("\nMenu Language Code: %c%c\n",
984 pgci_ut->lu[i].lang_code >> 8,
985 pgci_ut->lu[i].lang_code & 0xff);
986
987 menu = pgci_ut->lu[i].exists;
988 printf("Menu Existence: %02x: ", menu);
989 if (menu == 0) {
990 printf("No menus ");
991 }
992 if (menu & 0x80) {
993 printf("Root ");
994 menu^=0x80;
995 }
996 if (menu & 0x40) {
997 printf("Sub-Picture ");
998 menu^=0x40;
999 }
1000 if (menu & 0x20) {
1001 printf("Audio ");
1002 menu^=0x20;
1003 }
1004 if (menu & 0x10) {
1005 printf("Angle ");
1006 menu^=0x10;
1007 }
1008 if (menu & 0x08) {
1009 printf("PTT ");
1010 menu^=0x08;
1011 }
1012 if (menu > 0) {
1013 printf("Unknown extra menus ");
1014 menu^=0x08;
1015 }
1016 printf("\n");
1017 ifo_print_PGCIT(pgci_ut->lu[i].pgcit, 1);
1018 }
1019 }
1020
1021
1022 static void ifo_print_VTS_ATTRIBUTES(vts_attributes_t *vts_attributes) {
1023 int i;
1024
1025 printf("VTS_CAT Application type: %08x\n", vts_attributes->vts_cat);
1026
1027 printf("Video attributes of VTSM_VOBS: ");
1028 ifo_print_video_attributes(5, &vts_attributes->vtsm_vobs_attr);
1029 printf("\n");
1030 printf("Number of Audio streams: %i\n",
1031 vts_attributes->nr_of_vtsm_audio_streams);
1032 if(vts_attributes->nr_of_vtsm_audio_streams > 0) {
1033 printf("\tstream %i attributes: ", 1);
1034 ifo_print_audio_attributes(5, &vts_attributes->vtsm_audio_attr);
1035 printf("\n");
1036 }
1037 printf("Number of Subpicture streams: %i\n",
1038 vts_attributes->nr_of_vtsm_subp_streams);
1039 if(vts_attributes->nr_of_vtsm_subp_streams > 0) {
1040 printf("\tstream %2i attributes: ", 1);
1041 ifo_print_subp_attributes(5, &vts_attributes->vtsm_subp_attr);
1042 printf("\n");
1043 }
1044
1045 printf("Video attributes of VTSTT_VOBS: ");
1046 ifo_print_video_attributes(5, &vts_attributes->vtstt_vobs_video_attr);
1047 printf("\n");
1048 printf("Number of Audio streams: %i\n",
1049 vts_attributes->nr_of_vtstt_audio_streams);
1050 for(i = 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) {
1051 printf("\tstream %i attributes: ", i);
1052 ifo_print_audio_attributes(5, &vts_attributes->vtstt_audio_attr[i]);
1053 printf("\n");
1054 }
1055
1056 printf("Number of Subpicture streams: %i\n",
1057 vts_attributes->nr_of_vtstt_subp_streams);
1058 for(i = 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) {
1059 printf("\tstream %2i attributes: ", i);
1060 ifo_print_subp_attributes(5, &vts_attributes->vtstt_subp_attr[i]);
1061 printf("\n");
1062 }
1063 }
1064
1065
1066 void ifo_print_VTS_ATRT(vts_atrt_t *vts_atrt) {
1067 int i;
1068
1069 printf("Number of Video Title Sets: %3i\n", vts_atrt->nr_of_vtss);
1070 for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
1071 printf("\nVideo Title Set %i\n", i + 1);
1072 ifo_print_VTS_ATTRIBUTES(&vts_atrt->vts[i]);
1073 }
1074 }
1075
1076
1077 void ifo_print(dvd_reader_t *dvd, int title) {
1078 ifo_handle_t *ifohandle;
1079 printf("Local ifo_print\n");
1080 ifohandle = ifoOpen(dvd, title);
1081 if(!ifohandle) {
1082 fprintf(stderr, "Can't open info file for title %d\n", title);
1083 return;
1084 }
1085
1086
1087 if(ifohandle->vmgi_mat) {
1088
1089 printf("VMG top level\n-------------\n");
1090 ifo_print_VMGI_MAT(ifohandle->vmgi_mat);
1091
1092 printf("\nFirst Play PGC\n--------------\n");
1093 if(ifohandle->first_play_pgc)
1094 ifo_print_PGC(ifohandle->first_play_pgc);
1095 else
1096 printf("No First Play PGC present\n");
1097
1098 printf("\nTitle Track search pointer table\n");
1099 printf( "------------------------------------------------\n");
1100 ifo_print_TT_SRPT(ifohandle->tt_srpt);
1101
1102 printf("\nMenu PGCI Unit table\n");
1103 printf( "--------------------\n");
1104 if(ifohandle->pgci_ut) {
1105 ifo_print_PGCI_UT(ifohandle->pgci_ut);
1106 } else {
1107 printf("No PGCI Unit table present\n");
1108 }
1109
1110 printf("\nParental Manegment Information table\n");
1111 printf( "------------------------------------\n");
1112 if(ifohandle->ptl_mait) {
1113 ifo_print_PTL_MAIT(ifohandle->ptl_mait);
1114 } else {
1115 printf("No Parental Management Information present\n");
1116 }
1117
1118 printf("\nVideo Title Set Attribute Table\n");
1119 printf( "-------------------------------\n");
1120 ifo_print_VTS_ATRT(ifohandle->vts_atrt);
1121
1122 printf("\nText Data Manager Information\n");
1123 printf( "-----------------------------\n");
1124 if(ifohandle->txtdt_mgi) {
1125 //ifo_print_TXTDT_MGI(&(vmgi->txtdt_mgi));
1126 } else {
1127 printf("No Text Data Manager Information present\n");
1128 }
1129
1130 printf("\nMenu Cell Adress table\n");
1131 printf( "-----------------\n");
1132 if(ifohandle->menu_c_adt) {
1133 ifo_print_C_ADT(ifohandle->menu_c_adt);
1134 } else {
1135 printf("No Menu Cell Adress table present\n");
1136 }
1137
1138 printf("\nVideo Manager Menu VOBU address map\n");
1139 printf( "-----------------\n");
1140 if(ifohandle->menu_vobu_admap) {
1141 ifo_print_VOBU_ADMAP(ifohandle->menu_vobu_admap);
1142 } else {
1143 printf("No Menu VOBU address map present\n");
1144 }
1145 }
1146
1147
1148 if(ifohandle->vtsi_mat) {
1149
1150 printf("VTS top level\n-------------\n");
1151 ifo_print_VTSI_MAT(ifohandle->vtsi_mat);
1152
1153 printf("\nPart of Title Track search pointer table\n");
1154 printf( "----------------------------------------------\n");
1155 ifo_print_VTS_PTT_SRPT(ifohandle->vts_ptt_srpt);
1156
1157 printf("\nPGCI Unit table\n");
1158 printf( "--------------------\n");
1159 ifo_print_PGCIT(ifohandle->vts_pgcit, 0);
1160
1161 printf("\nMenu PGCI Unit table\n");
1162 printf( "--------------------\n");
1163 if(ifohandle->pgci_ut) {
1164 ifo_print_PGCI_UT(ifohandle->pgci_ut);
1165 } else {
1166 printf("No Menu PGCI Unit table present\n");
1167 }
1168
1169 printf("\nVTS Time Map table\n");
1170 printf( "-----------------\n");
1171 if(ifohandle->vts_tmapt) {
1172 ifo_print_VTS_TMAPT(ifohandle->vts_tmapt);
1173 } else {
1174 printf("No VTS Time Map table present\n");
1175 }
1176
1177 printf("\nMenu Cell Adress table\n");
1178 printf( "-----------------\n");
1179 if(ifohandle->menu_c_adt) {
1180 ifo_print_C_ADT(ifohandle->menu_c_adt);
1181 } else {
1182 printf("No Cell Adress table present\n");
1183 }
1184
1185 printf("\nVideo Title Set Menu VOBU address map\n");
1186 printf( "-----------------\n");
1187 if(ifohandle->menu_vobu_admap) {
1188 ifo_print_VOBU_ADMAP(ifohandle->menu_vobu_admap);
1189 } else {
1190 printf("No Menu VOBU address map present\n");
1191 }
1192
1193 printf("\nCell Adress table\n");
1194 printf( "-----------------\n");
1195 ifo_print_C_ADT(ifohandle->vts_c_adt);
1196
1197 printf("\nVideo Title Set VOBU address map\n");
1198 printf( "-----------------\n");
1199 ifo_print_VOBU_ADMAP(ifohandle->vts_vobu_admap);
1200 }
1201
1202 ifoClose(ifohandle);
1203 }
1204
1205 /*
1206 * $Log$
1207 * Revision 1.3 2004/10/22 11:36:19 jcdutton
1208 * Stop seg fault when using ifo_dump.
1209 *
1210 * Revision 1.2 2004/09/27 12:24:01 jcdutton
1211 * Add extra info to printout when using ifo_dump.
1212 *
1213 * Revision 1.1 2004/01/11 21:43:13 mroi
1214 * big build system changes
1215 * * cleaned up all Makefiles and added a Makefile.common
1216 * * added relchk script
1217 * * moved libdvdread files to a dvdread subdir
1218 * * moved DVD VM to a vm subdir
1219 * * removed unused code in read_cache.c
1220 *
1221 * Revision 1.4 2004/01/01 15:13:13 jcdutton
1222 * Put ifo_print.c and .h back in.
1223 *
1224 * Revision 1.7 2003/04/28 15:17:17 jcdutton
1225 * Update ifodump to work with new libdvdnav cvs, instead of needing libdvdread.
1226 *
1227 * Revision 1.6 2003/04/05 22:49:04 jcdutton
1228 * Update with more info from the latest libdvdread.
1229 *
1230 * Revision 1.5 2003/04/05 13:03:49 jcdutton
1231 * Small updates.
1232 *
1233 * Revision 1.4 2003/04/01 08:01:03 jcdutton
1234 * Add VTS Time map display. Requires libdvdread 0.9.4. The same version that comes with xine.
1235 *
1236 * Revision 1.3 2003/03/14 15:49:18 mroi
1237 * adjust to new libdvdread version
1238 *
1239 * Revision 1.2 2002/08/30 05:12:33 jcdutton
1240 * Minor update now that I know what PGC Entry IDs are for.
1241 *
1242 * Revision 1.1.1.1 2002/08/28 09:48:35 jcdutton
1243 * Initial import into CVS.
1244 *
1245 *
1246 *
1247 */
1248