Mercurial > libdvdnav.hg
annotate dvdread/nav_read.c @ 249:5d643668f1e3 src
I added this code myself a long time ago, but now I am quite convinced that
it is wrong: Why would we filter out SPU stream change events that switch
SPUs off? This breaks watching the trailer on the RC2 of "Girl, interrupted",
because you always get unwanted subtitles.
When I added this code, it fixed a problem with the RC2 of "Terminator", but
I cannot reproduce this problem any more. Back then, the menu highlights would
not show up, but they do now. I assume the problem really got fixed with proper
support for forced subtitles in xine, so this crappy workaround here can go
away.
After all, this way it is more symmetric to audio stream change events,
because these are not filtered.
author | mroi |
---|---|
date | Sun, 12 Sep 2004 15:12:43 +0000 |
parents | e75c52894630 |
children | a5319a5c34f4 |
rev | line source |
---|---|
225 | 1 /* |
2 * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort@dtek.chalmers.se> | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * This program is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with this program; if not, write to the Free Software | |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 */ | |
18 | |
19 #include "config.h" | |
20 | |
21 #include <stdio.h> | |
243
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
22 #include <stdlib.h> |
225 | 23 #include <string.h> |
24 #include <inttypes.h> | |
25 | |
26 #include "bswap.h" | |
27 #include "nav_types.h" | |
28 #include "nav_read.h" | |
29 #include "dvdread_internal.h" | |
30 | |
31 typedef struct { | |
32 uint8_t *start; | |
33 uint32_t byte_position; | |
34 uint32_t bit_position; | |
35 uint8_t byte; | |
36 } getbits_state_t; | |
37 | |
243
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
38 static int getbits_init(getbits_state_t *state, uint8_t *start) { |
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
39 if ((state == NULL) || (start == NULL)) return 0; |
225 | 40 state->start = start; |
41 state->bit_position = 0; | |
42 state->byte_position = 0; | |
43 state->byte = start[0]; | |
243
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
44 return 1; |
225 | 45 } |
46 | |
47 /* Non-optimized getbits. */ | |
48 /* This can easily be optimized for particular platforms. */ | |
49 static uint32_t getbits(getbits_state_t *state, uint32_t number_of_bits) { | |
50 uint32_t result=0; | |
51 uint8_t byte=0; | |
52 if (number_of_bits > 32) { | |
53 printf("Number of bits > 32 in getbits\n"); | |
243
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
54 abort(); |
225 | 55 } |
56 | |
57 if ((state->bit_position) > 0) { /* Last getbits left us in the middle of a byte. */ | |
58 if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */ | |
59 byte = state->byte; | |
60 byte = byte >> (state->bit_position); | |
61 result = byte; | |
62 number_of_bits -= (8-state->bit_position); | |
63 state->bit_position = 0; | |
64 state->byte_position++; | |
65 state->byte = state->start[state->byte_position]; | |
66 } else { | |
67 byte=state->byte; | |
68 state->byte = state->byte << number_of_bits; | |
69 byte = byte >> (8 - number_of_bits); | |
70 result = byte; | |
71 state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */ | |
72 if (state->bit_position == 8) { | |
73 state->bit_position = 0; | |
74 state->byte_position++; | |
75 state->byte = state->start[state->byte_position]; | |
76 } | |
77 number_of_bits = 0; | |
78 } | |
79 } | |
240
585e0f683973
nesting and indentation do not match, but I think the braces do not actually
mroi
parents:
225
diff
changeset
|
80 if ((state->bit_position) == 0) { |
225 | 81 while (number_of_bits > 7) { |
82 result = (result << 8) + state->byte; | |
83 state->byte_position++; | |
84 state->byte = state->start[state->byte_position]; | |
85 number_of_bits -= 8; | |
86 } | |
87 if (number_of_bits > 0) { /* number_of_bits < 8 */ | |
88 byte = state->byte; | |
89 state->byte = state->byte << number_of_bits; | |
90 state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */ | |
91 byte = byte >> (8 - number_of_bits); | |
92 result = (result << number_of_bits) + byte; | |
93 number_of_bits = 0; | |
94 } | |
240
585e0f683973
nesting and indentation do not match, but I think the braces do not actually
mroi
parents:
225
diff
changeset
|
95 } |
225 | 96 |
97 return result; | |
98 } | |
99 | |
100 #if 0 /* TODO: optimized versions not yet used */ | |
101 | |
102 /* WARNING: This function can only be used on a byte boundary. | |
103 No checks are made that we are in fact on a byte boundary. | |
104 */ | |
105 static uint16_t get16bits(getbits_state_t *state) { | |
106 uint16_t result; | |
107 state->byte_position++; | |
108 result = (state->byte << 8) + state->start[state->byte_position++]; | |
109 state->byte = state->start[state->byte_position]; | |
110 return result; | |
111 } | |
112 | |
113 /* WARNING: This function can only be used on a byte boundary. | |
114 No checks are made that we are in fact on a byte boundary. | |
115 */ | |
116 static uint32_t get32bits(getbits_state_t *state) { | |
117 uint32_t result; | |
118 state->byte_position++; | |
119 result = (state->byte << 8) + state->start[state->byte_position++]; | |
120 result = (result << 8) + state->start[state->byte_position++]; | |
121 result = (result << 8) + state->start[state->byte_position++]; | |
122 state->byte = state->start[state->byte_position]; | |
123 return result; | |
124 } | |
125 | |
126 #endif | |
127 | |
128 void navRead_PCI(pci_t *pci, unsigned char *buffer) { | |
129 int32_t i, j; | |
130 getbits_state_t state; | |
243
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
131 if (!getbits_init(&state, buffer)) abort(); /* Passed NULL pointers */ |
225 | 132 |
133 /* pci pci_gi */ | |
134 pci->pci_gi.nv_pck_lbn = getbits(&state, 32 ); | |
135 pci->pci_gi.vobu_cat = getbits(&state, 16 ); | |
136 pci->pci_gi.zero1 = getbits(&state, 16 ); | |
137 pci->pci_gi.vobu_uop_ctl.zero = getbits(&state, 7 ); | |
138 pci->pci_gi.vobu_uop_ctl.video_pres_mode_change = getbits(&state, 1 ); | |
139 | |
140 pci->pci_gi.vobu_uop_ctl.karaoke_audio_pres_mode_change = getbits(&state, 1 ); | |
141 pci->pci_gi.vobu_uop_ctl.angle_change = getbits(&state, 1 ); | |
142 pci->pci_gi.vobu_uop_ctl.subpic_stream_change = getbits(&state, 1 ); | |
143 pci->pci_gi.vobu_uop_ctl.audio_stream_change = getbits(&state, 1 ); | |
144 pci->pci_gi.vobu_uop_ctl.pause_on = getbits(&state, 1 ); | |
145 pci->pci_gi.vobu_uop_ctl.still_off = getbits(&state, 1 ); | |
146 pci->pci_gi.vobu_uop_ctl.button_select_or_activate = getbits(&state, 1 ); | |
147 pci->pci_gi.vobu_uop_ctl.resume = getbits(&state, 1 ); | |
148 | |
149 pci->pci_gi.vobu_uop_ctl.chapter_menu_call = getbits(&state, 1 ); | |
150 pci->pci_gi.vobu_uop_ctl.angle_menu_call = getbits(&state, 1 ); | |
151 pci->pci_gi.vobu_uop_ctl.audio_menu_call = getbits(&state, 1 ); | |
152 pci->pci_gi.vobu_uop_ctl.subpic_menu_call = getbits(&state, 1 ); | |
153 pci->pci_gi.vobu_uop_ctl.root_menu_call = getbits(&state, 1 ); | |
154 pci->pci_gi.vobu_uop_ctl.title_menu_call = getbits(&state, 1 ); | |
155 pci->pci_gi.vobu_uop_ctl.backward_scan = getbits(&state, 1 ); | |
156 pci->pci_gi.vobu_uop_ctl.forward_scan = getbits(&state, 1 ); | |
157 | |
158 pci->pci_gi.vobu_uop_ctl.next_pg_search = getbits(&state, 1 ); | |
159 pci->pci_gi.vobu_uop_ctl.prev_or_top_pg_search = getbits(&state, 1 ); | |
160 pci->pci_gi.vobu_uop_ctl.time_or_chapter_search = getbits(&state, 1 ); | |
161 pci->pci_gi.vobu_uop_ctl.go_up = getbits(&state, 1 ); | |
162 pci->pci_gi.vobu_uop_ctl.stop = getbits(&state, 1 ); | |
163 pci->pci_gi.vobu_uop_ctl.title_play = getbits(&state, 1 ); | |
164 pci->pci_gi.vobu_uop_ctl.chapter_search_or_play = getbits(&state, 1 ); | |
165 pci->pci_gi.vobu_uop_ctl.title_or_time_play = getbits(&state, 1 ); | |
166 pci->pci_gi.vobu_s_ptm = getbits(&state, 32 ); | |
167 pci->pci_gi.vobu_e_ptm = getbits(&state, 32 ); | |
168 pci->pci_gi.vobu_se_e_ptm = getbits(&state, 32 ); | |
169 pci->pci_gi.e_eltm.hour = getbits(&state, 8 ); | |
170 pci->pci_gi.e_eltm.minute = getbits(&state, 8 ); | |
171 pci->pci_gi.e_eltm.second = getbits(&state, 8 ); | |
172 pci->pci_gi.e_eltm.frame_u = getbits(&state, 8 ); | |
173 for(i = 0; i < 32; i++) | |
174 pci->pci_gi.vobu_isrc[i] = getbits(&state, 8 ); | |
175 | |
176 /* pci nsml_agli */ | |
177 for(i = 0; i < 9; i++) | |
178 pci->nsml_agli.nsml_agl_dsta[i] = getbits(&state, 32 ); | |
179 | |
180 /* pci hli hli_gi */ | |
181 pci->hli.hl_gi.hli_ss = getbits(&state, 16 ); | |
182 pci->hli.hl_gi.hli_s_ptm = getbits(&state, 32 ); | |
183 pci->hli.hl_gi.hli_e_ptm = getbits(&state, 32 ); | |
184 pci->hli.hl_gi.btn_se_e_ptm = getbits(&state, 32 ); | |
185 pci->hli.hl_gi.zero1 = getbits(&state, 2 ); | |
186 pci->hli.hl_gi.btngr_ns = getbits(&state, 2 ); | |
187 pci->hli.hl_gi.zero2 = getbits(&state, 1 ); | |
188 pci->hli.hl_gi.btngr1_dsp_ty = getbits(&state, 3 ); | |
189 pci->hli.hl_gi.zero3 = getbits(&state, 1 ); | |
190 pci->hli.hl_gi.btngr2_dsp_ty = getbits(&state, 3 ); | |
191 pci->hli.hl_gi.zero4 = getbits(&state, 1 ); | |
192 pci->hli.hl_gi.btngr3_dsp_ty = getbits(&state, 3 ); | |
193 pci->hli.hl_gi.btn_ofn = getbits(&state, 8 ); | |
194 pci->hli.hl_gi.btn_ns = getbits(&state, 8 ); | |
195 pci->hli.hl_gi.nsl_btn_ns = getbits(&state, 8 ); | |
196 pci->hli.hl_gi.zero5 = getbits(&state, 8 ); | |
197 pci->hli.hl_gi.fosl_btnn = getbits(&state, 8 ); | |
198 pci->hli.hl_gi.foac_btnn = getbits(&state, 8 ); | |
199 | |
200 /* pci hli btn_colit */ | |
201 for(i = 0; i < 3; i++) | |
202 for(j = 0; j < 2; j++) | |
203 pci->hli.btn_colit.btn_coli[i][j] = getbits(&state, 32 ); | |
204 | |
205 /* NOTE: I've had to change the structure from the disk layout to get | |
206 * the packing to work with Sun's Forte C compiler. */ | |
207 | |
208 /* pci hli btni */ | |
209 for(i = 0; i < 36; i++) { | |
210 pci->hli.btnit[i].btn_coln = getbits(&state, 2 ); | |
211 pci->hli.btnit[i].x_start = getbits(&state, 10 ); | |
212 pci->hli.btnit[i].zero1 = getbits(&state, 2 ); | |
213 pci->hli.btnit[i].x_end = getbits(&state, 10 ); | |
214 | |
215 pci->hli.btnit[i].auto_action_mode = getbits(&state, 2 ); | |
216 pci->hli.btnit[i].y_start = getbits(&state, 10 ); | |
217 pci->hli.btnit[i].zero2 = getbits(&state, 2 ); | |
218 pci->hli.btnit[i].y_end = getbits(&state, 10 ); | |
219 | |
220 pci->hli.btnit[i].zero3 = getbits(&state, 2 ); | |
221 pci->hli.btnit[i].up = getbits(&state, 6 ); | |
222 pci->hli.btnit[i].zero4 = getbits(&state, 2 ); | |
223 pci->hli.btnit[i].down = getbits(&state, 6 ); | |
224 pci->hli.btnit[i].zero5 = getbits(&state, 2 ); | |
225 pci->hli.btnit[i].left = getbits(&state, 6 ); | |
226 pci->hli.btnit[i].zero6 = getbits(&state, 2 ); | |
227 pci->hli.btnit[i].right = getbits(&state, 6 ); | |
228 /* pci vm_cmd */ | |
229 for(j = 0; j < 8; j++) | |
230 pci->hli.btnit[i].cmd.bytes[j] = getbits(&state, 8 ); | |
231 } | |
232 | |
233 | |
234 | |
235 #ifndef NDEBUG | |
236 /* Asserts */ | |
237 | |
238 /* pci pci gi */ | |
239 CHECK_VALUE(pci->pci_gi.zero1 == 0); | |
240 | |
241 /* pci hli hli_gi */ | |
242 CHECK_VALUE(pci->hli.hl_gi.zero1 == 0); | |
243 CHECK_VALUE(pci->hli.hl_gi.zero2 == 0); | |
244 CHECK_VALUE(pci->hli.hl_gi.zero3 == 0); | |
245 CHECK_VALUE(pci->hli.hl_gi.zero4 == 0); | |
246 CHECK_VALUE(pci->hli.hl_gi.zero5 == 0); | |
247 | |
248 /* Are there buttons defined here? */ | |
249 if((pci->hli.hl_gi.hli_ss & 0x03) != 0) { | |
250 CHECK_VALUE(pci->hli.hl_gi.btn_ns != 0); | |
251 CHECK_VALUE(pci->hli.hl_gi.btngr_ns != 0); | |
252 } else { | |
253 CHECK_VALUE((pci->hli.hl_gi.btn_ns != 0 && pci->hli.hl_gi.btngr_ns != 0) | |
254 || (pci->hli.hl_gi.btn_ns == 0 && pci->hli.hl_gi.btngr_ns == 0)); | |
255 } | |
256 | |
257 /* pci hli btnit */ | |
258 for(i = 0; i < pci->hli.hl_gi.btngr_ns; i++) { | |
259 for(j = 0; j < (36 / pci->hli.hl_gi.btngr_ns); j++) { | |
260 int n = (36 / pci->hli.hl_gi.btngr_ns) * i + j; | |
261 CHECK_VALUE(pci->hli.btnit[n].zero1 == 0); | |
262 CHECK_VALUE(pci->hli.btnit[n].zero2 == 0); | |
263 CHECK_VALUE(pci->hli.btnit[n].zero3 == 0); | |
264 CHECK_VALUE(pci->hli.btnit[n].zero4 == 0); | |
265 CHECK_VALUE(pci->hli.btnit[n].zero5 == 0); | |
266 CHECK_VALUE(pci->hli.btnit[n].zero6 == 0); | |
267 | |
268 if (j < pci->hli.hl_gi.btn_ns) { | |
269 CHECK_VALUE(pci->hli.btnit[n].x_start <= pci->hli.btnit[n].x_end); | |
270 CHECK_VALUE(pci->hli.btnit[n].y_start <= pci->hli.btnit[n].y_end); | |
271 CHECK_VALUE(pci->hli.btnit[n].up <= pci->hli.hl_gi.btn_ns); | |
272 CHECK_VALUE(pci->hli.btnit[n].down <= pci->hli.hl_gi.btn_ns); | |
273 CHECK_VALUE(pci->hli.btnit[n].left <= pci->hli.hl_gi.btn_ns); | |
274 CHECK_VALUE(pci->hli.btnit[n].right <= pci->hli.hl_gi.btn_ns); | |
275 /* vmcmd_verify(pci->hli.btnit[n].cmd); */ | |
276 } else { | |
277 int k; | |
278 CHECK_VALUE(pci->hli.btnit[n].btn_coln == 0); | |
279 CHECK_VALUE(pci->hli.btnit[n].auto_action_mode == 0); | |
280 CHECK_VALUE(pci->hli.btnit[n].x_start == 0); | |
281 CHECK_VALUE(pci->hli.btnit[n].y_start == 0); | |
282 CHECK_VALUE(pci->hli.btnit[n].x_end == 0); | |
283 CHECK_VALUE(pci->hli.btnit[n].y_end == 0); | |
284 CHECK_VALUE(pci->hli.btnit[n].up == 0); | |
285 CHECK_VALUE(pci->hli.btnit[n].down == 0); | |
286 CHECK_VALUE(pci->hli.btnit[n].left == 0); | |
287 CHECK_VALUE(pci->hli.btnit[n].right == 0); | |
288 for (k = 0; k < 8; k++) | |
289 CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] == 0); /* CHECK_ZERO? */ | |
290 } | |
291 } | |
292 } | |
293 #endif /* !NDEBUG */ | |
294 } | |
295 | |
296 void navRead_DSI(dsi_t *dsi, unsigned char *buffer) { | |
297 int i; | |
298 getbits_state_t state; | |
243
e75c52894630
* assert(0) does not always and the program (see NDEBUG)
mroi
parents:
240
diff
changeset
|
299 if (!getbits_init(&state, buffer)) abort(); /* Passed NULL pointers */ |
225 | 300 |
301 /* dsi dsi gi */ | |
302 dsi->dsi_gi.nv_pck_scr = getbits(&state, 32 ); | |
303 dsi->dsi_gi.nv_pck_lbn = getbits(&state, 32 ); | |
304 dsi->dsi_gi.vobu_ea = getbits(&state, 32 ); | |
305 dsi->dsi_gi.vobu_1stref_ea = getbits(&state, 32 ); | |
306 dsi->dsi_gi.vobu_2ndref_ea = getbits(&state, 32 ); | |
307 dsi->dsi_gi.vobu_3rdref_ea = getbits(&state, 32 ); | |
308 dsi->dsi_gi.vobu_vob_idn = getbits(&state, 16 ); | |
309 dsi->dsi_gi.zero1 = getbits(&state, 8 ); | |
310 dsi->dsi_gi.vobu_c_idn = getbits(&state, 8 ); | |
311 dsi->dsi_gi.c_eltm.hour = getbits(&state, 8 ); | |
312 dsi->dsi_gi.c_eltm.minute = getbits(&state, 8 ); | |
313 dsi->dsi_gi.c_eltm.second = getbits(&state, 8 ); | |
314 dsi->dsi_gi.c_eltm.frame_u = getbits(&state, 8 ); | |
315 | |
316 /* dsi sml pbi */ | |
317 dsi->sml_pbi.category = getbits(&state, 16 ); | |
318 dsi->sml_pbi.ilvu_ea = getbits(&state, 32 ); | |
319 dsi->sml_pbi.ilvu_sa = getbits(&state, 32 ); | |
320 dsi->sml_pbi.size = getbits(&state, 16 ); | |
321 dsi->sml_pbi.vob_v_s_s_ptm = getbits(&state, 32 ); | |
322 dsi->sml_pbi.vob_v_e_e_ptm = getbits(&state, 32 ); | |
323 for(i = 0; i < 8; i++) { | |
324 dsi->sml_pbi.vob_a[i].stp_ptm1 = getbits(&state, 32 ); | |
325 dsi->sml_pbi.vob_a[i].stp_ptm2 = getbits(&state, 32 ); | |
326 dsi->sml_pbi.vob_a[i].gap_len1 = getbits(&state, 32 ); | |
327 dsi->sml_pbi.vob_a[i].gap_len2 = getbits(&state, 32 ); | |
328 } | |
329 | |
330 /* dsi sml agli */ | |
331 for(i = 0; i < 9; i++) { | |
332 dsi->sml_agli.data[ i ].address = getbits(&state, 32 ); | |
333 dsi->sml_agli.data[ i ].size = getbits(&state, 16 ); | |
334 } | |
335 | |
336 /* dsi vobu sri */ | |
337 dsi->vobu_sri.next_video = getbits(&state, 32 ); | |
338 for(i = 0; i < 19; i++) | |
339 dsi->vobu_sri.fwda[i] = getbits(&state, 32 ); | |
340 dsi->vobu_sri.next_vobu = getbits(&state, 32 ); | |
341 dsi->vobu_sri.prev_vobu = getbits(&state, 32 ); | |
342 for(i = 0; i < 19; i++) | |
343 dsi->vobu_sri.bwda[i] = getbits(&state, 32 ); | |
344 dsi->vobu_sri.prev_video = getbits(&state, 32 ); | |
345 | |
346 /* dsi synci */ | |
347 for(i = 0; i < 8; i++) | |
348 dsi->synci.a_synca[i] = getbits(&state, 16 ); | |
349 for(i = 0; i < 32; i++) | |
350 dsi->synci.sp_synca[i] = getbits(&state, 32 ); | |
351 | |
352 | |
353 /* Asserts */ | |
354 | |
355 /* dsi dsi gi */ | |
356 CHECK_VALUE(dsi->dsi_gi.zero1 == 0); | |
357 } | |
358 |