libbluray | branch: master | hpi1 <[email protected]> | Fri Apr 24 12:20:54 2015 +0300| [a10b15fc4d85f6e4b970f294ec3f9d6190d4cb6a] | committer: hpi1
Generate pseudo disc id when AACS disc id is not available ID is created from 128-bit murmur3 hashes of index.bdmv and MovieObject.bdmv. > http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=a10b15fc4d85f6e4b970f294ec3f9d6190d4cb6a --- src/libbluray/disc/disc.c | 88 +++++++++++++++++++++++++++++++++++++++++++++ src/libbluray/disc/disc.h | 3 ++ 2 files changed, 91 insertions(+) diff --git a/src/libbluray/disc/disc.c b/src/libbluray/disc/disc.c index c269cd2..4c33f6f 100644 --- a/src/libbluray/disc/disc.c +++ b/src/libbluray/disc/disc.c @@ -511,3 +511,91 @@ void disc_event(BD_DISC *disc, uint32_t event, uint32_t param) } } +/* + * Pseudo disc ID + * This is used when AACS disc ID is not available + */ + +static uint64_t _rotl64(uint64_t k, int n) +{ + return (k << n) | (k >> (64 - n)); +} + +static uint64_t _fmix64(uint64_t k) +{ + k ^= k >> 33; + k *= UINT64_C(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= UINT64_C(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + return k; +} + +static void _murmurhash3_128(const uint8_t *in, size_t len, void *out) +{ + // original MurmurHash3 was written by Austin Appleby, and is placed in the public domain. + // https://code.google.com/p/smhasher/wiki/MurmurHash3 + const uint64_t c1 = UINT64_C(0x87c37b91114253d5); + const uint64_t c2 = UINT64_C(0x4cf5ad432745937f); + uint64_t h[2] = {0, 0}; + size_t i; + + /* use only N * 16 bytes, ignore tail */ + len &= ~15; + + for (i = 0; i < len; i += 16) { + uint64_t k1, k2; + memcpy(&k1, in + i, sizeof(uint64_t)); + memcpy(&k2, in + i + 8, sizeof(uint64_t)); + + k1 *= c1; k1 = _rotl64(k1, 31); k1 *= c2; h[0] ^= k1; + + h[0] = _rotl64(h[0], 27); h[0] += h[1]; h[0] = h[0] * 5 + 0x52dce729; + + k2 *= c2; k2 = _rotl64(k2, 33); k2 *= c1; h[1] ^= k2; + + h[1] = _rotl64(h[1], 31); h[1] += h[0]; h[1] = h[1] * 5 + 0x38495ab5; + } + + h[0] ^= len; + h[1] ^= len; + + h[0] += h[1]; + h[1] += h[0]; + + h[0] = _fmix64(h[0]); + h[1] = _fmix64(h[1]); + + h[0] += h[1]; + h[1] += h[0]; + + memcpy(out, h, 2*sizeof(uint64_t)); +} + +static int _hash_file(BD_DISC *p, const char *dir, const char *file, void *hash) +{ + uint8_t *data = NULL; + size_t sz; + + sz = disc_read_file(p, dir, file, &data); + if (sz > 16) { + _murmurhash3_128(data, sz, hash); + } + + X_FREE(data); + return sz > 16; +} + +BD_PRIVATE void disc_pseudo_id(BD_DISC *p, uint8_t *id/*[20]*/) +{ + uint8_t h[2][20]; + int i; + + memset(h, 0, sizeof(h)); + _hash_file(p, "BDMV", "MovieObject.bdmv", h[0]); + _hash_file(p, "BDMV", "index.bdmv", h[1]); + + for (i = 0; i < 20; i++) { + id[i] = h[0][i] ^ h[1][i]; + } +} diff --git a/src/libbluray/disc/disc.h b/src/libbluray/disc/disc.h index f005d82..8bbde7b 100644 --- a/src/libbluray/disc/disc.h +++ b/src/libbluray/disc/disc.h @@ -52,6 +52,9 @@ BD_PRIVATE const char *disc_root(BD_DISC *disc); /* Get UDF volume ID */ BD_PRIVATE const char *disc_volume_id(BD_DISC *); +/* Generate pseudo disc ID */ +BD_PRIVATE void disc_pseudo_id(BD_DISC *, uint8_t *id/*[20]*/); + /* Open VFS file (relative to disc root) */ BD_PRIVATE struct bd_file_s *disc_open_file(BD_DISC *disc, const char *dir, const char *file); BD_PRIVATE struct bd_file_s *disc_open_path(BD_DISC *disc, const char *path); _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
