[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