[libbluray-devel] Generate pseudo disc id when AACS disc id is not available
hpi1
git at videolan.org
Fri Apr 24 16:25:24 CEST 2015
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | 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);
More information about the libbluray-devel
mailing list