summaryrefslogtreecommitdiffstats
path: root/stream/stream_bluray.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/stream_bluray.c')
-rw-r--r--stream/stream_bluray.c85
1 files changed, 80 insertions, 5 deletions
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
index e7ecd08d64..e21f534550 100644
--- a/stream/stream_bluray.c
+++ b/stream/stream_bluray.c
@@ -23,7 +23,6 @@
* Use 'git clone git://git.videolan.org/libbluray' to get it.
*
* TODO:
- * - Add AACS/BD+ protection detection
* - Add descrambled keys database support (KEYDB.cfg)
*
*/
@@ -63,6 +62,16 @@
#define BD_TIME_TO_MP(x) ((x) / (double)(BD_TIMEBASE))
#define BD_TIME_FROM_MP(x) ((uint64_t)(x * BD_TIMEBASE))
+// copied from aacs.h in libaacs
+#define AACS_ERROR_CORRUPTED_DISC -1 /* opening or reading of AACS files failed */
+#define AACS_ERROR_NO_CONFIG -2 /* missing config file */
+#define AACS_ERROR_NO_PK -3 /* no matching processing key */
+#define AACS_ERROR_NO_CERT -4 /* no valid certificate */
+#define AACS_ERROR_CERT_REVOKED -5 /* certificate has been revoked */
+#define AACS_ERROR_MMC_OPEN -6 /* MMC open failed (no MMC drive ?) */
+#define AACS_ERROR_MMC_FAILURE -7 /* MMC failed */
+#define AACS_ERROR_NO_DK -8 /* no matching device key */
+
char *bluray_device = NULL;
int bluray_angle = 0;
@@ -604,6 +613,73 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg)
return STREAM_UNSUPPORTED;
}
+static bool check_disc_info(stream_t *s)
+{
+ struct bluray_priv_s *b = s->priv;
+ const BLURAY_DISC_INFO *info = bd_get_disc_info(b->bd);
+
+ // check Blu-ray
+ if (!info->bluray_detected) {
+ MP_ERR(s, "Given stream is not a Blu-ray.\n");
+ return false;
+ }
+
+ // check AACS
+ if (info->aacs_detected) {
+ if (!info->libaacs_detected) {
+ MP_ERR(s, "AACS encryption detected but cannot find libaacs.\n");
+ return false;
+ }
+ if (!info->aacs_handled) {
+ const char *err = NULL;
+ switch (info->aacs_error_code) {
+ case AACS_ERROR_CORRUPTED_DISC:
+ err = "opening or reading of AACS files failed";
+ break;
+ case AACS_ERROR_NO_CONFIG:
+ err = "missing config file";
+ break;
+ case AACS_ERROR_NO_PK:
+ err = "no matching processing key";
+ break;
+ case AACS_ERROR_NO_CERT:
+ err = "no valid certificate";
+ break;
+ case AACS_ERROR_CERT_REVOKED:
+ err = "certificate has been revoked";
+ break;
+ case AACS_ERROR_MMC_OPEN:
+ err = "MMC open failed (maybe no MMC drive?)";
+ break;
+ case AACS_ERROR_MMC_FAILURE:
+ err = "MMC failed";
+ break;
+ case AACS_ERROR_NO_DK:
+ err = "no matching device key";
+ break;
+ default:
+ err = "unknown error";
+ }
+ MP_ERR(s, "AACS error: %s\n", err);
+ return false;
+ }
+ }
+
+ // check BD+
+ if (info->bdplus_detected) {
+ if (!info->libbdplus_detected) {
+ MP_ERR(s, "BD+ encryption detected but cannot find libbdplus.\n");
+ return false;
+ }
+ if (!info->bdplus_handled) {
+ MP_ERR(s, "Cannot decrypt BD+ encryption.\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
static void select_initial_title(stream_t *s, int title_guess) {
struct bluray_priv_s *b = s->priv;
@@ -672,16 +748,16 @@ static int bluray_stream_open(stream_t *s, int mode)
MP_ERR(s, "Couldn't open Blu-ray device: %s\n", device);
return STREAM_UNSUPPORTED;
}
+ b->bd = bd;
- const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(bd);
- if (!disc_info->bluray_detected) {
- MP_ERR(s, "Given stream is not a Blu-ray.\n");
+ if (!check_disc_info(s)) {
destruct(b);
return STREAM_UNSUPPORTED;
}
int title_guess = BLURAY_DEFAULT_TITLE;
if (b->use_nav) {
+ const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(b->bd);
b->num_titles = disc_info->num_hdmv_titles + disc_info->num_bdj_titles;
++b->num_titles; // for BLURAY_TITLE_TOP_MENU
++b->num_titles; // for BLURAY_TITLE_FIRST_PLAY
@@ -722,7 +798,6 @@ static int bluray_stream_open(stream_t *s, int mode)
// these should be set before any callback
b->pool = mp_image_pool_new(6);
- b->bd = bd;
b->current_angle = -1;
b->current_title = -1;