bluray.c 5.9 KB
Newer Older
Accident's avatar
 
Accident committed
1 2 3 4 5 6 7 8 9 10 11
#if HAVE_CONFIG_H
#include "config.h"
#endif

#if HAVE_MALLOC_H
#include <malloc.h>
#endif

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
cRTrn13's avatar
cRTrn13 committed
12

cRTrn13's avatar
cRTrn13 committed
13
#include <dlfcn.h>
cRTrn13's avatar
cRTrn13 committed
14
#include <stdio.h>
cRTrn13's avatar
cRTrn13 committed
15

cRTrn13's avatar
cRTrn13 committed
16
#include "bluray.h"
cRTrn13's avatar
cRTrn13 committed
17
#include "util/macro.h"
cRTrn13's avatar
cRTrn13 committed
18
#include "util/logging.h"
cRTrn13's avatar
cRTrn13 committed
19

cRTrn13's avatar
cRTrn13 committed
20 21
BLURAY *bd_open(const char* device_path, const char* keyfile_path)
{
22
    BLURAY *bd = calloc(1, sizeof(BLURAY));
cRTrn13's avatar
cRTrn13 committed
23

cRTrn13's avatar
cRTrn13 committed
24
    if (device_path) {
25
        bd->device_path = strdup(device_path);
cRTrn13's avatar
cRTrn13 committed
26

cRTrn13's avatar
cRTrn13 committed
27 28 29 30
        bd->aacs = NULL;
        bd->h_libaacs = NULL;
        bd->fp = NULL;

cRTrn13's avatar
Fix  
cRTrn13 committed
31
        if (keyfile_path) {
cRTrn13's avatar
cRTrn13 committed
32
            if ((bd->h_libaacs = dlopen("libaacs.so", RTLD_LAZY))) {
cRTrn13's avatar
cRTrn13 committed
33 34 35
                fptr_p_void fptr;
                uint8_t *vid;

cRTrn13's avatar
cRTrn13 committed
36
                DEBUG(DBG_BLURAY, "Downloaded libaacs (0x%08x)\n", bd->h_libaacs);
cRTrn13's avatar
cRTrn13 committed
37

cRTrn13's avatar
cRTrn13 committed
38 39 40 41 42 43 44 45 46 47 48 49 50
                if ((fptr = dlsym(bd->h_libaacs, "aacs_open"))) {
                    if ((bd->aacs = fptr(device_path, keyfile_path))) {
                        if ((fptr = dlsym(bd->h_libaacs, "aacs_get_vid"))) {
                            vid = fptr(bd->aacs);
                        }

                        if ((bd->h_libbdplus = dlopen("libbdplus.so", RTLD_LAZY))) {
                            DEBUG(DBG_BLURAY, "Downloaded libbdplus (0x%08x)\n", bd->h_libbdplus);

                            if ((fptr = dlsym(bd->h_libbdplus, "bdplus_open"))) {
                                if (!(bd->bdplus = fptr(device_path, keyfile_path, vid))) {
                                    DEBUG(DBG_BLURAY, "libbdplus ret NULL!\n");
                                }
cRTrn13's avatar
Fix  
cRTrn13 committed
51
                            }
cRTrn13's avatar
cRTrn13 committed
52
                        } else {
53
                            DEBUG(DBG_BLURAY, "libbdplus not found!\n");
cRTrn13's avatar
cRTrn13 committed
54 55
                        }
                    } else {
56
                        DEBUG(DBG_BLURAY | DBG_CRIT, "libaacs failed to initialize! If this disc is encrypted, you will not be able to play it\n");
cRTrn13's avatar
cRTrn13 committed
57 58
                    }
                }
cRTrn13's avatar
cRTrn13 committed
59
            } else {
60
                DEBUG(DBG_BLURAY, "libaacs not found!\n");
cRTrn13's avatar
cRTrn13 committed
61 62
            }
        } else {
cRTrn13's avatar
cRTrn13 committed
63
            DEBUG(DBG_BLURAY | DBG_CRIT, "No keyfile provided. You will not be able to make use of crypto functionality (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
64 65
        }

66 67
        bd->int_buf_off = 6144;

cRTrn13's avatar
Fix  
cRTrn13 committed
68
        DEBUG(DBG_BLURAY, "BLURAY initialized! (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
69
    } else {
cRTrn13's avatar
cRTrn13 committed
70 71
        X_FREE(bd);

cRTrn13's avatar
cRTrn13 committed
72
        DEBUG(DBG_BLURAY | DBG_CRIT, "No device path provided!\n");
cRTrn13's avatar
cRTrn13 committed
73 74 75 76 77 78 79
    }

    return bd;
}

void bd_close(BLURAY *bd)
{
cRTrn13's avatar
cRTrn13 committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93
    if (bd->h_libaacs) {
        if (bd->aacs) {
            fptr_p_void fptr = dlsym(bd->h_libaacs, "aacs_close");
            fptr(bd->aacs);
        }

        dlclose(bd->h_libaacs);
    }

    if (bd->h_libbdplus) {
        if (bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_close");
            fptr(bd->bdplus);
        }
cRTrn13's avatar
cRTrn13 committed
94

95 96
        dlclose(bd->h_libaacs);
    }
cRTrn13's avatar
cRTrn13 committed
97

cRTrn13's avatar
cRTrn13 committed
98 99 100
    if (bd->fp) {
        file_close(bd->fp);
    }
cRTrn13's avatar
cRTrn13 committed
101

102 103
    X_FREE(bd->device_path);

cRTrn13's avatar
cRTrn13 committed
104
    DEBUG(DBG_BLURAY, "BLURAY destroyed! (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
105 106

    X_FREE(bd);
cRTrn13's avatar
cRTrn13 committed
107
}
cRTrn13's avatar
cRTrn13 committed
108

cRTrn13's avatar
cRTrn13 committed
109
uint64_t bd_seek(BLURAY *bd, uint64_t pos)
cRTrn13's avatar
cRTrn13 committed
110 111 112 113
{
    if (pos < bd->s_size) {
        bd->s_pos = pos - (pos % 6144);

cRTrn13's avatar
cRTrn13 committed
114
        file_seek(bd->fp, bd->s_pos, SEEK_SET);
115

cRTrn13's avatar
cRTrn13 committed
116 117 118 119 120
        if (bd->h_libbdplus && bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_seek");
            fptr(bd->bdplus, bd->s_pos);
        }

121 122
        bd->int_buf_off = 6144;

123
        DEBUG(DBG_BLURAY, "Seek to %ld (0x%08x)\n", bd->s_pos, bd);
cRTrn13's avatar
cRTrn13 committed
124 125 126 127 128 129 130
    }

    return bd->s_pos;
}

int bd_read(BLURAY *bd, unsigned char *buf, int len)
{
131
    if (bd->fp) {
132 133
        int out_len = 0;

134 135
        DEBUG(DBG_BLURAY, "Reading unit [%d bytes] at %ld... (0x%08x)\n", len, bd->s_pos, bd);

hpi1's avatar
hpi1 committed
136
        if (len + bd->s_pos <= bd->s_size) {
137 138 139
            while (out_len < len) {
                if (bd->int_buf_off == 6144) {
                    int read_len;
140

141 142 143 144 145
                    if ((read_len = file_read(bd->fp, bd->int_buf, 6144)) == 6144) {
                        if (bd->h_libaacs && bd->aacs) {
                            if ((bd->libaacs_decrypt_unit = dlsym(bd->h_libaacs, "aacs_decrypt_unit"))) {
                                if (!bd->libaacs_decrypt_unit(bd->aacs, bd->int_buf, read_len, 0)) {
                                    DEBUG(DBG_BLURAY, "Unable decrypt unit! (0x%08x)\n", bd);
146

147 148
                                    return 0;
                                }
cRTrn13's avatar
cRTrn13 committed
149

150 151 152 153 154
                                if (bd->h_libbdplus && bd->bdplus) {
                                    fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_fixup");
                                    fptr(bd->bdplus, bd->int_buf, read_len);
                                }
                            }
cRTrn13's avatar
cRTrn13 committed
155
                        }
156
                    }
157
                    bd->int_buf_off = 0;
cRTrn13's avatar
cRTrn13 committed
158 159
                }

160 161
                buf[out_len++] = bd->int_buf[bd->int_buf_off++];
            }
cRTrn13's avatar
cRTrn13 committed
162

163
            bd->s_pos += len;
164

165 166 167
            DEBUG(DBG_BLURAY, "%d bytes read OK! (0x%08x)\n", len, bd);

            return len;
cRTrn13's avatar
cRTrn13 committed
168 169 170
        }
    }

171 172
    DEBUG(DBG_BLURAY, "No valid title selected! (0x%08x)\n", bd->s_pos);

cRTrn13's avatar
cRTrn13 committed
173 174
    return 0;
}
cRTrn13's avatar
cRTrn13 committed
175

cRTrn13's avatar
cRTrn13 committed
176 177 178 179 180 181 182 183 184 185 186 187 188
int bd_select_title(BLURAY *bd, uint64_t title)
{
    char f_name[100];

    memset(f_name, 0, sizeof(f_name));
    snprintf(f_name, 100, "%s/BDMV/STREAM/%05ld.m2ts", bd->device_path, title);

    bd->s_size = 0;
    bd->s_pos = 0;

    if ((bd->fp = file_open(f_name, "rb"))) {
        file_seek(bd->fp, 0, SEEK_END);
        if ((bd->s_size = file_tell(bd->fp))) {
cRTrn13's avatar
cRTrn13 committed
189 190 191 192 193
            if (bd->h_libbdplus && bd->bdplus) {
                fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_set_title");
                fptr(bd->bdplus, title);
            }

194 195 196
            bd_seek(bd, 0);

            DEBUG(DBG_BLURAY, "Title %s selected! (0x%08x)\n", f_name, bd);
cRTrn13's avatar
cRTrn13 committed
197 198 199

            return 1;
        }
200 201

        DEBUG(DBG_BLURAY, "Title %s empty! (0x%08x)\n", f_name, bd);
cRTrn13's avatar
cRTrn13 committed
202 203
    }

cRTrn13's avatar
cRTrn13 committed
204
    DEBUG(DBG_BLURAY | DBG_CRIT, "Unable to select title %s! (0x%08x)\n", f_name, bd);
205

cRTrn13's avatar
cRTrn13 committed
206 207
    return 0;
}
208 209 210 211 212

uint64_t bd_get_title_size(BLURAY *bd)
{
    return bd->s_size;
}
cRTrn13's avatar
cRTrn13 committed
213 214 215 216 217

uint64_t bd_tell(BLURAY *bd)
{
    return bd->s_pos;
}