comparison menus.c @ 2:399518436fcf

fix tabbing
author paulo@thepaulopc
date Fri, 13 Nov 2009 00:02:37 -0800
parents cfe5048cc182
children ffbf478b80c2
comparison
equal deleted inserted replaced
1:f14c340e1864 2:516c64130cf8
43 #ifdef WIN32 43 #ifdef WIN32
44 #define S_IRWXG 0 44 #define S_IRWXG 0
45 #endif 45 #endif
46 46
47 int main(int argc, char **argv) { 47 int main(int argc, char **argv) {
48 dvdnav_t *dvdnav; 48 dvdnav_t *dvdnav;
49 uint8_t mem[DVD_VIDEO_LB_LEN]; 49 uint8_t mem[DVD_VIDEO_LB_LEN];
50 int finished = 0; 50 int finished = 0;
51 int output_fd = 0; 51 int output_fd = 0;
52 int dump = 0, tt_dump = 0, tt_skip = 0; 52 int dump = 0, tt_dump = 0, tt_skip = 0;
53 53
54 /* open dvdnav handle */ 54 /* open dvdnav handle */
55 printf("Opening DVD...\n"); 55 printf("Opening DVD...\n");
56 if (dvdnav_open(&dvdnav, "/dev/dvd") != DVDNAV_STATUS_OK) { 56 if (dvdnav_open(&dvdnav, "/dev/dvd") != DVDNAV_STATUS_OK) {
57 printf("Error on dvdnav_open\n"); 57 printf("Error on dvdnav_open\n");
58 return 1; 58 return 1;
59 } 59 }
60 60
61 /* set read ahead cache usage */ 61 /* set read ahead cache usage */
62 if (dvdnav_set_readahead_flag(dvdnav, DVD_READ_CACHE) != DVDNAV_STATUS_OK) { 62 if (dvdnav_set_readahead_flag(dvdnav, DVD_READ_CACHE) != DVDNAV_STATUS_OK) {
63 printf("Error on dvdnav_set_readahead_flag: %s\n", dvdnav_err_to_string(dvdnav)); 63 printf("Error on dvdnav_set_readahead_flag: %s\n", dvdnav_err_to_string(dvdnav));
64 return 2; 64 return 2;
65 } 65 }
66 66
67 /* set the language */ 67 /* set the language */
68 if (dvdnav_menu_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK || 68 if (dvdnav_menu_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK ||
69 dvdnav_audio_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK || 69 dvdnav_audio_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK ||
70 dvdnav_spu_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK) { 70 dvdnav_spu_language_select(dvdnav, DVD_LANGUAGE) != DVDNAV_STATUS_OK) {
71 printf("Error on setting languages: %s\n", dvdnav_err_to_string(dvdnav)); 71 printf("Error on setting languages: %s\n", dvdnav_err_to_string(dvdnav));
72 return 2; 72 return 2;
73 } 73 }
74 74
75 /* set the PGC positioning flag to have position information relatively to the 75 /* set the PGC positioning flag to have position information relatively to the
76 * whole feature instead of just relatively to the current chapter */ 76 * whole feature instead of just relatively to the current chapter */
77 if (dvdnav_set_PGC_positioning_flag(dvdnav, 1) != DVDNAV_STATUS_OK) { 77 if (dvdnav_set_PGC_positioning_flag(dvdnav, 1) != DVDNAV_STATUS_OK) {
78 printf("Error on dvdnav_set_PGC_positioning_flag: %s\n", dvdnav_err_to_string(dvdnav)); 78 printf("Error on dvdnav_set_PGC_positioning_flag: %s\n", dvdnav_err_to_string(dvdnav));
79 return 2; 79 return 2;
80 } 80 }
81 81
82 82
83 /* the read loop which regularly calls dvdnav_get_next_block 83 /* the read loop which regularly calls dvdnav_get_next_block
84 * and handles the returned events */ 84 * and handles the returned events */
85 printf("Reading...\n"); 85 printf("Reading...\n");
86 while (!finished) { 86 while (!finished) {
87 int result, event, len; 87 int result, event, len;
88 uint8_t *buf = mem; 88 uint8_t *buf = mem;
89 89
90 /* the main reading function */ 90 /* the main reading function */
91 #if DVD_READ_CACHE 91 #if DVD_READ_CACHE
92 result = dvdnav_get_next_cache_block(dvdnav, &buf, &event, &len); 92 result = dvdnav_get_next_cache_block(dvdnav, &buf, &event, &len);
93 #else 93 #else
94 result = dvdnav_get_next_block(dvdnav, buf, &event, &len); 94 result = dvdnav_get_next_block(dvdnav, buf, &event, &len);
95 #endif 95 #endif
96 96
97 if (result == DVDNAV_STATUS_ERR) { 97 if (result == DVDNAV_STATUS_ERR) {
98 printf("Error getting next block: %s\n", dvdnav_err_to_string(dvdnav)); 98 printf("Error getting next block: %s\n", dvdnav_err_to_string(dvdnav));
99 return 3; 99 return 3;
100 } 100 }
101 101
102 switch (event) { 102 switch (event) {
103 case DVDNAV_BLOCK_OK: 103 case DVDNAV_BLOCK_OK:
104 /* We have received a regular block of the currently playing MPEG stream. 104 /* We have received a regular block of the currently playing MPEG stream.
105 * A real player application would now pass this block through demuxing 105 * A real player application would now pass this block through demuxing
106 * and decoding. We simply write it to disc here. */ 106 * and decoding. We simply write it to disc here. */
107 107
108 if (!output_fd && (dump || tt_dump)) { 108 if (!output_fd && (dump || tt_dump)) {
109 printf("Opening output...\n"); 109 printf("Opening output...\n");
110 output_fd = open("libdvdnav.mpg", O_CREAT | O_WRONLY | O_APPEND, S_IRWXU | S_IRWXG); 110 output_fd = open("libdvdnav.mpg", O_CREAT | O_WRONLY | O_APPEND, S_IRWXU | S_IRWXG);
111 if (output_fd == -1) { 111 if (output_fd == -1) {
112 printf("Error opening output\n"); 112 printf("Error opening output\n");
113 return 4; 113 return 4;
114 } 114 }
115 } 115 }
116 116
117 if (dump || tt_dump) 117 if (dump || tt_dump)
118 write(output_fd, buf, len); 118 write(output_fd, buf, len);
119 119
120 break; 120 break;
121 case DVDNAV_NOP: 121 case DVDNAV_NOP:
122 /* Nothing to do here. */ 122 /* Nothing to do here. */
123 break; 123 break;
124 case DVDNAV_STILL_FRAME: 124 case DVDNAV_STILL_FRAME:
125 /* We have reached a still frame. A real player application would wait 125 /* We have reached a still frame. A real player application would wait
126 * the amount of time specified by the still's length while still handling 126 * the amount of time specified by the still's length while still handling
127 * user input to make menus and other interactive stills work. 127 * user input to make menus and other interactive stills work.
128 * A length of 0xff means an indefinite still which has to be skipped 128 * A length of 0xff means an indefinite still which has to be skipped
129 * indirectly by some user interaction. */ 129 * indirectly by some user interaction. */
130 { 130 dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)buf;
131 dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)buf; 131 if (still_event->length < 0xff)
132 if (still_event->length < 0xff) 132 printf("Skipping %d seconds of still frame\n", still_event->length);
133 printf("Skipping %d seconds of still frame\n", still_event->length); 133 else
134 else 134 printf("Skipping indefinite length still frame\n");
135 printf("Skipping indefinite length still frame\n"); 135 dvdnav_still_skip(dvdnav);
136 dvdnav_still_skip(dvdnav); 136 break;
137 } 137 case DVDNAV_WAIT:
138 break; 138 /* We have reached a point in DVD playback, where timing is critical.
139 case DVDNAV_WAIT: 139 * Player application with internal fifos can introduce state
140 /* We have reached a point in DVD playback, where timing is critical. 140 * inconsistencies, because libdvdnav is always the fifo's length
141 * Player application with internal fifos can introduce state 141 * ahead in the stream compared to what the application sees.
142 * inconsistencies, because libdvdnav is always the fifo's length 142 * Such applications should wait until their fifos are empty
143 * ahead in the stream compared to what the application sees. 143 * when they receive this type of event. */
144 * Such applications should wait until their fifos are empty 144 printf("Skipping wait condition\n");
145 * when they receive this type of event. */ 145 dvdnav_wait_skip(dvdnav);
146 printf("Skipping wait condition\n"); 146 break;
147 dvdnav_wait_skip(dvdnav); 147 case DVDNAV_SPU_CLUT_CHANGE:
148 break; 148 /* Player applications should pass the new colour lookup table to their
149 case DVDNAV_SPU_CLUT_CHANGE: 149 * SPU decoder */
150 /* Player applications should pass the new colour lookup table to their 150 break;
151 * SPU decoder */ 151 case DVDNAV_SPU_STREAM_CHANGE:
152 break; 152 /* Player applications should inform their SPU decoder to switch channels */
153 case DVDNAV_SPU_STREAM_CHANGE: 153 break;
154 /* Player applications should inform their SPU decoder to switch channels */ 154 case DVDNAV_AUDIO_STREAM_CHANGE:
155 break; 155 /* Player applications should inform their audio decoder to switch channels */
156 case DVDNAV_AUDIO_STREAM_CHANGE: 156 break;
157 /* Player applications should inform their audio decoder to switch channels */ 157 case DVDNAV_HIGHLIGHT:
158 break; 158 /* Player applications should inform their overlay engine to highlight the
159 case DVDNAV_HIGHLIGHT: 159 * given button */
160 /* Player applications should inform their overlay engine to highlight the 160 dvdnav_highlight_event_t *highlight_event = (dvdnav_highlight_event_t *)buf;
161 * given button */ 161 printf("Selected button %d\n", highlight_event->buttonN);
162 { 162 break;
163 dvdnav_highlight_event_t *highlight_event = (dvdnav_highlight_event_t *)buf; 163 case DVDNAV_VTS_CHANGE:
164 printf("Selected button %d\n", highlight_event->buttonN); 164 /* Some status information like video aspect and video scale permissions do
165 } 165 * not change inside a VTS. Therefore this event can be used to query such
166 break; 166 * information only when necessary and update the decoding/displaying
167 case DVDNAV_VTS_CHANGE: 167 * accordingly. */
168 /* Some status information like video aspect and video scale permissions do 168 break;
169 * not change inside a VTS. Therefore this event can be used to query such 169 case DVDNAV_CELL_CHANGE:
170 * information only when necessary and update the decoding/displaying 170 /* Some status information like the current Title and Part numbers do not
171 * accordingly. */ 171 * change inside a cell. Therefore this event can be used to query such
172 break; 172 * information only when necessary and update the decoding/displaying
173 case DVDNAV_CELL_CHANGE: 173 * accordingly. */
174 /* Some status information like the current Title and Part numbers do not 174 {
175 * change inside a cell. Therefore this event can be used to query such 175 int32_t tt = 0, ptt = 0;
176 * information only when necessary and update the decoding/displaying 176 uint32_t pos, len;
177 * accordingly. */ 177 char input = '\0';
178 { 178
179 int32_t tt = 0, ptt = 0; 179 dvdnav_current_title_info(dvdnav, &tt, &ptt);
180 uint32_t pos, len; 180 dvdnav_get_position(dvdnav, &pos, &len);
181 char input = '\0'; 181 printf("Cell change: Title %d, Chapter %d\n", tt, ptt);
182 182 printf("At position %.0f%% inside the feature\n", 100 * (double)pos / (double)len);
183 dvdnav_current_title_info(dvdnav, &tt, &ptt); 183
184 dvdnav_get_position(dvdnav, &pos, &len); 184 dump = 0;
185 printf("Cell change: Title %d, Chapter %d\n", tt, ptt); 185 if (tt_dump && tt != tt_dump)
186 printf("At position %.0f%% inside the feature\n", 100 * (double)pos / (double)len); 186 tt_dump = 0;
187 187
188 dump = 0; 188 if (tt_skip && tt != tt_skip)
189 if (tt_dump && tt != tt_dump) 189 tt_skip = 0;
190 tt_dump = 0; 190
191 191 if (output_fd && !tt_dump) {
192 if (tt_skip && tt != tt_skip) 192 printf("Closing output...\n");
193 tt_skip = 0; 193 output_fd = close(output_fd);
194 194 }
195 if (output_fd && !tt_dump) { 195
196 printf("Closing output...\n"); 196 if (!dump && !tt_dump && !tt_skip) {
197 output_fd = close(output_fd); 197 fflush(stdin);
198 } 198 while ((input != 'a') && (input != 's') && (input != 'q') && (input != 't') && (input != 'l')) {
199 199 printf("(a)ppend cell to output\n(s)kip cell\nappend until end of (t)itle\nskip tit(l)e\n(q)uit\n");
200 if (!dump && !tt_dump && !tt_skip) { 200 scanf("%c", &input);
201 fflush(stdin); 201 }
202 while ((input != 'a') && (input != 's') && (input != 'q') && (input != 't') && (input != 'l')) { 202
203 printf("(a)ppend cell to output\n(s)kip cell\nappend until end of (t)itle\nskip tit(l)e\n(q)uit\n"); 203 switch (input) {
204 scanf("%c", &input); 204 case 'a':
205 } 205 dump = 1;
206 206 break;
207 switch (input) { 207 case 't':
208 case 'a': 208 tt_dump = tt;
209 dump = 1; 209 break;
210 break; 210 case 'l':
211 case 't': 211 tt_skip = tt;
212 tt_dump = tt; 212 break;
213 break; 213 case 'q':
214 case 'l': 214 finished = 1;
215 tt_skip = tt; 215 }
216 break; 216 }
217 case 'q': 217 }
218 finished = 1; 218 break;
219 } 219 case DVDNAV_NAV_PACKET:
220 } 220 /* A NAV packet provides PTS discontinuity information, angle linking information and
221 } 221 * button definitions for DVD menus. Angles are handled completely inside libdvdnav.
222 break; 222 * For the menus to work, the NAV packet information has to be passed to the overlay
223 case DVDNAV_NAV_PACKET: 223 * engine of the player so that it knows the dimensions of the button areas. */
224 /* A NAV packet provides PTS discontinuity information, angle linking information and 224 {
225 * button definitions for DVD menus. Angles are handled completely inside libdvdnav. 225 pci_t *pci;
226 * For the menus to work, the NAV packet information has to be passed to the overlay 226
227 * engine of the player so that it knows the dimensions of the button areas. */ 227 /* Applications with fifos should not use these functions to retrieve NAV packets,
228 { 228 * they should implement their own NAV handling, because the packet you get from these
229 pci_t *pci; 229 * functions will already be ahead in the stream which can cause state inconsistencies.
230 230 * Applications with fifos should therefore pass the NAV packet through the fifo
231 /* Applications with fifos should not use these functions to retrieve NAV packets, 231 * and decoding pipeline just like any other data. */
232 * they should implement their own NAV handling, because the packet you get from these 232 pci = dvdnav_get_current_nav_pci(dvdnav);
233 * functions will already be ahead in the stream which can cause state inconsistencies. 233 dvdnav_get_current_nav_dsi(dvdnav);
234 * Applications with fifos should therefore pass the NAV packet through the fifo 234
235 * and decoding pipeline just like any other data. */ 235 if(pci->hli.hl_gi.btn_ns > 0) {
236 pci = dvdnav_get_current_nav_pci(dvdnav); 236 int button;
237 dvdnav_get_current_nav_dsi(dvdnav); 237
238 238 printf("Found %i DVD menu buttons...\n", pci->hli.hl_gi.btn_ns);
239 if(pci->hli.hl_gi.btn_ns > 0) { 239
240 int button; 240 for (button = 0; button < pci->hli.hl_gi.btn_ns; button++) {
241 241 btni_t *btni = &(pci->hli.btnit[button]);
242 printf("Found %i DVD menu buttons...\n", pci->hli.hl_gi.btn_ns); 242 printf("Button %i top-left @ (%i,%i), bottom-right @ (%i,%i)\n",
243 243 button + 1, btni->x_start, btni->y_start,
244 for (button = 0; button < pci->hli.hl_gi.btn_ns; button++) { 244 btni->x_end, btni->y_end);
245 btni_t *btni = &(pci->hli.btnit[button]); 245 }
246 printf("Button %i top-left @ (%i,%i), bottom-right @ (%i,%i)\n", 246
247 button + 1, btni->x_start, btni->y_start, 247 button = 0;
248 btni->x_end, btni->y_end); 248 while ((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
249 } 249 printf("Which button (1 to %i): ", pci->hli.hl_gi.btn_ns);
250 250 scanf("%i", &button);
251 button = 0; 251 }
252 while ((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) { 252
253 printf("Which button (1 to %i): ", pci->hli.hl_gi.btn_ns); 253 printf("Selecting button %i...\n", button);
254 scanf("%i", &button); 254 /* This is the point where applications with fifos have to hand in a NAV packet
255 } 255 * which has traveled through the fifos. See the notes above. */
256 256 dvdnav_button_select_and_activate(dvdnav, pci, button);
257 printf("Selecting button %i...\n", button); 257 }
258 /* This is the point where applications with fifos have to hand in a NAV packet 258 }
259 * which has traveled through the fifos. See the notes above. */ 259 break;
260 dvdnav_button_select_and_activate(dvdnav, pci, button); 260 case DVDNAV_HOP_CHANNEL:
261 } 261 /* This event is issued whenever a non-seamless operation has been executed.
262 } 262 * Applications with fifos should drop the fifos content to speed up responsiveness. */
263 break; 263 break;
264 case DVDNAV_HOP_CHANNEL: 264 case DVDNAV_STOP:
265 /* This event is issued whenever a non-seamless operation has been executed. 265 /* Playback should end here. */
266 * Applications with fifos should drop the fifos content to speed up responsiveness. */ 266 finished = 1;
267 break; 267 break;
268 case DVDNAV_STOP: 268 default:
269 /* Playback should end here. */ 269 printf("Unknown event (%i)\n", event);
270 { 270 finished = 1;
271 finished = 1; 271 break;
272 } 272 }
273 break;
274 default:
275 printf("Unknown event (%i)\n", event);
276 finished = 1;
277 break;
278 }
279 #if DVD_READ_CACHE 273 #if DVD_READ_CACHE
280 dvdnav_free_cache_block(dvdnav, buf); 274 dvdnav_free_cache_block(dvdnav, buf);
281 #endif 275 #endif
282 } 276 }
283 277
284 /* destroy dvdnav handle */ 278 /* destroy dvdnav handle */
285 if (dvdnav_close(dvdnav) != DVDNAV_STATUS_OK) { 279 if (dvdnav_close(dvdnav) != DVDNAV_STATUS_OK) {
286 printf("Error on dvdnav_close: %s\n", dvdnav_err_to_string(dvdnav)); 280 printf("Error on dvdnav_close: %s\n", dvdnav_err_to_string(dvdnav));
287 return 5; 281 return 5;
288 } 282 }
289 close(output_fd); 283 close(output_fd);
290 284
291 return 0; 285 return 0;
292 } 286 }