Commit a10b15fc authored by Petri Hintukainen's avatar Petri Hintukainen

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.
parent ad6690f2
......@@ -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];
}
}
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment