|
MythTV
0.26-pre
|
00001 /* 00002 * This file is part of libbluray 00003 * Copyright (C) 2010 hpi1 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library. If not, see 00017 * <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include "register.h" 00021 #include "util/attributes.h" 00022 #include "util/macro.h" 00023 #include "util/logging.h" 00024 #include "util/mutex.h" 00025 00026 #include <stdlib.h> 00027 #include <string.h> 00028 00029 #define BD_PSR_COUNT 128 00030 #define BD_GPR_COUNT 4096 00031 00032 /* 00033 * Initial values for player status/setting registers (5.8.2). 00034 * 00035 * PS in comment indicates player setting -> register can't be changed from movie object code. 00036 */ 00037 00038 static const uint32_t bd_psr_init[BD_PSR_COUNT] = { 00039 1, /* PSR0: Interactive graphics stream number */ 00040 0xff, /* PSR1: Primary audio stream number */ 00041 0x0fff0fff, /* PSR2: PG TextST stream number and PiP PG stream number*/ 00042 1, /* PSR3: Angle number */ 00043 0xffff, /* PSR4: Title number */ 00044 0xffff, /* PSR5: Chapter number */ 00045 0, /* PSR6: PlayList ID */ 00046 0, /* PSR7: PlayItem ID */ 00047 0, /* PSR8: Presentation time */ 00048 0, /* PSR9: Navigation timer */ 00049 0xffff, /* PSR10: Selected button ID */ 00050 0, /* PSR11: Page ID */ 00051 0xff, /* PSR12: User style number */ 00052 0xff, /* PS: PSR13: User age */ 00053 0xffff, /* PSR14: Secondary audio stream number and secondary video stream number */ 00054 0xffff, /* PS: PSR15: player capability for audio */ 00055 0xffffff, /* PS: PSR16: Language code for audio */ 00056 0xffffff, /* PS: PSR17: Language code for PG and Text subtitles */ 00057 0xffffff, /* PS: PSR18: Menu description language code */ 00058 0xffff, /* PS: PSR19: Country code */ 00059 0x07, /* PS: PSR20: Region code */ /* 1 - A, 2 - B, 4 - C */ 00060 0, /* PSR21 */ 00061 0, /* PSR22 */ 00062 0, /* PSR23 */ 00063 0, /* PSR24 */ 00064 0, /* PSR25 */ 00065 0, /* PSR26 */ 00066 0, /* PSR27 */ 00067 0, /* PSR28 */ 00068 0x03, /* PS: PSR29: player capability for video */ 00069 0x1ffff, /* PS: PSR30: player capability for text subtitle */ 00070 0x080200, /* PS: PSR31: Player profile and version */ 00071 0, /* PSR32 */ 00072 0, /* PSR33 */ 00073 0, /* PSR34 */ 00074 0, /* PSR35 */ 00075 0xffff, /* PSR36: backup PSR4 */ 00076 0xffff, /* PSR37: backup PSR5 */ 00077 0, /* PSR38: backup PSR6 */ 00078 0, /* PSR39: backup PSR7 */ 00079 0, /* PSR40: backup PSR8 */ 00080 0, /* PSR41: */ 00081 0xffff, /* PSR42: backup PSR10 */ 00082 0, /* PSR43: backup PSR11 */ 00083 0xff, /* PSR44: backup PSR12 */ 00084 0, /* PSR45: */ 00085 0, /* PSR46: */ 00086 0, /* PSR47: */ 00087 0xffffffff, /* PS: PSR48: Characteristic text caps */ 00088 0xffffffff, /* PS: PSR49: Characteristic text caps */ 00089 0xffffffff, /* PS: PSR50: Characteristic text caps */ 00090 0xffffffff, /* PS: PSR51: Characteristic text caps */ 00091 0xffffffff, /* PS: PSR52: Characteristic text caps */ 00092 0xffffffff, /* PS: PSR53: Characteristic text caps */ 00093 0xffffffff, /* PS: PSR54: Characteristic text caps */ 00094 0xffffffff, /* PS: PSR55: Characteristic text caps */ 00095 0xffffffff, /* PS: PSR56: Characteristic text caps */ 00096 0xffffffff, /* PS: PSR57: Characteristic text caps */ 00097 0xffffffff, /* PS: PSR58: Characteristic text caps */ 00098 0xffffffff, /* PS: PSR59: Characteristic text caps */ 00099 0xffffffff, /* PS: PSR60: Characteristic text caps */ 00100 0xffffffff, /* PS: PSR61: Characteristic text caps */ 00101 /* 62-95: reserved */ 00102 /* 96-111: reserved for BD system use */ 00103 /* 112-127: reserved */ 00104 }; 00105 00106 /* 00107 * PSR ids for debugging 00108 */ 00109 static const char * const bd_psr_name[BD_PSR_COUNT] = { 00110 "IG_STREAM_ID", 00111 "PRIMARY_AUDIO_ID", 00112 "PG_STREAM", 00113 "ANGLE_NUMBER", 00114 "TITLE_NUMBER", 00115 "CHAPTER", 00116 "PLAYLIST", 00117 "PLAYITEM", 00118 "TIME", 00119 "NAV_TIMER", 00120 "SELECTED_BUTTON_ID", 00121 "MENU_PAGE_ID", 00122 "STYLE", 00123 "PARENTAL", 00124 "SECONDARY_AUDIO_VIDEO", 00125 "AUDIO_CAP", 00126 "AUDIO_LANG", 00127 "PG_AND_SUB_LANG", 00128 "PSR_MENU_LANG", 00129 "PSR_COUNTRY", 00130 "PSR_REGION", 00131 "PSR_VIDEO_CAP", 00132 }; 00133 00134 /* 00135 * data 00136 */ 00137 00138 typedef struct { 00139 void *handle; 00140 void (*cb)(void *, BD_PSR_EVENT*); 00141 } PSR_CB_DATA; 00142 00143 struct bd_registers_s 00144 { 00145 uint32_t psr[BD_PSR_COUNT]; 00146 uint32_t gpr[BD_GPR_COUNT]; 00147 00148 /* callbacks */ 00149 unsigned num_cb; 00150 PSR_CB_DATA *cb; 00151 00152 BD_MUTEX mutex; 00153 }; 00154 00155 /* 00156 * init / free 00157 */ 00158 00159 BD_REGISTERS *bd_registers_init(void) 00160 { 00161 BD_REGISTERS *p = calloc(1, sizeof(BD_REGISTERS)); 00162 00163 memcpy(p->psr, bd_psr_init, sizeof(bd_psr_init)); 00164 00165 bd_mutex_init(&p->mutex); 00166 00167 return p; 00168 } 00169 00170 void bd_registers_free(BD_REGISTERS *p) 00171 { 00172 if (p) { 00173 bd_mutex_destroy(&p->mutex); 00174 00175 X_FREE(p->cb); 00176 } 00177 00178 X_FREE(p); 00179 } 00180 00181 /* 00182 * PSR lock / unlock 00183 */ 00184 00185 void bd_psr_lock(BD_REGISTERS *p) 00186 { 00187 bd_mutex_lock(&p->mutex); 00188 } 00189 00190 void bd_psr_unlock(BD_REGISTERS *p) 00191 { 00192 bd_mutex_unlock(&p->mutex); 00193 } 00194 00195 /* 00196 * PSR change callback register / unregister 00197 */ 00198 00199 void bd_psr_register_cb (BD_REGISTERS *p, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle) 00200 { 00201 /* no duplicates ! */ 00202 unsigned i; 00203 00204 bd_psr_lock(p); 00205 00206 for (i = 0; i < p->num_cb; i++) { 00207 if (p->cb[i].handle == cb_handle && p->cb[i].cb == callback) { 00208 00209 bd_psr_unlock(p); 00210 return; 00211 } 00212 } 00213 00214 p->num_cb++; 00215 p->cb = realloc(p->cb, p->num_cb * sizeof(PSR_CB_DATA)); 00216 00217 p->cb[p->num_cb - 1].cb = callback; 00218 p->cb[p->num_cb - 1].handle = cb_handle; 00219 00220 bd_psr_unlock(p); 00221 } 00222 00223 void bd_psr_unregister_cb(BD_REGISTERS *p, void (*callback)(void*,BD_PSR_EVENT*), void *cb_handle) 00224 { 00225 unsigned i = 0; 00226 00227 bd_psr_lock(p); 00228 00229 while (i < p->num_cb) { 00230 if (p->cb[i].handle == cb_handle && p->cb[i].cb == callback) { 00231 if (--p->num_cb) { 00232 memmove(p->cb + i, p->cb + i + 1, sizeof(PSR_CB_DATA) * p->num_cb); 00233 continue; 00234 } 00235 } 00236 i++; 00237 } 00238 00239 bd_psr_unlock(p); 00240 } 00241 00242 /* 00243 * PSR state save / restore 00244 */ 00245 00246 void bd_psr_save_state(BD_REGISTERS *p) 00247 { 00248 /* store registers 4-8 and 10-12 to backup registers */ 00249 00250 bd_psr_lock(p); 00251 00252 memcpy(p->psr + 36, p->psr + 4, sizeof(uint32_t) * 5); 00253 memcpy(p->psr + 42, p->psr + 10, sizeof(uint32_t) * 3); 00254 00255 /* generate save event */ 00256 00257 if (p->num_cb) { 00258 BD_PSR_EVENT ev = { 00259 .ev_type = BD_PSR_SAVE, 00260 .psr_idx = -1, 00261 .old_val = 0, 00262 .new_val = 0, 00263 }; 00264 00265 unsigned j; 00266 for (j = 0; j < p->num_cb; j++) { 00267 p->cb[j].cb(p->cb[j].handle, &ev); 00268 } 00269 } 00270 00271 bd_psr_unlock(p); 00272 } 00273 00274 void bd_psr_reset_backup_registers(BD_REGISTERS *p) 00275 { 00276 bd_psr_lock(p); 00277 00278 /* init backup registers to default */ 00279 memcpy(p->psr + 36, bd_psr_init + 36, sizeof(uint32_t) * 5); 00280 memcpy(p->psr + 42, bd_psr_init + 42, sizeof(uint32_t) * 3); 00281 00282 bd_psr_unlock(p); 00283 } 00284 00285 void bd_psr_restore_state(BD_REGISTERS *p) 00286 { 00287 uint32_t old_psr[13]; 00288 uint32_t new_psr[13]; 00289 00290 bd_psr_lock(p); 00291 00292 if (p->num_cb) { 00293 memcpy(old_psr, p->psr, sizeof(old_psr[0]) * 13); 00294 } 00295 00296 /* restore backup registers */ 00297 memcpy(p->psr + 4, p->psr + 36, sizeof(uint32_t) * 5); 00298 memcpy(p->psr + 10, p->psr + 42, sizeof(uint32_t) * 3); 00299 00300 if (p->num_cb) { 00301 memcpy(new_psr, p->psr, sizeof(new_psr[0]) * 13); 00302 } 00303 00304 /* init backup registers to default */ 00305 memcpy(p->psr + 36, bd_psr_init + 36, sizeof(uint32_t) * 5); 00306 memcpy(p->psr + 42, bd_psr_init + 42, sizeof(uint32_t) * 3); 00307 00308 /* generate restore events */ 00309 if (p->num_cb) { 00310 BD_PSR_EVENT ev; 00311 unsigned i, j; 00312 00313 ev.ev_type = BD_PSR_RESTORE; 00314 00315 for (i = 4; i < 13; i++) { 00316 if (i != PSR_NAV_TIMER) { 00317 00318 ev.psr_idx = i; 00319 ev.old_val = old_psr[i]; 00320 ev.new_val = new_psr[i]; 00321 00322 for (j = 0; j < p->num_cb; j++) { 00323 p->cb[j].cb(p->cb[j].handle, &ev); 00324 } 00325 } 00326 } 00327 } 00328 00329 bd_psr_unlock(p); 00330 } 00331 00332 /* 00333 * GPR read / write 00334 */ 00335 00336 int bd_gpr_write(BD_REGISTERS *p, int reg, uint32_t val) 00337 { 00338 if (reg < 0 || reg > BD_GPR_COUNT) { 00339 BD_DEBUG(DBG_BLURAY, "bd_gpr_write(%d): invalid register\n", reg); 00340 return -1; 00341 } 00342 00343 p->gpr[reg] = val; 00344 return 0; 00345 } 00346 00347 uint32_t bd_gpr_read(BD_REGISTERS *p, int reg) 00348 { 00349 if (reg < 0 || reg > BD_GPR_COUNT) { 00350 BD_DEBUG(DBG_BLURAY, "bd_gpr_read(%d): invalid register\n", reg); 00351 return -1; 00352 } 00353 00354 return p->gpr[reg]; 00355 } 00356 00357 /* 00358 * PSR read / write 00359 */ 00360 00361 uint32_t bd_psr_read(BD_REGISTERS *p, int reg) 00362 { 00363 uint32_t val; 00364 00365 if (reg < 0 || reg > BD_PSR_COUNT) { 00366 BD_DEBUG(DBG_BLURAY, "bd_psr_read(%d): invalid register\n", reg); 00367 return -1; 00368 } 00369 00370 bd_psr_lock(p); 00371 00372 val = p->psr[reg]; 00373 00374 bd_psr_unlock(p); 00375 00376 return val; 00377 } 00378 00379 int bd_psr_setting_write(BD_REGISTERS *p, int reg, uint32_t val) 00380 { 00381 if (reg < 0 || reg > BD_PSR_COUNT) { 00382 BD_DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): invalid register\n", reg, val); 00383 return -1; 00384 } 00385 00386 bd_psr_lock(p); 00387 00388 if (p->psr[reg] == val) { 00389 BD_DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): no change in value\n", reg, val); 00390 } else if (bd_psr_name[reg]) { 00391 BD_DEBUG(DBG_BLURAY, "bd_psr_write(): PSR%-4d (%s) 0x%x -> 0x%x\n", reg, bd_psr_name[reg], p->psr[reg], val); 00392 } else { 00393 BD_DEBUG(DBG_BLURAY, "bd_psr_write(): PSR%-4d 0x%x -> 0x%x\n", reg, p->psr[reg], val); 00394 } 00395 00396 if (p->num_cb) { 00397 BD_PSR_EVENT ev; 00398 unsigned i; 00399 00400 ev.ev_type = p->psr[reg] == val ? BD_PSR_WRITE : BD_PSR_CHANGE; 00401 ev.psr_idx = reg; 00402 ev.old_val = p->psr[reg]; 00403 ev.new_val = val; 00404 00405 p->psr[reg] = val; 00406 00407 for (i = 0; i < p->num_cb; i++) { 00408 p->cb[i].cb(p->cb[i].handle, &ev); 00409 } 00410 00411 } else { 00412 00413 p->psr[reg] = val; 00414 } 00415 00416 bd_psr_unlock(p); 00417 00418 return 0; 00419 } 00420 00421 int bd_psr_write(BD_REGISTERS *p, int reg, uint32_t val) 00422 { 00423 if ((reg == 13) || 00424 (reg >= 15 && reg <= 20) || 00425 (reg >= 29 && reg <= 31) || 00426 (reg >= 48 && reg <= 61)) { 00427 BD_DEBUG(DBG_BLURAY, "bd_psr_write(%d, %d): read-only register !\n", reg, val); 00428 return -2; 00429 } 00430 00431 return bd_psr_setting_write(p, reg, val); 00432 } 00433
1.7.6.1