~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to .pc/50_Hurd_PATH_MAX.patch/stream/stream_bd.c

  • Committer: Gauvain Pocentek
  • Date: 2012-03-06 11:59:12 UTC
  • mfrom: (66.1.15 precise)
  • Revision ID: gauvain@pocentek.net-20120306115912-h9d6kt9j0l532oo5
* Merge from Ubuntu:
  - put back faac support
  - recommends apport-hooks-medibuntu
  - change Maintainer, Uploaders & Vcs-* fields.
* New upstream snapshot
* upload to unstable
* Build against external libmpeg2
* drop 51_FTBFS_arm.patch again
* no longer build depend on libcdparanoia-dev on the Hurd
* Fix FTBFS on the hurd.
  Thanks to Samuel Thibault <sthibault@debian.org> (Closes: #654974)
* Fix FTBFS on arm
* New upstream snapshot, Closes: #650339, #643621, #481807
* Imported Upstream version 1.0~rc4+svn34492
* Bump standards version
* Bump dependency on libav >= 4:0.8~, Closes: #653887
* Fix build-indep
* Build mplayer-gui again, Closes: #568514
* Drop debian/all-lang-config-mak.sh, no longer needed
* include .dfsg1 in version number
* remove get-orig-source target
* no longer prune compiler flags from the environment
* No longer advertise nor build 3fdx, mga and dxr3 backends,
  Closes: #496106, #442181, #533546
* beautify mplayer version identification string
* Brown paperbag upload.
* Next try to fix build failure on sparce after recent binutils change.
* Brown paperbag upload.
* Really fix build failure on sparc after recent binutils change.
* Properly set Replaces/Conflicts on mplayer2{,-dbg} to avoid
  file overwrite errors.
* Adjust versioning of mplayer listed in the mplayer-dbg's Depends field.
* Fix build failure on sparc after recent binutils change.
* Urgency medium bumped because of RC-level bugfix
  and speeding up x264 transition.
* Update to my @debian.org email.
* Upload to unstable
* Enable joystick support on Linux only, Closes: #638408
* Rebuild fixes toolchain issue on arm, Closes: #637077
* New upstream snapshot
* following the discussion started by Diego Biurrun <diego@biurrun.de>
  in debian-devel, I have prepared a new packaging of 'mplayer'
  (with code that comes from CVS)
* the upstream tar.bz cannot be distributed by Debian, since it contains
   CSS code; so I am repackaging it 
* I have tried my best to address all known issues:
  - the package contains the detailed Copyright made by Diego Biurrun 
  - the package does not contain CSS code, or  AFAIK other code on which 
     there is active patent enforcement
  - there is a script  debian/cvs-changelog.sh  that shows all changes
     done to files included in this source.
    This should comply with GPLv2 sec 2.a  (in spirit if not in letter)
    For this reason, the source code contains CVS directories.
* needs   make (>= 3.80) for 'html-chunked-$(1)' in DOCS/xml/Makefile

* some corrections, as suggested Diego Biurrun
  - binary codecs should go into /usr/lib/codecs (upstream default)
  - better template 'mplayer/install_codecs'
  - an empty 'font=' in mplayer.conf breaks mplayer: postinst corrected
* correction in 'mplayer/cfgnote'
* better mplayer.postinst and mplayer.config

* New upstream release
* better debian/copyright file
* do not ship a skin
* New upstream release
* changed DEB_BUILD_OPTIONS to DEB_BUILD_CONFIGURE ,
  DEB_BUILD_OPTIONS is used as in debian policy
* use gcc-3.4
* changed xlibs-dev to a long list of dependencies, for Debian/etch
* try to adhere to  http://www.mplayerhq.hu/DOCS/tech/binary-packaging.txt
  (see README.Debian for details)
* removed dependency on xlibmesa-dev, disabled opengl
* New upstream release
* Simon McVittie <hacks@pseudorandom.co.uk> wonderful work:
- Work around Debian bug #267442 (glibc's sys/uio.h and gcc's altivec.h have
  conflicting uses for __vector) by re-ordering #includes
- Fix potential symlink attack in ./configure
- Disable support for binary codecs on platforms for which those codecs
  aren't available; also disable the corresponding Debconf note when it's
  inappropriate
- Changed Build-Depends: so it works in pbuilder
- Explicitly build-depend on libjpeg62-dev, libfontconfig1-dev,
  libungif4-dev 
- Tweak debian/rules to avoid certain errors being ignored
- Use --language=all
* provide a target  'debian/rules get-orig-source' 
  that recreates the orig.tar.gz ; then use the above orig.tar.gz
* rewrote some parts of debian/rules
* don't clean and recompile docs if upstream ships them
* mplayer-doc was shipping too much stuff
* translated man pages where not installed properly
* compile with libdv4-dev
* correct README.Debian
* Forgot build-dep on libtheora
* Must not depend on libxvidcore
* New upstream release
* new release.
* rc1 to become 0.90
* new pre-release
* new pre-release
* gtk bug fixed.
* new release.
* version bumped
* 0.60 pre2 release
* 0.60 pre-release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Blu-ray stream playback
 
3
 * by cRTrn13 <crtrn13-at-gmail.com> 2009
 
4
 *
 
5
 * This file is part of MPlayer.
 
6
 *
 
7
 * MPlayer is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * MPlayer is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License along
 
18
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
 
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
 
 
22
#include <stdio.h>
 
23
#include <limits.h>
 
24
#include <ctype.h>
 
25
#include "libavutil/common.h"
 
26
#include "libavutil/aes.h"
 
27
#include "libavutil/sha.h"
 
28
#include "libmpdemux/demuxer.h"
 
29
#include "libavutil/intreadwrite.h"
 
30
#include "m_struct.h"
 
31
#include "m_option.h"
 
32
#include "mp_msg.h"
 
33
#include "stream.h"
 
34
#include "stream_bd.h"
 
35
 
 
36
static const int   BD_UNIT_SIZE = 6144;
 
37
static const char BD_UKF_PATH[]  = "%s/AACS/Unit_Key_RO.inf";
 
38
static const char BD_M2TS_PATH[] = "%s/BDMV/STREAM/%05d.m2ts";
 
39
static const char BD_CLIPINF_PATH[] = "%s/BDMV/CLIPINF/%05d.clpi";
 
40
 
 
41
static const char DEFAULT_BD_DEVICE[] = "/mnt/bd";
 
42
 
 
43
static const struct stream_priv_s {
 
44
    int   title;
 
45
    char *device;
 
46
} stream_priv_dflts = {
 
47
    0,
 
48
    NULL
 
49
};
 
50
 
 
51
// Format: bd://[title][</mntlocation>]
 
52
// --> e.g.: bd://117/media/THE_MUMMY/
 
53
// --> or   bd://152
 
54
// instead of directly, mount location can also be gotten through -dvd-device
 
55
#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
 
56
static const m_option_t stream_opts_fields[] = {
 
57
    { "hostname", ST_OFF(title),  CONF_TYPE_INT, M_OPT_RANGE, 0, 99999, NULL},
 
58
    { "filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL},
 
59
    { NULL, NULL, 0, 0, 0, 0,  NULL }
 
60
};
 
61
 
 
62
static const struct m_struct_st stream_opts = {
 
63
    "bd",
 
64
    sizeof(struct stream_priv_s),
 
65
    &stream_priv_dflts,
 
66
    stream_opts_fields
 
67
};
 
68
 
 
69
typedef union {
 
70
    uint64_t u64[2];
 
71
    uint8_t  u8[16];
 
72
} key;
 
73
 
 
74
static const key BD_CBC_IV = {
 
75
    .u8 = {
 
76
    0x0b, 0xa0, 0xf8, 0xdd, 0xfe, 0xa6, 0x1f, 0xb3,
 
77
    0xd8, 0xdf, 0x9f, 0x56, 0x6a, 0x05, 0x0f, 0x78
 
78
    }
 
79
};
 
80
 
 
81
struct uks {
 
82
    int  count;
 
83
    key *keys;
 
84
};
 
85
 
 
86
// This is just a guess
 
87
#define LANG_NAME_LEN 20
 
88
 
 
89
struct lang_map {
 
90
    int id;
 
91
    int type;
 
92
    char lang_name[LANG_NAME_LEN + 1];
 
93
};
 
94
 
 
95
struct bd_priv {
 
96
    key           vuk;
 
97
    key           iv;
 
98
    int           title;
 
99
    const char   *device;
 
100
    stream_t     *title_file;
 
101
    struct AVAES *aescbc;
 
102
    struct AVAES *aeseed;
 
103
    off_t         pos;
 
104
    struct uks    uks;
 
105
    int           nr_lang_maps;
 
106
    struct lang_map *lang_maps;
 
107
};
 
108
 
 
109
static void bd_stream_close(stream_t *s)
 
110
{
 
111
    struct bd_priv *bd = s->priv;
 
112
    free_stream(bd->title_file);
 
113
    av_free(bd->aescbc);
 
114
    av_free(bd->aeseed);
 
115
    free(bd->uks.keys);
 
116
    free(bd);
 
117
}
 
118
 
 
119
static int bd_stream_seek(stream_t *s, off_t pos)
 
120
{
 
121
    struct bd_priv *bd = s->priv;
 
122
 
 
123
    // must seek to start of unit
 
124
    pos -= pos % BD_UNIT_SIZE;
 
125
    if (!stream_seek(bd->title_file, pos)) {
 
126
        s->eof = 1;
 
127
        return 0;
 
128
    }
 
129
 
 
130
    bd->pos = pos;
 
131
    s->pos  = pos;
 
132
 
 
133
    return 1;
 
134
}
 
135
 
 
136
#define ID_STR_LEN 41
 
137
static void id2str(const uint8_t *id, int idlen, char dst[ID_STR_LEN])
 
138
{
 
139
    int i;
 
140
    idlen = FFMIN(idlen, 20);
 
141
    for (i = 0; i < idlen; i++)
 
142
        snprintf(dst + 2*i, 3, "%02"PRIX8, id[i]);
 
143
}
 
144
 
 
145
static int find_vuk(struct bd_priv *bd, const uint8_t discid[20])
 
146
{
 
147
    char line[1024];
 
148
    char filename[PATH_MAX];
 
149
    const char *home;
 
150
    int vukfound = 0;
 
151
    stream_t *file;
 
152
    char idstr[ID_STR_LEN];
 
153
 
 
154
    // look up discid in KEYDB.cfg to get VUK
 
155
    home = getenv("HOME");
 
156
    snprintf(filename, sizeof(filename), "%s/.dvdcss/KEYDB.cfg", home);
 
157
    file = open_stream(filename, NULL, NULL);
 
158
    if (!file) {
 
159
        mp_msg(MSGT_OPEN,MSGL_ERR,
 
160
               "Cannot open VUK database file %s\n", filename);
 
161
        return 0;
 
162
    }
 
163
    id2str(discid, 20, idstr);
 
164
    while (stream_read_line(file, line, sizeof(line), 0)) {
 
165
        char *vst;
 
166
 
 
167
        // file is built up this way:
 
168
        // DISCID = title | V | VUK
 
169
        // or
 
170
        // DISCID = title | key-pair
 
171
        // key-pair = V | VUK
 
172
        // or         D | Date
 
173
        // or         M | M-key???
 
174
        // or         I | I-Key
 
175
        // can be followed by ; and comment
 
176
 
 
177
        if (strncasecmp(line, idstr, 40))
 
178
            continue;
 
179
        mp_msg(MSGT_OPEN, MSGL_V, "KeyDB found Entry for DiscID:\n%s\n", line);
 
180
 
 
181
        vst = strstr(line, "| V |");
 
182
        if (!vst)
 
183
            break;
 
184
        vst += 6;
 
185
        while (isspace(*vst)) vst++;
 
186
        if (sscanf(vst,      "%16"SCNx64, &bd->vuk.u64[0]) != 1)
 
187
            continue;
 
188
        if (sscanf(vst + 16, "%16"SCNx64, &bd->vuk.u64[1]) != 1)
 
189
            continue;
 
190
        bd->vuk.u64[0] = av_be2ne64(bd->vuk.u64[0]);
 
191
        bd->vuk.u64[1] = av_be2ne64(bd->vuk.u64[1]);
 
192
        vukfound = 1;
 
193
    }
 
194
    free_stream(file);
 
195
    return vukfound;
 
196
}
 
197
 
 
198
static int bd_get_uks(struct bd_priv *bd)
 
199
{
 
200
    unsigned char *buf;
 
201
    size_t file_size;
 
202
    int pos;
 
203
    int i;
 
204
    struct AVAES *a;
 
205
    struct AVSHA *asha;
 
206
    stream_t *file;
 
207
    char filename[PATH_MAX];
 
208
    uint8_t discid[20];
 
209
    char idstr[ID_STR_LEN];
 
210
 
 
211
    snprintf(filename, sizeof(filename), BD_UKF_PATH, bd->device);
 
212
    file = open_stream(filename, NULL, NULL);
 
213
    if (!file) {
 
214
        mp_msg(MSGT_OPEN, MSGL_ERR,
 
215
               "Cannot open file %s to get UK and DiscID\n", filename);
 
216
        return 0;
 
217
    }
 
218
    file_size = file->end_pos;
 
219
    if (file_size <= 0 || file_size > 10 * 1024* 1024) {
 
220
        mp_msg(MSGT_OPEN, MSGL_ERR, "File %s too large\n", filename);
 
221
        free_stream(file);
 
222
        return 0;
 
223
    }
 
224
    buf = av_malloc(file_size);
 
225
    stream_read(file, buf, file_size);
 
226
    free_stream(file);
 
227
 
 
228
    // get discid from file
 
229
    asha = av_malloc(av_sha_size);
 
230
    av_sha_init(asha, 160);
 
231
    av_sha_update(asha, buf, file_size);
 
232
    av_sha_final(asha, discid);
 
233
    av_free(asha);
 
234
 
 
235
    if (!find_vuk(bd, discid)) {
 
236
        id2str(discid, 20, idstr);
 
237
        mp_msg(MSGT_OPEN, MSGL_ERR,
 
238
               "No Volume Unique Key (VUK) found for this Disc: %s\n", idstr);
 
239
        av_free(buf);
 
240
        return 0;
 
241
    }
 
242
 
 
243
    pos = AV_RB32(buf);
 
244
    if (pos < file_size) {
 
245
        int key_pos = pos + 48;
 
246
        int max_count = (file_size - key_pos - 16) / 48;
 
247
        bd->uks.count = AV_RB16(&buf[pos]);
 
248
        if (max_count < bd->uks.count) {
 
249
            mp_msg(MSGT_OPEN, MSGL_ERR,
 
250
                   "File to small for key count %i, using %i\n",
 
251
                   bd->uks.count, max_count);
 
252
            bd->uks.count = max_count;
 
253
        }
 
254
        bd->uks.keys  = calloc(bd->uks.count, sizeof(key));
 
255
 
 
256
        a = av_malloc(av_aes_size);
 
257
        av_aes_init(a, bd->vuk.u8, 128, 1);
 
258
 
 
259
        id2str(discid, 20, idstr);
 
260
        mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_BD_DISCID=%s\n", idstr);
 
261
        id2str(bd->vuk.u8, 16, idstr);
 
262
        mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_BD_VUK=%s\n", idstr);
 
263
 
 
264
        for (i = 0; i < bd->uks.count; i++) {
 
265
            av_aes_crypt(a, bd->uks.keys[i].u8, &buf[key_pos], 1, NULL, 1); // decrypt unit key
 
266
            key_pos += 48;
 
267
        }
 
268
 
 
269
        av_free(a);
 
270
    }
 
271
 
 
272
    av_free(buf);
 
273
    return 1;
 
274
}
 
275
 
 
276
// NOTE: we assume buf is sufficiently aligned to 64 bit read/writes
 
277
static off_t bd_read(struct bd_priv *bd, uint8_t *buf, int len)
 
278
{
 
279
    int read_len;
 
280
    int unit_offset = bd->pos % BD_UNIT_SIZE;
 
281
    len &= ~15;
 
282
    if (!len)
 
283
        return 0;
 
284
 
 
285
    read_len = stream_read(bd->title_file, buf, len);
 
286
    if (read_len != len)
 
287
        return -1;
 
288
 
 
289
    if (unit_offset) {
 
290
        int decrypt_len = FFMIN(len, BD_UNIT_SIZE - unit_offset);
 
291
        av_aes_crypt(bd->aescbc, buf, buf, decrypt_len / 16, bd->iv.u8, 1);
 
292
        buf += decrypt_len;
 
293
        len -= decrypt_len;
 
294
    }
 
295
    while (len) {
 
296
        int decrypt_len = FFMIN(len, BD_UNIT_SIZE);
 
297
        // reset aes context as at start of unit
 
298
        key enc_seed;
 
299
        bd->iv = BD_CBC_IV;
 
300
 
 
301
        // perform encryption of first 16 bytes of unit (seed)
 
302
        av_aes_crypt(bd->aeseed, enc_seed.u8, buf, 1, NULL, 0);
 
303
 
 
304
        // perform xor
 
305
        enc_seed.u64[0] ^= AV_RN64A(buf);
 
306
        enc_seed.u64[1] ^= AV_RN64A(buf + 8);
 
307
 
 
308
        // set uk AES-CBC key from enc_seed and BD_CBC_IV
 
309
        av_aes_init(bd->aescbc, enc_seed.u8, 128, 1);
 
310
 
 
311
        // decrypt
 
312
        av_aes_crypt(bd->aescbc, &buf[16], &buf[16],
 
313
                     (decrypt_len - 16) / 16, bd->iv.u8, 1);
 
314
        buf += decrypt_len;
 
315
        len -= decrypt_len;
 
316
    }
 
317
 
 
318
    bd->pos += read_len;
 
319
 
 
320
    return read_len;
 
321
}
 
322
 
 
323
static int bd_stream_fill_buffer(stream_t *s, char *buf, int len)
 
324
{
 
325
    int read_len;
 
326
    struct bd_priv *bd = s->priv;
 
327
 
 
328
    read_len = bd_read(bd, buf, len);
 
329
 
 
330
    s->pos = bd->pos;
 
331
 
 
332
    return read_len;
 
333
}
 
334
 
 
335
static int is_video_type(int type)
 
336
{
 
337
    switch (type) {
 
338
    case 1:
 
339
    case 2:
 
340
    case 0x10:
 
341
    case 0x1b:
 
342
    case 0xD1:
 
343
    case 0xEA:
 
344
        return 1;
 
345
    }
 
346
    return 0;
 
347
}
 
348
 
 
349
static int is_audio_type(int type)
 
350
{
 
351
    switch (type) {
 
352
    case 3:
 
353
    case 4:
 
354
    case 0x0f:
 
355
    case 0x11:
 
356
    case 0x81:
 
357
    case 0x8A:
 
358
    case 0x82:
 
359
    case 0x85:
 
360
    case 0x86:
 
361
        return 1;
 
362
    }
 
363
    return 0;
 
364
}
 
365
 
 
366
static int is_sub_type(int type)
 
367
{
 
368
    switch (type) {
 
369
    case 0x90:
 
370
        return 1;
 
371
    }
 
372
    return 0;
 
373
}
 
374
 
 
375
const char *bd_lang_from_id(stream_t *s, int id)
 
376
{
 
377
    struct bd_priv *bd = s->priv;
 
378
    int i;
 
379
    for (i = 0; i < bd->nr_lang_maps; i++) {
 
380
        if (bd->lang_maps[i].id == id)
 
381
            return bd->lang_maps[i].lang_name;
 
382
    }
 
383
    return NULL;
 
384
}
 
385
 
 
386
int bd_aid_from_lang(stream_t *s, const char *lang)
 
387
{
 
388
    struct bd_priv *bd = s->priv;
 
389
    int i;
 
390
    for (i = 0; i < bd->nr_lang_maps; i++) {
 
391
        if (is_audio_type(bd->lang_maps[i].type) &&
 
392
            strstr(bd->lang_maps[i].lang_name, lang))
 
393
            return bd->lang_maps[i].id;
 
394
    }
 
395
    return -1;
 
396
}
 
397
 
 
398
int bd_sid_from_lang(stream_t *s, const char *lang)
 
399
{
 
400
    struct bd_priv *bd = s->priv;
 
401
    int i;
 
402
    for (i = 0; i < bd->nr_lang_maps; i++) {
 
403
        if (is_sub_type(bd->lang_maps[i].type) &&
 
404
            strstr(bd->lang_maps[i].lang_name, lang))
 
405
            return bd->lang_maps[i].id;
 
406
    }
 
407
    return -1;
 
408
}
 
409
 
 
410
static void get_clipinf(struct bd_priv *bd)
 
411
{
 
412
    int i;
 
413
    int langmap_offset, index_offset, end_offset;
 
414
    char filename[PATH_MAX];
 
415
    stream_t *file;
 
416
 
 
417
    snprintf(filename, sizeof(filename), BD_CLIPINF_PATH, bd->device, bd->title);
 
418
    file = open_stream(filename, NULL, NULL);
 
419
    if (!file) {
 
420
        mp_msg(MSGT_OPEN, MSGL_ERR, "Cannot open clipinf %s\n", filename);
 
421
        return;
 
422
    }
 
423
    if (stream_read_qword(file) != AV_RB64("HDMV0200")) {
 
424
        mp_msg(MSGT_OPEN, MSGL_ERR, "Unknown clipinf format\n");
 
425
        return;
 
426
    }
 
427
    stream_read_dword(file); // unknown offset
 
428
    langmap_offset = stream_read_dword(file);
 
429
    index_offset = stream_read_dword(file);
 
430
    end_offset = stream_read_dword(file);
 
431
 
 
432
    // read language <-> stream id mappings
 
433
    stream_seek(file, langmap_offset);
 
434
    stream_read_dword(file); // size
 
435
    stream_skip(file, 8); // unknown
 
436
    bd->nr_lang_maps = stream_read_char(file); // number of entries
 
437
    stream_read_char(file); // unknown
 
438
 
 
439
    bd->lang_maps = calloc(bd->nr_lang_maps, sizeof(*bd->lang_maps));
 
440
    for (i = 0; i < bd->nr_lang_maps; i++) {
 
441
        int type;
 
442
        bd->lang_maps[i].id = stream_read_word(file);
 
443
        stream_read_char(file); // unknown
 
444
        type = stream_read_char(file);
 
445
        if (!is_video_type(type) && !is_audio_type(type) && !is_sub_type(type))
 
446
            mp_msg(MSGT_OPEN, MSGL_WARN, "Unknown type %x in clipinf\n", type);
 
447
        bd->lang_maps[i].type = type;
 
448
        stream_read(file, bd->lang_maps[i].lang_name, LANG_NAME_LEN);
 
449
    }
 
450
 
 
451
    free_stream(file);
 
452
}
 
453
 
 
454
static int bd_stream_open(stream_t *s, int mode, void* opts, int* file_format)
 
455
{
 
456
    char filename[PATH_MAX];
 
457
 
 
458
    struct stream_priv_s* p = opts;
 
459
    struct bd_priv *bd = calloc(1, sizeof(*bd));
 
460
 
 
461
    if (p->device)
 
462
        bd->device = p->device;
 
463
    else if (bluray_device)
 
464
        bd->device = bluray_device;
 
465
    else
 
466
        bd->device = DEFAULT_BD_DEVICE;
 
467
 
 
468
    s->sector_size = BD_UNIT_SIZE;
 
469
    s->read_chunk  = 32 * BD_UNIT_SIZE;
 
470
    s->flags       = STREAM_READ | MP_STREAM_SEEK;
 
471
    s->fill_buffer = bd_stream_fill_buffer;
 
472
    s->seek        = bd_stream_seek;
 
473
    s->close       = bd_stream_close;
 
474
    s->start_pos   = 0;
 
475
    s->priv        = bd;
 
476
    s->type        = STREAMTYPE_BD;
 
477
    s->url         = strdup("bd://");
 
478
 
 
479
    bd->pos   = 0;
 
480
    bd->title = p->title;
 
481
 
 
482
    // get and decrypt unit keys
 
483
    if (!bd_get_uks(bd))
 
484
        return STREAM_ERROR;
 
485
 
 
486
    bd->aescbc = av_malloc(av_aes_size);
 
487
    bd->aeseed = av_malloc(av_aes_size);
 
488
 
 
489
    // set up AES key from uk
 
490
    av_aes_init(bd->aeseed, bd->uks.keys[0].u8, 128, 0);
 
491
 
 
492
    snprintf(filename, sizeof(filename), BD_M2TS_PATH, bd->device, bd->title);
 
493
    mp_msg(MSGT_OPEN, MSGL_STATUS, "Opening %s\n", filename);
 
494
    bd->title_file = open_stream(filename, NULL, NULL);
 
495
    if (!bd->title_file)
 
496
        return STREAM_ERROR;
 
497
    s->end_pos = bd->title_file->end_pos;
 
498
 
 
499
    get_clipinf(bd);
 
500
 
 
501
    return STREAM_OK;
 
502
}
 
503
 
 
504
const stream_info_t stream_info_bd = {
 
505
    "Blu-ray",
 
506
    "bd",
 
507
    "cRTrn13",
 
508
    "",
 
509
    bd_stream_open,
 
510
    { "bd", NULL },
 
511
    &stream_opts,
 
512
    1
 
513
};