libmmbd with kodi18

The place to discuss linux version of MakeMKV
Message
Author
steo86
Posts: 8
Joined: Mon Dec 04, 2017 11:26 am

libmmbd with kodi18

#1 Post by steo86 » Mon Dec 04, 2017 11:35 am

Hello,

I am using makemkv to play encrypted blu rays in kodi mediacenter by linking libmmbd.so.0 to libaacs.so.0 and libbdplus.so.0
See here:
https://wiki.ubuntuusers.de/MakeMKV/
This was working fine in kodi 17. When I try to play a disk in kodi 18 kodi hangs up.
I dont know if the problem is related to makemkv or kodi.
But anyway does anyone of you got this working with kodi18 in linux?

delleceste
Posts: 2
Joined: Sat Dec 16, 2017 1:09 pm

Re: libmmbd with kodi18

#2 Post by delleceste » Sat Dec 16, 2017 1:49 pm

Same problem here. Shortly a new post will appear, with the problem description and a crash log.

KODI developers rejected the BUG as third party.

I really hope this can be solved.

Giacomo

steo86
Posts: 8
Joined: Mon Dec 04, 2017 11:26 am

Re: libmmbd with kodi18

#3 Post by steo86 » Mon Dec 25, 2017 9:36 am

Hello,
any news on that issue?
The problem seems also to get discussed here:
http://www.makemkv.com/forum2/viewtopic ... 10&t=15571

steo86
Posts: 8
Joined: Mon Dec 04, 2017 11:26 am

Re: libmmbd with kodi18

#4 Post by steo86 » Mon Dec 25, 2017 9:37 am


dainara
Posts: 6
Joined: Thu Aug 03, 2017 8:29 pm

Re: libmmbd with kodi18

#5 Post by dainara » Sat Jan 20, 2018 9:47 am

Hi
I have an worling makemkv 1.10.10 for LibreElec, there is an working Kodi system
Some from the Libreelec devs have an Source Code with makemkv i changed the version number from makemkv and compilled it and it works

But my Problem is, that UHD BD Discs not Play
The uhd-bd Drive is the friendly one from Asus, it works under Windows 10 and makemkv 1.10.10
I have an Core i5 7500, the Mainboard have only an hdmi 1.4 Port, but in the Description from this Board it tells that it is possible but only with Max 24hz, so
I don't know where the Problem is.
I have the new key files in the .MakeMKV folder and the other Files for normal BD Disks

Next one the uhd-bd Drive is very Slow when i Inserat an 4K Bad Disk. With an normal bd Disk everything is all Right

Maybe someone can help?

ByeBye
Dainara

dgktkr
Posts: 18
Joined: Thu Dec 30, 2010 7:51 pm

Re: libmmbd with kodi18

#6 Post by dgktkr » Thu Feb 01, 2018 8:46 pm

Hi,

Kodi 18 used to crash for me also on Ubuntu 17.10. However, I've implemented a fix that, after preliminary testing, seems to work. The solution points to a Kodi coding problem, not a Makemkv or libbluray problem.

In the Kodi source file ~/xbmc/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp (around line 400) I've replaced (!m_dll->bd_open_files(m_bd, &m_rootPath, DllLibbluray::dir_open, DllLibbluray::file_open)) with (!m_dll->bd_open_disc( m_bd,root.c_str(), NULL)).
And in ~/xbmc/xbmc/filesystem/BlurayDirectory.cpp (around line 280), I've made the same substitution. After a recompile, blurays play without Kodi crashing! This solution works on both macOS and Ubuntu 17.10.

Here's the thinking (and testing) behind this. Because Kodi crashed with libmmbd installed, but did not crash when only the default libaacs was in place, it sure looked like the fault was in libmmbd. On the other hand, for macOS, crash logs seemed to indicate there might be a problem with libbluray.

So I compiled test_libbluray.c that comes with the libbluray distribution and ran the program to see if any errors showed up. But that program ran without error. So I dug into what bd_open_files() in libbluray (the function called in Kodi) is all about. The documentation is sparse, but by following the code, it looks like bd_open_files() is meant to be used by a developer writing code that uses libbluray to dynamically install custom dir_open() and file_open() into libbluray. Why a developer would want to do that is beyond me. If bd_open_files() is not called, then default dir_open() and file_open() are used and libbluray seems to work well that way.

For those of you who can install Kodi from source, does this solution work for you?

dgktkr

steo86
Posts: 8
Joined: Mon Dec 04, 2017 11:26 am

Re: libmmbd with kodi18

#7 Post by steo86 » Sun Feb 04, 2018 8:58 am

ok that means the Problem should be reported to kodi Forum?

steo86
Posts: 8
Joined: Mon Dec 04, 2017 11:26 am

Re: libmmbd with kodi18

#8 Post by steo86 » Sun Feb 04, 2018 9:41 am

@dgktkr: many thanks for having a look at the Problem.
Ist possible to post the complete coding changes maybe as an diff-file?
I will then post it to the kodi forum hoping if someone maybe can tell use why it is coded as it is. Maybe they can change it to get kodi out of the box working again with makemkv.

mosquitogang201
Posts: 5
Joined: Sat Dec 23, 2017 3:43 am

Re: libmmbd with kodi18

#9 Post by mosquitogang201 » Sun Feb 04, 2018 1:35 pm

Assuming that playback does work as it is, I think team Kodi would be more amenable to a patch that basically says,

Code: Select all

if (has_libmmbd) use bd_open_disc
else use bd_open_files
libbluray does a similar check we could pull code from, and it defaults to libmmbd when present. So this patch wouldn't alter the way Kodi+libaacs works, but adds an alternative and working code path when makemkv/libmmbd is present.

Other relevant thread is here.

http://www.makemkv.com/forum2/viewtopic.php?f=3&t=16864

It does seem to me like the API between libaacs and libmmbd has diverged a little bit; that said, I'm not sure that makemkv is really intended to mirror the API 100%. It also seems that patching Kodi to work with libmmbd as it is would be much easier.
Last edited by mosquitogang201 on Fri Jul 22, 2022 7:07 pm, edited 1 time in total.

joniw
Posts: 6
Joined: Thu Dec 07, 2017 11:46 pm

Re: libmmbd with kodi18

#10 Post by joniw » Sun Feb 04, 2018 2:57 pm

Hello,
dgktkr wrote:
Here's the thinking (and testing) behind this. Because Kodi crashed with libmmbd installed, but did not crash when only the default libaacs was in place, it sure looked like the fault was in libmmbd. On the other hand, for macOS, crash logs seemed to indicate there might be a problem with libbluray.

dgktkr
i debugged the problem and described it here: https://forum.kodi.tv/showthread.php?ti ... pid2676853.

It looks like the libmmbd does not accept a "NULL" value for the "locator" variable, because it uses strlen without checking for NULL. Libaacs does support a NULL value for the path so its working as expected.

Unfortunately i was not able to compile libmmbd under windows to develop a fix, i am still waiting for the developers to fix it in libmmbd.

Joniw

steo86
Posts: 8
Joined: Mon Dec 04, 2017 11:26 am

Re: libmmbd with kodi18

#11 Post by steo86 » Mon Feb 05, 2018 7:48 am

Sorry I am not able to help coding here because I dont have the skills to do that.
Regarding to this post in the kodi forum replaceing "openfile" with "opendisk" seems to get libmmd-encoding working again with makemkv (as in Kodi 17) but seems to break the new BD-J Menu support in Kodi 18:
https://forum.kodi.tv/showthread.php?ti ... pid2700041
It would be nice to get both working. BD-J-Menus and makemkv encoding in kodi18.
If I understand the post of joniw, integrating acceptung NULL in the libmmd source code would fix this and get both (BD-J menu and libmmd encoding) working again?
Is that right? Maybe an makemkv developer can confirm this?

mike admin
Posts: 4075
Joined: Wed Nov 26, 2008 2:26 am
Contact:

Re: libmmbd with kodi18

#12 Post by mike admin » Mon Feb 05, 2018 8:48 pm

joniw wrote:i debugged the problem and described it here: https://forum.kodi.tv/showthread.php?ti ... pid2676853.
It looks like the libmmbd does not accept a "NULL" value for the "locator" variable, because it uses strlen without checking for NULL. Libaacs does support a NULL value for the path so its working as expected.
Thanks for doing this!
Unfortunately, this is very screwed up. The issue is actually a libbluray fault - they do not have a (good) API that would take both locator and file access functions. As a result xbmc uses an API with access functions only. That means, for example, that libaacs (no mater "real" or mmbd) would be unable to read any discs from BE-enabled drive, as there is no way to for libaacs to issue any scsi commands. Very bad architectural choice, this has to be (properly) fixed in both libbluray and xbmc.
Workaround is possible for most cases, but it requires changes in both libmmbd and makemkvcon. I'll try to get it into next version, however no promises...

dgktkr
Posts: 18
Joined: Thu Dec 30, 2010 7:51 pm

Re: libmmbd with kodi18

#13 Post by dgktkr » Wed Mar 21, 2018 5:36 pm

FWIW

After a good amount of experimentation I've succeeded in getting Kodi 18 to play bluray discs by making changes only in the libmmbd source, recompiling and installing. Kodi and libbluray are unmodified.

The first trick is to use the handle, the second parameter of aacs_set_fopen() in makemkv-oss-1.12.0/libmmbd/src/aacs.cpp, to provide access to data needed to construct the C string path that libmmbd's version of aacs_open_device() requires. For Ubuntu, that's something like "/media/username/bluray_title". The handle that comes though from Kodi + libbluray when they call aacs_set_fopen() is a pointer to a BD-DISC structure. It has a member fs_handle that is a pointer to a C++ string object that can be converted to the required C string. That string can then be given to aacs_open_device() to enable libmmbd to do its thing. Some declarations need to be included in makemkv-oss-1.12.0/libmmbd/src/aacs.cpp so that the C++ string can be extracted from the BD_DISC structure.

Another problem that comes up at this point is that a call that Kodi + libbluray make to libbdplus_init() fails. That is because that call in libbluray require a non-NULL value for one of the variables 'root' or 'device' in libbluray.1.0.2/src/libbluray/disc/bdplus.c. Unless, that is, a function bdplus_set_fopen() exists in libbdplus ( or the linked lilbmmbd). The existence of that function is needed even though its execution is essentially a NOP. And the unmodified libmmbd doesn't have it because it isn't used. The makemkv-oss-1.12.0/libmmbd/src/bdplus.cpp, makemkv-oss-1.12.0/libmmbd/src/bdplus.h and makemkv-oss-1.12.0/libmmbd/src/libmmbd.vers files need to be modified to accommodate the new function in the modified library.

Whether this breaks any functionality of Kodi + libbluray (like BD-J menus), I don't know. Also, this solution will probably be seen as an ugly hack by some, but that's OK. At the very least it should serve as a proof of principle; that it is possible to get libmmbd to be compatible with Kodi 18 and libbluray 1.0.2.

dgktkr

G0llum
Posts: 5
Joined: Sat Mar 24, 2018 8:45 am

Re: libmmbd with kodi18

#14 Post by G0llum » Sat Mar 24, 2018 8:50 am

@dgktkr

Would you mind sharing your changes? I think a lot of Kodi 18 testers would love to be able to use MakeMKV as they did before.

dgktkr
Posts: 18
Joined: Thu Dec 30, 2010 7:51 pm

Re: libmmbd with kodi18

#15 Post by dgktkr » Mon Mar 26, 2018 4:54 pm

G0llum wrote:@dgktkr
Would you mind sharing your changes? I think a lot of Kodi 18 testers would love to be able to use MakeMKV as they did before.
OK. Here are the details.

In makemkv-oss-1.12.0/libmmbd/src/aacs.cpp, the function aacs_open_device() is defined:

Code: Select all

AACS_PUBLIC int __cdecl aacs_open_device(AACS *aacs, const char *path, const char *keyfile_path)
1) Just before that line add the line:

Code: Select all

static std::string *cxx_string_pointer;  // declare a persistent file scope variable
2) Within the aacs_open_device() function definition replace the one line:

Code: Select all

if (mmbd_open((MMBD*)aacs,path)) {  
with the two lines:

Code: Select all

    const char * c_string_path = (*cxx_string_pointer).c_str(); // convert to the C string we're after
    if (mmbd_open((MMBD*)aacs,c_string_path)) {  // change path to c_string_path
3a) In aacs.cpp the definition of aacs_set_fopen() needs to be changed. Replace the first line of the function definition with:

Code: Select all

AACS_PUBLIC void __cdecl aacs_set_fopen(AACS *aacs, void *bd_disc_structure_pointer, void* p)
3b) Populate the body with the lines:

Code: Select all

	BD_DISC bd_disc_structure = *reinterpret_cast<BD_DISC*>(bd_disc_structure_pointer); // Copy the BD_DISC structure

	cxx_string_pointer = reinterpret_cast<std::string*>(bd_disc_structure.fs_handle); // Copy the C++ string object pointer of interest
For the above changes to work properly, add one include and a series of declarations at the beginning of aacs.cpp.

4) Just after the #include <string.h> add:

Code: Select all

#include <string>

typedef struct bd_mutex_s BD_MUTEX;
struct bd_mutex_s {
    void *impl;
};


typedef void    (*fptr_void)(...);
typedef int     (*fptr_int)(...);
typedef int32_t (*fptr_int32)(...);
typedef void*   (*fptr_p_void)(...);

typedef struct bd_aacs BD_AACS;

struct bd_aacs {
    void           *h_libaacs;   /* library handle from dlopen */
    void           *aacs;        /* aacs handle from aacs_open() */

    const uint8_t *disc_id;
    uint32_t       mkbv;

    /* function pointers */
    fptr_int       decrypt_unit;
    fptr_int       decrypt_bus;

    int            impl_id;
};

typedef struct bd_bdplus BD_BDPLUS;

struct bd_bdplus {
    void           *h_libbdplus; /* library handle from dlopen */

    void           *bdplus;      /* bdplus handle from bdplus_open() */

    /* functions */
    fptr_int32     event;
    fptr_p_void    m2ts;
    fptr_int32     m2ts_close;
    fptr_int32     seek;
    fptr_int32     fixup;

    /* old API */
    fptr_p_void    title;

    int impl_id;
};

typedef struct bd_dec BD_DEC;
struct bd_dec {
    int        use_menus;
    BD_AACS   *aacs;
    BD_BDPLUS *bdplus;
};


typedef struct bd_file_s BD_FILE_H;
struct bd_file_s
{
    void* internal;
    void    (*close) (BD_FILE_H *file);
    int64_t (*seek)  (BD_FILE_H *file, int64_t offset, int32_t origin);
    int64_t (*tell)  (BD_FILE_H *file);
    int     (*eof)   (BD_FILE_H *file);
    int64_t (*read)  (BD_FILE_H *file, uint8_t *buf, int64_t size);
    int64_t (*write) (BD_FILE_H *file, const uint8_t *buf, int64_t size);
};

typedef struct
{
    char    d_name[256];
} BD_DIRENT;

typedef struct bd_dir_s BD_DIR_H;
struct bd_dir_s
{
    void* internal;
    void (*close)(BD_DIR_H *dir);
    int (*read)(BD_DIR_H *dir, BD_DIRENT *entry);
};

typedef struct bd_disc BD_DISC;

struct bd_disc {
    BD_MUTEX  ovl_mutex;     /* protect access to overlay root */
    BD_MUTEX  properties_mutex; /* protect access to properties file */

    char     *disc_root;     /* disc filesystem root (if disc is mounted) */
    char     *overlay_root;  /* overlay filesystem root (if set) */

    BD_DEC   *dec;

    void         *fs_handle;
    BD_FILE_H * (*pf_file_open_bdrom)(void *, const char *);
    BD_DIR_H *  (*pf_dir_open_bdrom)(void *, const char *);
    void        (*pf_fs_close)(void *);

    const char   *udf_volid;
    char         *properties_file;  /* NULL if not yet used */

    int8_t        avchd;  /* -1 - unknown. 0 - no. 1 - yes */
};

That should be it for aacs.cpp. No changes are made to aacs.h.

On my system, BD+ discs couldn't be played without further changes (to bdplus.cpp, bdplus.h and libmmbd.vers)

5) After line 32 in bdplus.h, below the prototype for bdplus_init(), add:

Code: Select all

AACS_PUBLIC BDPLUS_CTX* __cdecl bdplus_set_fopen(BDPLUS_CTX* ctx, void *bd_disc_structure_pointer, void* p);
6) After line 47 in bdplus.cpp, just above the definition of bdplus_init(), add:

Code: Select all

// provide a minimal bdplus_set_fopen()
AACS_PUBLIC BDPLUS_CTX* __cdecl bdplus_set_fopen(BDPLUS_CTX* ctx, void *bd_disc_structure_pointer, void* p)
{
    return ctx;
}
7) To make the symbol bdplus_set_fopen visible to users of the library, add the following to the bdplus section within libmmbd.vers:

Code: Select all

  bdplus_set_fopen;
Please report back your experience making these changes.

dgktkr
Last edited by dgktkr on Thu Mar 29, 2018 10:24 pm, edited 3 times in total.

Post Reply