MakeMKV 1.14.2 and Kodi 18.0

The place to discuss Mac OS X version of MakeMKV
Post Reply
dgktkr
Posts: 18
Joined: Thu Dec 30, 2010 7:51 pm

MakeMKV 1.14.2 and Kodi 18.0

Post by dgktkr »

Hi,

I like to play my blu-ray discs with Kodi. When version 18.0 was in beta, I tried playing blu-rays without success. Apparently Kodi had incorporated a new version of libbluray, which broke on-the-fly decryption by MakeMKV. For MacOS and Linux I found a solution which required editing of Kodi source and then building viewtopic.php?f=3&t=16824. Not and easy or quick endeavor.

With version 1.14.2, MakeMKV has gotten closer to a solution (deals properly with discs that have aacs protection only but doesn't handle BD+). There's no problem ripping discs, the problem is emulating the libbdplus to libbluray interface.

For Linux, a work around can be achieved by editing MakeMKV source code before building viewtopic.php?f=3&t=16824#p61608.

For MacOS, we don't have access to the MakeMKV source code. A solution can be had, however, by editing libbluray source code and building libluray.dylib:

In file libbluray/src/libbluray/disc/bdplus.c, replace 20 lines (starting around line 216):

Code: Select all

if (set_fopen) {
        /* New libbdplus. Use libbluray for file I/O */
        p->bdplus = bdplus_init(NULL, NULL, vid);
        /* In open source bdplus_set_fopen() (i.e. set_fopen() following this comment) p->bdplus members are
         set to values given by corresponding second and third parameters */
        set_fopen(p->bdplus, file_open_handle, file_open_fp);
    } else if (root) {
        /* Old libbdplus or libmmbd. Disc is mounted. */
        p->bdplus = bdplus_init(root, NULL, vid);
    } else if (device) {
        /* Unmounted device */
        if (p->impl_id == IMPL_LIBMMBD && !strncmp(device, "/dev/", 5)) {
            char *tmp = str_printf("dev:%s", device);
            if (tmp) {
                p->bdplus = bdplus_init(tmp, NULL, vid);
                X_FREE(tmp);
            }
        } else {
            BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Too old libbdplus detected. Disc must be mounted first.\n");
        }
    }
with

Code: Select all

    p->bdplus = bdplus_init(NULL, NULL, vid);
Then build libbluray in the usual way and take the resulting libbluray.2.dylib (found in directory .libs) and with it replace the file with that name in /Applications/Kodi.app/Contents/Libraries.

The hardest part of this process is getting all the dependencies installed properly before you build libbluray:

fontconfig
freetype2
libxml2
jre8-openjdk
ant
git
jdk8-openjdk

Hopefully, somebody else with find this useful.

dgktkr
spl147
Posts: 309
Joined: Mon Dec 10, 2012 4:59 pm

Re: MakeMKV 1.14.2 and Kodi 18.0

Post by spl147 »

dgktkr wrote:
Tue Feb 12, 2019 9:34 pm
Hi,

I like to play my blu-ray discs with Kodi. When version 18.0 was in beta, I tried playing blu-rays without success. Apparently Kodi had incorporated a new version of libbluray, which broke on-the-fly decryption by MakeMKV. For MacOS and Linux I found a solution which required editing of Kodi source and then building viewtopic.php?f=3&t=16824. Not and easy or quick endeavor.

With version 1.14.2, MakeMKV has gotten closer to a solution (deals properly with discs that have aacs protection only but doesn't handle BD+). There's no problem ripping discs, the problem is emulating the libbdplus to libbluray interface.

For Linux, a work around can be achieved by editing MakeMKV source code before building viewtopic.php?f=3&t=16824#p61608.

For MacOS, we don't have access to the MakeMKV source code. A solution can be had, however, by editing libbluray source code and building libluray.dylib:

In file libbluray/src/libbluray/disc/bdplus.c, replace 20 lines (starting around line 216):

Code: Select all

if (set_fopen) {
        /* New libbdplus. Use libbluray for file I/O */
        p->bdplus = bdplus_init(NULL, NULL, vid);
        /* In open source bdplus_set_fopen() (i.e. set_fopen() following this comment) p->bdplus members are
         set to values given by corresponding second and third parameters */
        set_fopen(p->bdplus, file_open_handle, file_open_fp);
    } else if (root) {
        /* Old libbdplus or libmmbd. Disc is mounted. */
        p->bdplus = bdplus_init(root, NULL, vid);
    } else if (device) {
        /* Unmounted device */
        if (p->impl_id == IMPL_LIBMMBD && !strncmp(device, "/dev/", 5)) {
            char *tmp = str_printf("dev:%s", device);
            if (tmp) {
                p->bdplus = bdplus_init(tmp, NULL, vid);
                X_FREE(tmp);
            }
        } else {
            BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Too old libbdplus detected. Disc must be mounted first.\n");
        }
    }
with

Code: Select all

    p->bdplus = bdplus_init(NULL, NULL, vid);
Then build libbluray in the usual way and take the resulting libbluray.2.dylib (found in directory .libs) and with it replace the file with that name in /Applications/Kodi.app/Contents/Libraries.

The hardest part of this process is getting all the dependencies installed properly before you build libbluray:

fontconfig
freetype2
libxml2
jre8-openjdk
ant
git
jdk8-openjdk

Hopefully, somebody else with find this useful.

dgktkr
so why not just rip your discs to mkv and be done with it! i don't believe MakeMKV was intended to decrypt for on the fly watching!

if you want to watch the original discs why not just use a real Blu-ray Player?
My1xT
Posts: 19
Joined: Fri Oct 26, 2018 9:29 am

Re: MakeMKV 1.14.2 and Kodi 18.0

Post by My1xT »

spl147 wrote:
Tue Feb 19, 2019 2:47 pm
so why not just rip your discs to mkv and be done with it! i don't believe MakeMKV was intended to decrypt for on the fly watching!
maybe because you dont always have up to 50GB to spare (also it's just quicker to not have to wait for reading the entire disc).
if you want to watch the original discs why not just use a real Blu-ray Player?
maybe because for example a portable BD player isnt much more than a crippled Laptop, or because you have a very nice working media center pc which is generally just nicer than to switch between devices for everything.
occono
Posts: 2
Joined: Wed Jun 12, 2019 12:17 am

Re: MakeMKV 1.14.2 and Kodi 18.0

Post by occono »

spl147 wrote:
Tue Feb 19, 2019 2:47 pm
so why not just rip your discs to mkv and be done with it! i don't believe MakeMKV was intended to decrypt for on the fly watching!

if you want to watch the original discs why not just use a real Blu-ray Player?
Personally I want to be able to just watch a BluRay in Windows sometimes instead of switching to a Bluray player. But also, I can use virtual headphone surround my Blurays if I watch them on my PC, and for me it works well enough, I'm not going to be able to set up actual surround sound equipment.

Kodi with the MakeMKV key works most reliably for playing all discs.
mike admin
Posts: 4075
Joined: Wed Nov 26, 2008 2:26 am
Contact:

Re: MakeMKV 1.14.2 and Kodi 18.0

Post by mike admin »

dgktkr wrote:
Tue Feb 12, 2019 9:34 pm
For Linux, a work around can be achieved by editing MakeMKV source code before building https://www.makemkv.com/forum/viewtopic ... 824#p61608.
For MacOS, we don't have access to the MakeMKV source code. A solution can be had, however, by editing libbluray source code and building libluray.dylib:
Interesting. Is the reason for the failure the missing bdplus_set_fopen API? This will be fixed in a next version. Also, the "linux" code is actually a cross-platform. You can rebuild libmmbd for mac from that code, that's how it actually is built.
dgktkr
Posts: 18
Joined: Thu Dec 30, 2010 7:51 pm

Re: MakeMKV 1.14.2 and Kodi 18.0

Post by dgktkr »

mike admin wrote:
Mon Jul 15, 2019 11:57 am
dgktkr wrote:
Tue Feb 12, 2019 9:34 pm
For Linux, a work around can be achieved by editing MakeMKV source code before building https://www.makemkv.com/forum/viewtopic ... 824#p61608.
For MacOS, we don't have access to the MakeMKV source code. A solution can be had, however, by editing libbluray source code and building libluray.dylib:
Interesting. Is the reason for the failure the missing bdplus_set_fopen API? This will be fixed in a next version. Also, the "linux" code is actually a cross-platform. You can rebuild libmmbd for mac from that code, that's how it actually is built.
Hi Mike,

Yes, I believe that the missing bdplus_set_fopen() in MakeMKV 1.14.4 does cause failure when trying to directly play blurays with Kodi 18.3. VLC and MakeMKV play together well. As near as I can tell the explanation for this is that Kodi doesn't pass values for 'root' or 'device' to libbluray (VLC passes 'root'). As a consequence, control in Kodi passes through libbdplus_init() in libbluray 1.0.2 without executing bdplus_init(), because bdplus_set_fopen() is not made available by MakeMKV. It's not hard to correct for this in libbluray, but it's also not hard to correct for this in MakeMKV. bdplus_set_fopen() doesn't need to be used by MakeMKV to do anything, it just needs to be exported so that

Code: Select all

p->bdplus = bdplus_init(NULL, NULL, vid);
will be executed in libbdplus_init().

Code: Select all

int libbdplus_init(BD_BDPLUS *p, const char *root, const char *device,
                   void *file_open_handle, void *file_open_fp,
                   const uint8_t *vid, const uint8_t *mk)
{
    fptr_p_void    bdplus_init;
    fptr_void      set_fopen;

    _libbdplus_close(p);

    /* force libmmbd BD+ if no AACS media key:
     * - open source libbdplus requires media key
     * - libmmbd does not export media key
     *   (=> open source libbdplus won't work with libmmbd AACS)
     */
    if (mk == NULL && p->impl_id == IMPL_LIBBDPLUS) {
        BD_BDPLUS *p2 = _load(IMPL_LIBMMBD);
        if (p2) {
            if (!libbdplus_init(p2, root, device, file_open_handle, file_open_fp, vid, mk)) {
                /* succeed - swap implementations */
                _unload(p);
                *p = *p2;
                X_FREE(p2);
                return 0;
            }
            /* failed - continue with original bd+ implementation */
            libbdplus_unload(&p2);
        }
    }

    /* */

    *(void **)(&bdplus_init) = dl_dlsym(p->h_libbdplus, "bdplus_init");
    *(void **)(&set_fopen)   = dl_dlsym(p->h_libbdplus, "bdplus_set_fopen");

    if (!bdplus_init) {
        BD_DEBUG(DBG_BLURAY | DBG_CRIT, "libbdplus dlsym(bdplus_init) failed! (%p)\n", p->h_libbdplus);
        return -1;
    }

    if (set_fopen) {
        /* New libbdplus. Use libbluray for file I/O */
        p->bdplus = bdplus_init(NULL, NULL, vid);
        /* In open source bdplus_set_fopen() (i.e. set_fopen() following this comment) p->bdplus members are
         set to values given by corresponding second and third parameters */
        set_fopen(p->bdplus, file_open_handle, file_open_fp);
    } else if (root) {
        /* Old libbdplus or libmmbd. Disc is mounted. */
        p->bdplus = bdplus_init(root, NULL, vid);
    } else if (device) {
        /* Unmounted device */
        if (p->impl_id == IMPL_LIBMMBD && !strncmp(device, "/dev/", 5)) {
            char *tmp = str_printf("dev:%s", device);
            if (tmp) {
                p->bdplus = bdplus_init(tmp, NULL, vid);
                X_FREE(tmp);
            }
        } else {
            BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Too old libbdplus detected. Disc must be mounted first.\n");
        }
    }AY | DBG_CRIT, "ghr081519 set_fopen, root and device don't exist\n");
    if (!p->bdplus) {
        BD_DEBUG(DBG_BLURAY | DBG_CRIT, "bdplus_init() failed! (%p)\n", p->h_libbdplus);
        return -1;
    }

    DL_CALL(p->h_libbdplus, bdplus_set_mk, p->bdplus, mk);

    return 0;
}
PS I believe that the same considerations apply to Linux installations.
Post Reply