282aae299b8f91c9f703fbceeb088a33111c2762
[vlc.git] / modules / access / bluray.c
1 /*****************************************************************************
2  * bluray.c: Blu-ray disc support plugin
3  *****************************************************************************
4  * Copyright © 2010-2012 VideoLAN, VLC authors and libbluray AUTHORS
5  *
6  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
7  *          Hugo Beauzée-Luyssen <hugo@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <assert.h>
29
30 #if defined (HAVE_MNTENT_H) && defined(HAVE_SYS_STAT_H)
31 # include <mntent.h>
32 # include <sys/stat.h>
33 #endif
34 #include <fcntl.h>      /* O_* */
35 #include <unistd.h>     /* close() */
36
37 #ifdef __APPLE__
38 # include <sys/stat.h>
39 # include <sys/param.h>
40 # include <sys/ucred.h>
41 # include <sys/mount.h>
42 #endif
43
44 #include <vlc_common.h>
45 #include <vlc_plugin.h>
46 #include <vlc_demux.h>                      /* demux_t */
47 #include <vlc_input.h>                      /* Seekpoints, chapters */
48 #include <vlc_atomic.h>
49 #include <vlc_dialog.h>                     /* BD+/AACS warnings */
50 #include <vlc_vout.h>                       /* vout_PutSubpicture / subpicture_t */
51 #include <vlc_url.h>                        /* vlc_path2uri */
52 #include <vlc_iso_lang.h>
53 #include <vlc_fs.h>
54
55 /* FIXME we should find a better way than including that */
56 #include "../../src/text/iso-639_def.h"
57
58
59 #include <libbluray/bluray.h>
60 #include <libbluray/bluray-version.h>
61 #include <libbluray/keys.h>
62 #include <libbluray/meta_data.h>
63 #include <libbluray/overlay.h>
64
65 /*****************************************************************************
66  * Module descriptor
67  *****************************************************************************/
68
69 #define BD_MENU_TEXT        N_("Blu-ray menus")
70 #define BD_MENU_LONGTEXT    N_("Use Blu-ray menus. If disabled, "\
71                                 "the movie will start directly")
72 #define BD_REGION_TEXT      N_("Region code")
73 #define BD_REGION_LONGTEXT  N_("Blu-Ray player region code. "\
74                                 "Some discs can be played only with a correct region code.")
75
76 static const char *const ppsz_region_code[] = {
77     "A", "B", "C" };
78 static const char *const ppsz_region_code_text[] = {
79     "Region A", "Region B", "Region C" };
80
81 #define REGION_DEFAULT   1   /* Index to region list. Actual region code is (1<<REGION_DEFAULT) */
82 #define LANGUAGE_DEFAULT ("eng")
83
84 #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0,8,0)
85 # define BLURAY_DEMUX
86 #endif
87
88 /* Callbacks */
89 static int  blurayOpen (vlc_object_t *);
90 static void blurayClose(vlc_object_t *);
91
92 vlc_module_begin ()
93     set_shortname(N_("Blu-ray"))
94     set_description(N_("Blu-ray Disc support (libbluray)"))
95
96     set_category(CAT_INPUT)
97     set_subcategory(SUBCAT_INPUT_ACCESS)
98     set_capability("access_demux", 200)
99     add_bool("bluray-menu", true, BD_MENU_TEXT, BD_MENU_LONGTEXT, false)
100     add_string("bluray-region", ppsz_region_code[REGION_DEFAULT], BD_REGION_TEXT, BD_REGION_LONGTEXT, false)
101         change_string_list(ppsz_region_code, ppsz_region_code_text)
102
103     add_shortcut("bluray", "file")
104
105     set_callbacks(blurayOpen, blurayClose)
106
107 #ifdef BLURAY_DEMUX
108     /* demux module */
109     add_submodule()
110         set_description( "BluRay demuxer" )
111         set_category( CAT_INPUT )
112         set_subcategory( SUBCAT_INPUT_DEMUX )
113         set_capability( "demux", 5 )
114         set_callbacks( blurayOpen, blurayClose )
115 #endif
116
117 vlc_module_end ()
118
119 /* libbluray's overlay.h defines 2 types of overlay (bd_overlay_plane_e). */
120 #define MAX_OVERLAY 2
121
122 typedef enum OverlayStatus {
123     Closed = 0,
124     ToDisplay,  //Used to mark the overlay to be displayed the first time.
125     Displayed,
126     Outdated    //used to update the overlay after it has been sent to the vout
127 } OverlayStatus;
128
129 typedef struct bluray_overlay_t
130 {
131     vlc_mutex_t         lock;
132     int                 i_channel;
133     OverlayStatus       status;
134     subpicture_region_t *p_regions;
135     int                 width, height;
136
137     /* pointer to last subpicture updater.
138      * used to disconnect this overlay from vout when:
139      * - the overlay is closed
140      * - vout is changed and this overlay is sent to the new vout
141      */
142     struct subpicture_updater_sys_t *p_updater;
143 } bluray_overlay_t;
144
145 struct  demux_sys_t
146 {
147     BLURAY              *bluray;
148
149     /* Titles */
150     unsigned int        i_title;
151     unsigned int        i_longest_title;
152     input_title_t       **pp_title;
153
154     vlc_mutex_t             pl_info_lock;
155     BLURAY_TITLE_INFO      *p_pl_info;
156     const BLURAY_CLIP_INFO *p_clip_info;
157
158     /* Attachments */
159     int                 i_attachments;
160     input_attachment_t  **attachments;
161     int                 i_cover_idx;
162
163     /* Meta information */
164     const META_DL       *p_meta;
165
166     /* Menus */
167     bluray_overlay_t    *p_overlays[MAX_OVERLAY];
168     bool                b_fatal_error;
169     bool                b_menu;
170     bool                b_menu_open;
171     bool                b_popup_available;
172     mtime_t             i_still_end_time;
173
174     vlc_mutex_t         bdj_overlay_lock; /* used to lock BD-J overlay open/close while overlays are being sent to vout */
175
176     /* */
177     vout_thread_t       *p_vout;
178
179     es_out_id_t         *p_dummy_video;
180
181     /* TS stream */
182     es_out_t            *p_out;
183     vlc_array_t         es;
184     int                 i_audio_stream_idx; /* Selected audio stream. -1 if default */
185     int                 i_spu_stream_idx;   /* Selected subtitle stream. -1 if default */
186     bool                b_spu_enable;       /* enabled / disabled */
187     int                 i_video_stream;
188     stream_t            *p_parser;
189     bool                b_flushed;
190     bool                b_pl_playing;       /* true when playing playlist */
191
192     /* stream input */
193     vlc_mutex_t         read_block_lock;
194
195     /* Used to store bluray disc path */
196     char                *psz_bd_path;
197 };
198
199 struct subpicture_updater_sys_t
200 {
201     vlc_mutex_t          lock;      // protect p_overlay pointer and ref_cnt
202     bluray_overlay_t    *p_overlay; // NULL if overlay has been closed
203     int                  ref_cnt;   // one reference in vout (subpicture_t), one in input (bluray_overlay_t)
204 };
205
206 /*
207  * cut the connection between vout and overlay.
208  * - called when vout is closed or overlay is closed.
209  * - frees subpicture_updater_sys_t when both sides have been closed.
210  */
211 static void unref_subpicture_updater(subpicture_updater_sys_t *p_sys)
212 {
213     vlc_mutex_lock(&p_sys->lock);
214     int refs = p_sys->ref_cnt--;
215     p_sys->p_overlay = NULL;
216     vlc_mutex_unlock(&p_sys->lock);
217
218     if (refs < 1) {
219         vlc_mutex_destroy(&p_sys->lock);
220         free(p_sys);
221     }
222 }
223
224 /* Get a 3 char code
225  * FIXME: partiallyy duplicated from src/input/es_out.c
226  */
227 static const char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var )
228 {
229     const iso639_lang_t *pl;
230     char *psz_lang;
231     char *p;
232
233     psz_lang = var_CreateGetString( p_demux, psz_var );
234     if( !psz_lang )
235         return LANGUAGE_DEFAULT;
236
237     /* XXX: we will use only the first value
238      * (and ignore other ones in case of a list) */
239     if( ( p = strchr( psz_lang, ',' ) ) )
240         *p = '\0';
241
242     for( pl = p_languages; pl->psz_eng_name != NULL; pl++ )
243     {
244         if( *psz_lang == '\0' )
245             continue;
246         if( !strcasecmp( pl->psz_eng_name, psz_lang ) ||
247             !strcasecmp( pl->psz_iso639_1, psz_lang ) ||
248             !strcasecmp( pl->psz_iso639_2T, psz_lang ) ||
249             !strcasecmp( pl->psz_iso639_2B, psz_lang ) )
250             break;
251     }
252
253     free( psz_lang );
254
255     if( pl->psz_eng_name != NULL )
256         return pl->psz_iso639_2T;
257
258     return LANGUAGE_DEFAULT;
259 }
260
261 /*****************************************************************************
262  * Local prototypes
263  *****************************************************************************/
264 static es_out_t *esOutNew(demux_t *p_demux);
265
266 static int   blurayControl(demux_t *, int, va_list);
267 static int   blurayDemux(demux_t *);
268
269 static void  blurayInitTitles(demux_t *p_demux, int menu_titles);
270 static int   bluraySetTitle(demux_t *p_demux, int i_title);
271
272 static void  blurayOverlayProc(void *ptr, const BD_OVERLAY * const overlay);
273 static void  blurayArgbOverlayProc(void *ptr, const BD_ARGB_OVERLAY * const overlay);
274
275 static int   onMouseEvent(vlc_object_t *p_vout, const char *psz_var,
276                           vlc_value_t old, vlc_value_t val, void *p_data);
277 static int   onIntfEvent(vlc_object_t *, char const *,
278                          vlc_value_t, vlc_value_t, void *);
279
280 static void  blurayResetParser(demux_t *p_demux);
281
282 #define FROM_TICKS(a) ((a)*CLOCK_FREQ / INT64_C(90000))
283 #define TO_TICKS(a)   ((a)*INT64_C(90000)/CLOCK_FREQ)
284 #define CUR_LENGTH    p_sys->pp_title[p_demux->info.i_title]->i_length
285
286 /* */
287 static void FindMountPoint(char **file)
288 {
289     char *device = *file;
290 #if defined (HAVE_MNTENT_H) && defined (HAVE_SYS_STAT_H)
291     /* bd path may be a symlink (e.g. /dev/dvd -> /dev/sr0), so make sure
292      * we look up the real device */
293     char *bd_device = realpath(device, NULL);
294     if (bd_device == NULL)
295         return;
296
297     struct stat st;
298     if (lstat (bd_device, &st) == 0 && S_ISBLK (st.st_mode)) {
299         FILE *mtab = setmntent ("/proc/self/mounts", "r");
300         struct mntent *m, mbuf;
301         char buf [8192];
302
303         while ((m = getmntent_r (mtab, &mbuf, buf, sizeof(buf))) != NULL) {
304             if (!strcmp (m->mnt_fsname, bd_device)) {
305                 free(device);
306                 *file = strdup(m->mnt_dir);
307                 break;
308             }
309         }
310         endmntent (mtab);
311     }
312     free(bd_device);
313
314 #elif defined(__APPLE__)
315     struct stat st;
316     if (!stat (device, &st) && S_ISBLK (st.st_mode)) {
317         int fs_count = getfsstat (NULL, 0, MNT_NOWAIT);
318         if (fs_count > 0) {
319             struct statfs mbuf[128];
320             getfsstat (mbuf, fs_count * sizeof(mbuf[0]), MNT_NOWAIT);
321             for (int i = 0; i < fs_count; ++i)
322                 if (!strcmp (mbuf[i].f_mntfromname, device)) {
323                     free(device);
324                     *file = strdup(mbuf[i].f_mntonname);
325                     return;
326                 }
327         }
328     }
329 #else
330 # warning Disc device to mount point not implemented
331     VLC_UNUSED( device );
332 #endif
333 }
334
335 static void blurayReleaseVout(demux_t *p_demux)
336 {
337     demux_sys_t *p_sys = p_demux->p_sys;
338
339     if (p_sys->p_vout != NULL) {
340         var_DelCallback(p_sys->p_vout, "mouse-moved", onMouseEvent, p_demux);
341         var_DelCallback(p_sys->p_vout, "mouse-clicked", onMouseEvent, p_demux);
342
343         for (int i = 0; i < MAX_OVERLAY; i++) {
344             bluray_overlay_t *p_ov = p_sys->p_overlays[i];
345             if (p_ov) {
346                 vlc_mutex_lock(&p_ov->lock);
347                 if (p_ov->i_channel != -1) {
348                     msg_Err(p_demux, "blurayReleaseVout: subpicture channel exists\n");
349                     vout_FlushSubpictureChannel(p_sys->p_vout, p_ov->i_channel);
350                 }
351                 p_ov->i_channel = -1;
352                 p_ov->status = ToDisplay;
353                 vlc_mutex_unlock(&p_ov->lock);
354
355                 if (p_ov->p_updater) {
356                     unref_subpicture_updater(p_ov->p_updater);
357                     p_ov->p_updater = NULL;
358                 }
359             }
360         }
361
362         vlc_object_release(p_sys->p_vout);
363         p_sys->p_vout = NULL;
364     }
365 }
366
367 /*****************************************************************************
368  * BD-J background video
369  *****************************************************************************/
370
371 static void startBackground(demux_t *p_demux)
372 {
373     demux_sys_t *p_sys = p_demux->p_sys;
374
375     if (p_sys->p_dummy_video) {
376         return;
377     }
378
379     msg_Info(p_demux, "Start background");
380
381     /* */
382     es_format_t fmt;
383     es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_I420 );
384     video_format_Setup( &fmt.video, VLC_CODEC_I420,
385                         1920, 1080, 1920, 1080, 1, 1);
386     fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN;
387     fmt.i_id = 4115; /* 4113 = main video. 4114 = MVC. 4115 = unused. */
388     fmt.i_group = 1;
389
390     p_sys->p_dummy_video = es_out_Add(p_demux->out, &fmt);
391     es_format_Clean(&fmt);
392
393     if (!p_sys->p_dummy_video) {
394       msg_Err(p_demux, "Error adding background ES");
395       return;
396     }
397
398     block_t *p_block = block_Alloc(fmt.video.i_width * fmt.video.i_height *
399                                    fmt.video.i_bits_per_pixel / 8);
400     if (!p_block) {
401         msg_Err(p_demux, "Error allocating block for background video");
402         return;
403     }
404
405     // XXX TODO: what would be correct timestamp ???
406     p_block->i_dts = p_block->i_pts = mdate() + CLOCK_FREQ/25;
407
408     uint8_t *p = p_block->p_buffer;
409     memset(p, 0, fmt.video.i_width * fmt.video.i_height);
410     p += fmt.video.i_width * fmt.video.i_height;
411     memset(p, 0x80, fmt.video.i_width * fmt.video.i_height / 2);
412
413     es_out_Send(p_demux->out, p_sys->p_dummy_video, p_block);
414 }
415
416 static void stopBackground(demux_t *p_demux)
417 {
418     demux_sys_t *p_sys = p_demux->p_sys;
419
420     if (!p_sys->p_dummy_video) {
421         return;
422     }
423
424     msg_Info(p_demux, "Stop background");
425
426     es_out_Del(p_demux->out, p_sys->p_dummy_video);
427     p_sys->p_dummy_video = NULL;
428 }
429
430 /*****************************************************************************
431  * cache current playlist (title) information
432  *****************************************************************************/
433
434 static void setTitleInfo(demux_sys_t *p_sys, BLURAY_TITLE_INFO *info)
435 {
436     vlc_mutex_lock(&p_sys->pl_info_lock);
437
438     if (p_sys->p_pl_info) {
439         bd_free_title_info(p_sys->p_pl_info);
440     }
441     p_sys->p_pl_info   = info;
442     p_sys->p_clip_info = NULL;
443
444     if (p_sys->p_pl_info && p_sys->p_pl_info->clip_count) {
445         p_sys->p_clip_info = &p_sys->p_pl_info->clips[0];
446     }
447
448     vlc_mutex_unlock(&p_sys->pl_info_lock);
449 }
450
451 /*****************************************************************************
452  * create input attachment for thumbnail
453  *****************************************************************************/
454
455 static void attachThumbnail(demux_t *p_demux)
456 {
457     demux_sys_t *p_sys = p_demux->p_sys;
458
459     if (!p_sys->p_meta)
460         return;
461
462 #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0,9,0)
463     if (p_sys->p_meta->thumb_count > 0 && p_sys->p_meta->thumbnails) {
464         int64_t size;
465         void *data;
466         if (bd_get_meta_file(p_sys->bluray, p_sys->p_meta->thumbnails[0].path, &data, &size) > 0) {
467             char psz_name[64];
468             input_attachment_t *p_attachment;
469
470             snprintf(psz_name, sizeof(psz_name), "picture%d_%s", p_sys->i_attachments, p_sys->p_meta->thumbnails[0].path);
471
472             p_attachment = vlc_input_attachment_New(psz_name, NULL, "Album art", data, size);
473             if (p_attachment) {
474                 p_sys->i_cover_idx = p_sys->i_attachments;
475                 TAB_APPEND(p_sys->i_attachments, p_sys->attachments, p_attachment);
476             }
477         }
478         free(data);
479     }
480 #endif
481 }
482
483 /*****************************************************************************
484  * stream input
485  *****************************************************************************/
486
487 static int probeStream(demux_t *p_demux)
488 {
489     /* input must be seekable */
490     bool b_canseek = false;
491     stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek );
492     if (!b_canseek) {
493         return VLC_EGENERIC;
494     }
495
496     /* first sector(s) should be filled with zeros */
497     size_t i_peek;
498     const uint8_t *p_peek;
499     i_peek = stream_Peek( p_demux->s, &p_peek, 2048 );
500     if( i_peek != 2048 ) {
501         return VLC_EGENERIC;
502     }
503     while (i_peek > 0) {
504         if (p_peek[ --i_peek ]) {
505             return VLC_EGENERIC;
506         }
507     }
508
509     return VLC_SUCCESS;
510 }
511
512 #ifdef BLURAY_DEMUX
513 static int blurayReadBlock(void *object, void *buf, int lba, int num_blocks)
514 {
515     demux_t *p_demux = (demux_t*)object;
516     demux_sys_t *p_sys = p_demux->p_sys;
517     int result = -1;
518
519     assert(p_demux->s != NULL);
520
521     vlc_mutex_lock(&p_sys->read_block_lock);
522
523     if (stream_Seek( p_demux->s, lba * INT64_C(2048) ) == VLC_SUCCESS) {
524         size_t  req = (size_t)2048 * num_blocks;
525         ssize_t got;
526
527         got = stream_Read( p_demux->s, buf, req);
528         if (got < 0) {
529             msg_Err(p_demux, "read from lba %d failed", lba);
530         } else {
531             result = got / 2048;
532         }
533     } else {
534        msg_Err(p_demux, "seek to lba %d failed", lba);
535     }
536
537     vlc_mutex_unlock(&p_sys->read_block_lock);
538
539     return result;
540 }
541 #endif
542
543 /*****************************************************************************
544  * probing of local files
545  *****************************************************************************/
546
547 /* Descriptor Tag (ECMA 167, 3/7.2) */
548 static int decode_descriptor_tag(const uint8_t *buf)
549 {
550     uint16_t id;
551     uint8_t  checksum = 0;
552     int      i;
553
554     id = buf[0] | (buf[1] << 8);
555
556     /* calculate tag checksum */
557     for (i = 0; i < 4; i++) {
558         checksum = (uint8_t)(checksum + buf[i]);
559     }
560     for (i = 5; i < 16; i++) {
561         checksum = (uint8_t)(checksum + buf[i]);
562     }
563
564     if (checksum != buf[4]) {
565         return -1;
566     }
567
568     return id;
569 }
570
571 static int probeFile(const char *psz_name)
572 {
573     struct stat stat_info;
574     uint8_t peek[2048];
575     unsigned i;
576     int ret = VLC_EGENERIC;
577     int fd;
578
579     fd = vlc_open(psz_name, O_RDONLY | O_NONBLOCK);
580     if (fd == -1) {
581         return VLC_EGENERIC;
582     }
583
584     if (fstat(fd, &stat_info) == -1) {
585         goto bailout;
586     }
587     if (!S_ISREG(stat_info.st_mode) && !S_ISBLK(stat_info.st_mode)) {
588         goto bailout;
589     }
590
591     /* first sector should be filled with zeros */
592     if (read(fd, peek, sizeof(peek)) != sizeof(peek)) {
593         goto bailout;
594     }
595     for (i = 0; i < sizeof(peek); i++) {
596         if (peek[ i ]) {
597             goto bailout;
598         }
599     }
600
601     /* Check AVDP tag checksum */
602     if (lseek(fd, 256 * 2048, SEEK_SET) == -1 ||
603         read(fd, peek, 16) != 16 ||
604         decode_descriptor_tag(peek) != 2) {
605         goto bailout;
606     }
607
608     ret = VLC_SUCCESS;
609
610 bailout:
611     close(fd);
612     return ret;
613 }
614
615 /*****************************************************************************
616  * blurayOpen: module init function
617  *****************************************************************************/
618 static int blurayOpen(vlc_object_t *object)
619 {
620     demux_t *p_demux = (demux_t*)object;
621     demux_sys_t *p_sys;
622     bool forced;
623     uint64_t i_init_pos = 0;
624
625     const char *error_msg = NULL;
626 #define BLURAY_ERROR(s) do { error_msg = s; goto error; } while(0)
627
628     forced = !strcasecmp(p_demux->psz_access, "bluray");
629
630     if (p_demux->s) {
631         if (p_demux->psz_access == NULL || !strcasecmp(p_demux->psz_access, "file")) {
632             /* use access_demux for local files */
633             return VLC_EGENERIC;
634         }
635
636         if (probeStream(p_demux) != VLC_SUCCESS) {
637             return VLC_EGENERIC;
638         }
639
640     } else if (!forced) {
641         if (!p_demux->psz_file) {
642             return VLC_EGENERIC;
643         }
644
645         if (probeFile(p_demux->psz_file) != VLC_SUCCESS) {
646             return VLC_EGENERIC;
647         }
648     }
649
650     /* */
651     p_demux->p_sys = p_sys = calloc(1, sizeof(*p_sys));
652     if (unlikely(!p_sys))
653         return VLC_ENOMEM;
654
655     p_sys->i_audio_stream_idx = -1;
656     p_sys->i_spu_stream_idx = -1;
657     p_sys->i_video_stream = -1;
658     p_sys->i_still_end_time = 0;
659
660     /* init demux info fields */
661     p_demux->info.i_update    = 0;
662     p_demux->info.i_title     = 0;
663     p_demux->info.i_seekpoint = 0;
664
665     TAB_INIT(p_sys->i_title, p_sys->pp_title);
666     TAB_INIT(p_sys->i_attachments, p_sys->attachments);
667
668     vlc_mutex_init(&p_sys->pl_info_lock);
669     vlc_mutex_init(&p_sys->bdj_overlay_lock);
670     vlc_mutex_init(&p_sys->read_block_lock); /* used during bd_open_stream() */
671
672     var_AddCallback( p_demux->p_input, "intf-event", onIntfEvent, p_demux );
673
674     /* Open BluRay */
675 #ifdef BLURAY_DEMUX
676     if (p_demux->s) {
677         i_init_pos = stream_Tell(p_demux->s);
678
679         p_sys->bluray = bd_init();
680         if (!bd_open_stream(p_sys->bluray, p_demux, blurayReadBlock)) {
681             bd_close(p_sys->bluray);
682             p_sys->bluray = NULL;
683         }
684     } else
685 #endif
686     {
687         if (!p_demux->psz_file) {
688             /* no path provided (bluray://). use default DVD device. */
689             p_sys->psz_bd_path = var_InheritString(object, "dvd");
690         } else {
691             /* store current bd path */
692             p_sys->psz_bd_path = strdup(p_demux->psz_file);
693         }
694
695         /* If we're passed a block device, try to convert it to the mount point. */
696         FindMountPoint(&p_sys->psz_bd_path);
697
698         p_sys->bluray = bd_open(p_sys->psz_bd_path, NULL);
699     }
700     if (!p_sys->bluray) {
701         goto error;
702     }
703
704     /* Warning the user about AACS/BD+ */
705     const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(p_sys->bluray);
706
707     /* Is it a bluray? */
708     if (!disc_info->bluray_detected) {
709         if (forced) {
710             BLURAY_ERROR(_("Path doesn't appear to be a Blu-ray"));
711         }
712         goto error;
713     }
714
715     msg_Info(p_demux, "First play: %i, Top menu: %i\n"
716                       "HDMV Titles: %i, BD-J Titles: %i, Other: %i",
717              disc_info->first_play_supported, disc_info->top_menu_supported,
718              disc_info->num_hdmv_titles, disc_info->num_bdj_titles,
719              disc_info->num_unsupported_titles);
720
721     /* AACS */
722     if (disc_info->aacs_detected) {
723         msg_Dbg(p_demux, "Disc is using AACS");
724         if (!disc_info->libaacs_detected)
725             BLURAY_ERROR(_("This Blu-ray Disc needs a library for AACS decoding"
726                       ", and your system does not have it."));
727         if (!disc_info->aacs_handled) {
728             if (disc_info->aacs_error_code) {
729                 switch (disc_info->aacs_error_code) {
730                 case BD_AACS_CORRUPTED_DISC:
731                     BLURAY_ERROR(_("Blu-ray Disc is corrupted."));
732                 case BD_AACS_NO_CONFIG:
733                     BLURAY_ERROR(_("Missing AACS configuration file!"));
734                 case BD_AACS_NO_PK:
735                     BLURAY_ERROR(_("No valid processing key found in AACS config file."));
736                 case BD_AACS_NO_CERT:
737                     BLURAY_ERROR(_("No valid host certificate found in AACS config file."));
738                 case BD_AACS_CERT_REVOKED:
739                     BLURAY_ERROR(_("AACS Host certificate revoked."));
740                 case BD_AACS_MMC_FAILED:
741                     BLURAY_ERROR(_("AACS MMC failed."));
742                 }
743             }
744         }
745     }
746
747     /* BD+ */
748     if (disc_info->bdplus_detected) {
749         msg_Dbg(p_demux, "Disc is using BD+");
750         if (!disc_info->libbdplus_detected)
751             BLURAY_ERROR(_("This Blu-ray Disc needs a library for BD+ decoding"
752                       ", and your system does not have it."));
753         if (!disc_info->bdplus_handled)
754             BLURAY_ERROR(_("Your system BD+ decoding library does not work. "
755                       "Missing configuration?"));
756     }
757
758     /* set player region code */
759     char *psz_region = var_InheritString(p_demux, "bluray-region");
760     unsigned int region = psz_region ? (psz_region[0] - 'A') : REGION_DEFAULT;
761     free(psz_region);
762     bd_set_player_setting(p_sys->bluray, BLURAY_PLAYER_SETTING_REGION_CODE, 1<<region);
763
764     /* set preferred languages */
765     const char *psz_code = DemuxGetLanguageCode( p_demux, "audio-language" );
766     bd_set_player_setting_str(p_sys->bluray, BLURAY_PLAYER_SETTING_AUDIO_LANG, psz_code);
767     psz_code = DemuxGetLanguageCode( p_demux, "sub-language" );
768     bd_set_player_setting_str(p_sys->bluray, BLURAY_PLAYER_SETTING_PG_LANG,    psz_code);
769     psz_code = DemuxGetLanguageCode( p_demux, "menu-language" );
770     bd_set_player_setting_str(p_sys->bluray, BLURAY_PLAYER_SETTING_MENU_LANG,  psz_code);
771
772     /* Get disc metadata */
773     p_sys->p_meta = bd_get_meta(p_sys->bluray);
774     if (!p_sys->p_meta)
775         msg_Warn(p_demux, "Failed to get meta info.");
776
777     p_sys->i_cover_idx = -1;
778     attachThumbnail(p_demux);
779
780     p_sys->b_menu = var_InheritBool(p_demux, "bluray-menu");
781
782     /* Check BD-J capability */
783     if (p_sys->b_menu && disc_info->bdj_detected && !disc_info->bdj_handled) {
784         msg_Err(p_demux, "BD-J menus not supported. Playing without menus. "
785                 "BD-J support: %d, JVM found: %d, JVM usable: %d",
786                 disc_info->bdj_supported, disc_info->libjvm_detected, disc_info->bdj_handled);
787         dialog_Fatal(p_demux, _("Java required"),
788                      _("This Blu-ray disc needs Java for menus.%s\nDisc is played without menus."),
789                      !disc_info->libjvm_detected ? _(" Java was not found from your system.") : "");
790         p_sys->b_menu = false;
791     }
792
793     /* Get titles and chapters */
794     blurayInitTitles(p_demux, disc_info->num_hdmv_titles + disc_info->num_bdj_titles + 1/*Top Menu*/ + 1/*First Play*/);
795
796     /*
797      * Initialize the event queue, so we can receive events in blurayDemux(Menu).
798      */
799     bd_get_event(p_sys->bluray, NULL);
800
801     /* Registering overlay event handler */
802     bd_register_overlay_proc(p_sys->bluray, p_demux, blurayOverlayProc);
803     if (unlikely(!p_demux->p_input)) {
804         msg_Err(p_demux, "Could not get parent input");
805         goto error;
806     }
807
808     if (p_sys->b_menu) {
809
810         /* Register ARGB overlay handler for BD-J */
811         if (disc_info->num_bdj_titles)
812             bd_register_argb_overlay_proc(p_sys->bluray, p_demux, blurayArgbOverlayProc, NULL);
813
814         /* libbluray will start playback from "First-Title" title */
815         if (bd_play(p_sys->bluray) == 0)
816             BLURAY_ERROR(_("Failed to start bluray playback. Please try without menu support."));
817
818     } else {
819         /* set start title number */
820         if (bluraySetTitle(p_demux, p_sys->i_longest_title) != VLC_SUCCESS) {
821             msg_Err(p_demux, "Could not set the title %d", p_sys->i_longest_title);
822             goto error;
823         }
824     }
825
826     vlc_array_init(&p_sys->es);
827     p_sys->p_out = esOutNew(p_demux);
828     if (unlikely(p_sys->p_out == NULL))
829         goto error;
830
831     blurayResetParser(p_demux);
832     if (!p_sys->p_parser) {
833         msg_Err(p_demux, "Failed to create TS demuxer");
834         goto error;
835     }
836
837     p_demux->pf_control = blurayControl;
838     p_demux->pf_demux   = blurayDemux;
839
840     return VLC_SUCCESS;
841
842 error:
843     if (error_msg)
844         dialog_Fatal(p_demux, _("Blu-ray error"), "%s", error_msg);
845     blurayClose(object);
846
847     if (p_demux->s != NULL) {
848         /* restore stream position */
849         if (stream_Seek(p_demux->s, i_init_pos) != VLC_SUCCESS) {
850             msg_Err(p_demux, "Failed to seek back to stream start");
851             return VLC_ETIMEOUT;
852         }
853     }
854
855     return VLC_EGENERIC;
856 #undef BLURAY_ERROR
857 }
858
859
860 /*****************************************************************************
861  * blurayClose: module destroy function
862  *****************************************************************************/
863 static void blurayClose(vlc_object_t *object)
864 {
865     demux_t *p_demux = (demux_t*)object;
866     demux_sys_t *p_sys = p_demux->p_sys;
867
868     var_DelCallback( p_demux->p_input, "intf-event", onIntfEvent, p_demux );
869
870     setTitleInfo(p_sys, NULL);
871
872     /*
873      * Close libbluray first.
874      * This will close all the overlays before we release p_vout
875      * bd_close(NULL) can crash
876      */
877     if (p_sys->bluray) {
878         bd_close(p_sys->bluray);
879     }
880
881     blurayReleaseVout(p_demux);
882
883     if (p_sys->p_parser)
884         stream_Delete(p_sys->p_parser);
885     if (p_sys->p_out != NULL)
886         es_out_Delete(p_sys->p_out);
887     assert(vlc_array_count(&p_sys->es) == 0);
888     vlc_array_clear(&p_sys->es);
889
890     /* Titles */
891     for (unsigned int i = 0; i < p_sys->i_title; i++)
892         vlc_input_title_Delete(p_sys->pp_title[i]);
893     TAB_CLEAN(p_sys->i_title, p_sys->pp_title);
894
895     for (int i = 0; i < p_sys->i_attachments; i++)
896       vlc_input_attachment_Delete(p_sys->attachments[i]);
897     TAB_CLEAN(p_sys->i_attachments, p_sys->attachments);
898
899     vlc_mutex_destroy(&p_sys->pl_info_lock);
900     vlc_mutex_destroy(&p_sys->bdj_overlay_lock);
901     vlc_mutex_destroy(&p_sys->read_block_lock);
902
903     free(p_sys->psz_bd_path);
904     free(p_sys);
905 }
906
907 /*****************************************************************************
908  * Elementary streams handling
909  *****************************************************************************/
910
911 struct es_out_sys_t {
912     demux_t *p_demux;
913 };
914
915 typedef struct  fmt_es_pair {
916     int         i_id;
917     es_out_id_t *p_es;
918 }               fmt_es_pair_t;
919
920 static int  findEsPairIndex(demux_sys_t *p_sys, int i_id)
921 {
922     for (int i = 0; i < vlc_array_count(&p_sys->es); ++i)
923         if (((fmt_es_pair_t*)vlc_array_item_at_index(&p_sys->es, i))->i_id == i_id)
924             return i;
925
926     return -1;
927 }
928
929 static int  findEsPairIndexByEs(demux_sys_t *p_sys, es_out_id_t *p_es)
930 {
931     for (int i = 0; i < vlc_array_count(&p_sys->es); ++i)
932         if (((fmt_es_pair_t*)vlc_array_item_at_index(&p_sys->es, i))->p_es == p_es)
933             return i;
934
935     return -1;
936 }
937
938 static void setStreamLang(demux_sys_t *p_sys, es_format_t *p_fmt)
939 {
940     const BLURAY_STREAM_INFO *p_streams;
941     int i_stream_count = 0;
942
943     vlc_mutex_lock(&p_sys->pl_info_lock);
944
945     if (p_sys->p_clip_info) {
946         if (p_fmt->i_cat == AUDIO_ES) {
947             p_streams      = p_sys->p_clip_info->audio_streams;
948             i_stream_count = p_sys->p_clip_info->audio_stream_count;
949         } else if (p_fmt->i_cat == SPU_ES) {
950             p_streams      = p_sys->p_clip_info->pg_streams;
951             i_stream_count = p_sys->p_clip_info->pg_stream_count;
952         }
953     }
954
955     for (int i = 0; i < i_stream_count; i++) {
956         if (p_fmt->i_id == p_streams[i].pid) {
957             free(p_fmt->psz_language);
958             p_fmt->psz_language = strndup((const char *)p_streams[i].lang, 3);
959             break;
960         }
961     }
962
963     vlc_mutex_unlock(&p_sys->pl_info_lock);
964 }
965
966 static int blurayEsPid(demux_sys_t *p_sys, int es_type, int i_es_idx)
967 {
968     int i_pid = -1;
969
970     vlc_mutex_lock(&p_sys->pl_info_lock);
971
972     if (p_sys->p_clip_info) {
973         if (es_type == AUDIO_ES) {
974             if (i_es_idx >= 0 && i_es_idx < p_sys->p_clip_info->pg_stream_count) {
975                 i_pid = p_sys->p_clip_info->audio_streams[i_es_idx].pid;
976             }
977         } else if (es_type == SPU_ES) {
978             if (i_es_idx >= 0 && i_es_idx < p_sys->p_clip_info->pg_stream_count) {
979                 i_pid = p_sys->p_clip_info->pg_streams[i_es_idx].pid;
980             }
981         }
982     }
983
984     vlc_mutex_unlock(&p_sys->pl_info_lock);
985
986     return i_pid;
987 }
988
989 static es_out_id_t *esOutAdd(es_out_t *p_out, const es_format_t *p_fmt)
990 {
991     demux_t *p_demux = p_out->p_sys->p_demux;
992     demux_sys_t *p_sys = p_demux->p_sys;
993     es_format_t fmt;
994     bool b_select = false;
995
996     es_format_Copy(&fmt, p_fmt);
997
998     switch (fmt.i_cat) {
999     case VIDEO_ES:
1000         if (p_sys->i_video_stream != -1 && p_sys->i_video_stream != p_fmt->i_id)
1001             fmt.i_priority = ES_PRIORITY_NOT_SELECTABLE;
1002         break ;
1003     case AUDIO_ES:
1004         if (p_sys->i_audio_stream_idx != -1) {
1005             if (blurayEsPid(p_sys, AUDIO_ES, p_sys->i_audio_stream_idx) == p_fmt->i_id)
1006                 b_select = true;
1007             fmt.i_priority = ES_PRIORITY_NOT_SELECTABLE;
1008         }
1009         setStreamLang(p_sys, &fmt);
1010         break ;
1011     case SPU_ES:
1012         if (p_sys->i_spu_stream_idx != -1) {
1013             if (blurayEsPid(p_sys, SPU_ES, p_sys->i_spu_stream_idx) == p_fmt->i_id)
1014                 b_select = true;
1015             fmt.i_priority = ES_PRIORITY_NOT_SELECTABLE;
1016         }
1017         setStreamLang(p_sys, &fmt);
1018         break ;
1019     }
1020
1021     es_out_id_t *p_es = es_out_Add(p_demux->out, &fmt);
1022     if (p_fmt->i_id >= 0) {
1023         /* Ensure we are not overriding anything */
1024         int idx = findEsPairIndex(p_sys, p_fmt->i_id);
1025         if (idx == -1) {
1026             fmt_es_pair_t *p_pair = malloc(sizeof(*p_pair));
1027             if (likely(p_pair != NULL)) {
1028                 p_pair->i_id = p_fmt->i_id;
1029                 p_pair->p_es = p_es;
1030                 msg_Info(p_demux, "Adding ES %d", p_fmt->i_id);
1031                 vlc_array_append(&p_sys->es, p_pair);
1032
1033                 if (b_select) {
1034                     if (fmt.i_cat == AUDIO_ES) {
1035                         var_SetInteger( p_demux->p_input, "audio-es", p_fmt->i_id );
1036                     } else if (fmt.i_cat == SPU_ES) {
1037                         var_SetInteger( p_demux->p_input, "spu-es", p_sys->b_spu_enable ? p_fmt->i_id : -1 );
1038                     }
1039                 }
1040             }
1041         }
1042     }
1043     es_format_Clean(&fmt);
1044     return p_es;
1045 }
1046
1047 static int esOutSend(es_out_t *p_out, es_out_id_t *p_es, block_t *p_block)
1048 {
1049     return es_out_Send(p_out->p_sys->p_demux->out, p_es, p_block);
1050 }
1051
1052 static void esOutDel(es_out_t *p_out, es_out_id_t *p_es)
1053 {
1054     int idx = findEsPairIndexByEs(p_out->p_sys->p_demux->p_sys, p_es);
1055     if (idx >= 0) {
1056         free(vlc_array_item_at_index(&p_out->p_sys->p_demux->p_sys->es, idx));
1057         vlc_array_remove(&p_out->p_sys->p_demux->p_sys->es, idx);
1058     }
1059     es_out_Del(p_out->p_sys->p_demux->out, p_es);
1060 }
1061
1062 static int esOutControl(es_out_t *p_out, int i_query, va_list args)
1063 {
1064     return es_out_vaControl(p_out->p_sys->p_demux->out, i_query, args);
1065 }
1066
1067 static void esOutDestroy(es_out_t *p_out)
1068 {
1069     for (int i = 0; i < vlc_array_count(&p_out->p_sys->p_demux->p_sys->es); ++i)
1070         free(vlc_array_item_at_index(&p_out->p_sys->p_demux->p_sys->es, i));
1071     vlc_array_clear(&p_out->p_sys->p_demux->p_sys->es);
1072     free(p_out->p_sys);
1073     free(p_out);
1074 }
1075
1076 static es_out_t *esOutNew(demux_t *p_demux)
1077 {
1078     assert(vlc_array_count(&p_demux->p_sys->es) == 0);
1079     es_out_t    *p_out = malloc(sizeof(*p_out));
1080     if (unlikely(p_out == NULL))
1081         return NULL;
1082
1083     p_out->pf_add       = esOutAdd;
1084     p_out->pf_control   = esOutControl;
1085     p_out->pf_del       = esOutDel;
1086     p_out->pf_destroy   = esOutDestroy;
1087     p_out->pf_send      = esOutSend;
1088
1089     p_out->p_sys = malloc(sizeof(*p_out->p_sys));
1090     if (unlikely(p_out->p_sys == NULL)) {
1091         free(p_out);
1092         return NULL;
1093     }
1094     p_out->p_sys->p_demux = p_demux;
1095     return p_out;
1096 }
1097
1098 /*****************************************************************************
1099  * subpicture_updater_t functions:
1100  *****************************************************************************/
1101
1102 static bluray_overlay_t *updater_lock_overlay(subpicture_updater_sys_t *p_upd_sys)
1103 {
1104     /* this lock is held while vout accesses overlay. => overlay can't be closed. */
1105     vlc_mutex_lock(&p_upd_sys->lock);
1106
1107     bluray_overlay_t *ov = p_upd_sys->p_overlay;
1108     if (ov) {
1109         /* this lock is held while vout accesses overlay. => overlay can't be modified. */
1110         vlc_mutex_lock(&ov->lock);
1111         return ov;
1112     }
1113
1114     /* overlay has been closed */
1115     vlc_mutex_unlock(&p_upd_sys->lock);
1116     return NULL;
1117 }
1118
1119 static void updater_unlock_overlay(subpicture_updater_sys_t *p_upd_sys)
1120 {
1121     assert (p_upd_sys->p_overlay);
1122
1123     vlc_mutex_unlock(&p_upd_sys->p_overlay->lock);
1124     vlc_mutex_unlock(&p_upd_sys->lock);
1125 }
1126
1127 static int subpictureUpdaterValidate(subpicture_t *p_subpic,
1128                                       bool b_fmt_src, const video_format_t *p_fmt_src,
1129                                       bool b_fmt_dst, const video_format_t *p_fmt_dst,
1130                                       mtime_t i_ts)
1131 {
1132     VLC_UNUSED(b_fmt_src);
1133     VLC_UNUSED(b_fmt_dst);
1134     VLC_UNUSED(p_fmt_src);
1135     VLC_UNUSED(p_fmt_dst);
1136     VLC_UNUSED(i_ts);
1137
1138     subpicture_updater_sys_t *p_upd_sys = p_subpic->updater.p_sys;
1139     bluray_overlay_t         *p_overlay = updater_lock_overlay(p_upd_sys);
1140
1141     if (!p_overlay) {
1142         return 1;
1143     }
1144
1145     int res = p_overlay->status == Outdated;
1146
1147     updater_unlock_overlay(p_upd_sys);
1148
1149     return res;
1150 }
1151
1152 static void subpictureUpdaterUpdate(subpicture_t *p_subpic,
1153                                     const video_format_t *p_fmt_src,
1154                                     const video_format_t *p_fmt_dst,
1155                                     mtime_t i_ts)
1156 {
1157     VLC_UNUSED(p_fmt_src);
1158     VLC_UNUSED(p_fmt_dst);
1159     VLC_UNUSED(i_ts);
1160     subpicture_updater_sys_t *p_upd_sys = p_subpic->updater.p_sys;
1161     bluray_overlay_t         *p_overlay = updater_lock_overlay(p_upd_sys);
1162
1163     if (!p_overlay) {
1164         return;
1165     }
1166
1167     /*
1168      * When this function is called, all p_subpic regions are gone.
1169      * We need to duplicate our regions (stored internaly) to this subpic.
1170      */
1171     subpicture_region_t *p_src = p_overlay->p_regions;
1172     if (!p_src) {
1173         updater_unlock_overlay(p_upd_sys);
1174         return;
1175     }
1176
1177     subpicture_region_t **p_dst = &p_subpic->p_region;
1178     while (p_src != NULL) {
1179         *p_dst = subpicture_region_Copy(p_src);
1180         if (*p_dst == NULL)
1181             break;
1182         p_dst = &(*p_dst)->p_next;
1183         p_src = p_src->p_next;
1184     }
1185     if (*p_dst != NULL)
1186         (*p_dst)->p_next = NULL;
1187     p_overlay->status = Displayed;
1188
1189     updater_unlock_overlay(p_upd_sys);
1190 }
1191
1192 static void subpictureUpdaterDestroy(subpicture_t *p_subpic)
1193 {
1194     subpicture_updater_sys_t *p_upd_sys = p_subpic->updater.p_sys;
1195     bluray_overlay_t         *p_overlay = updater_lock_overlay(p_upd_sys);
1196
1197     if (p_overlay) {
1198         /* vout is closed (seek, new clip, ?). Overlay must be redrawn. */
1199         p_overlay->status = ToDisplay;
1200         p_overlay->i_channel = -1;
1201         updater_unlock_overlay(p_upd_sys);
1202     }
1203
1204     unref_subpicture_updater(p_upd_sys);
1205 }
1206
1207 static subpicture_t *bluraySubpictureCreate(bluray_overlay_t *p_ov)
1208 {
1209     subpicture_updater_sys_t *p_upd_sys = malloc(sizeof(*p_upd_sys));
1210     if (unlikely(p_upd_sys == NULL)) {
1211         return NULL;
1212     }
1213
1214     p_upd_sys->p_overlay = p_ov;
1215
1216     subpicture_updater_t updater = {
1217         .pf_validate = subpictureUpdaterValidate,
1218         .pf_update   = subpictureUpdaterUpdate,
1219         .pf_destroy  = subpictureUpdaterDestroy,
1220         .p_sys       = p_upd_sys,
1221     };
1222
1223     subpicture_t *p_pic = subpicture_New(&updater);
1224     if (p_pic == NULL) {
1225         free(p_upd_sys);
1226         return NULL;
1227     }
1228
1229     p_pic->i_original_picture_width = p_ov->width;
1230     p_pic->i_original_picture_height = p_ov->height;
1231     p_pic->b_ephemer = true;
1232     p_pic->b_absolute = true;
1233
1234     vlc_mutex_init(&p_upd_sys->lock);
1235     p_upd_sys->ref_cnt = 2;
1236
1237     p_ov->p_updater = p_upd_sys;
1238
1239     return p_pic;
1240 }
1241
1242 /*****************************************************************************
1243  * User input events:
1244  *****************************************************************************/
1245 static int onMouseEvent(vlc_object_t *p_vout, const char *psz_var, vlc_value_t old,
1246                         vlc_value_t val, void *p_data)
1247 {
1248     demux_t     *p_demux = (demux_t*)p_data;
1249     demux_sys_t *p_sys   = p_demux->p_sys;
1250     mtime_t     now      = mdate();
1251     VLC_UNUSED(old);
1252     VLC_UNUSED(p_vout);
1253
1254     if (psz_var[6] == 'm')   //Mouse moved
1255         bd_mouse_select(p_sys->bluray, now, val.coords.x, val.coords.y);
1256     else if (psz_var[6] == 'c') {
1257         bd_mouse_select(p_sys->bluray, now, val.coords.x, val.coords.y);
1258         bd_user_input(p_sys->bluray, now, BD_VK_MOUSE_ACTIVATE);
1259     } else {
1260         vlc_assert_unreachable();
1261     }
1262     return VLC_SUCCESS;
1263 }
1264
1265 static int sendKeyEvent(demux_sys_t *p_sys, unsigned int key)
1266 {
1267     mtime_t now = mdate();
1268     if (bd_user_input(p_sys->bluray, now, key) < 0)
1269         return VLC_EGENERIC;
1270
1271     return VLC_SUCCESS;
1272 }
1273
1274 /*****************************************************************************
1275  * libbluray overlay handling:
1276  *****************************************************************************/
1277
1278 static void blurayCloseOverlay(demux_t *p_demux, int plane)
1279 {
1280     demux_sys_t *p_sys = p_demux->p_sys;
1281     bluray_overlay_t *ov = p_sys->p_overlays[plane];
1282
1283     if (ov != NULL) {
1284
1285         /* drop overlay from vout */
1286         if (ov->p_updater) {
1287             unref_subpicture_updater(ov->p_updater);
1288         }
1289         /* no references to this overlay exist in vo anymore */
1290         if (p_sys->p_vout && ov->i_channel != -1) {
1291             vout_FlushSubpictureChannel(p_sys->p_vout, ov->i_channel);
1292         }
1293
1294         vlc_mutex_destroy(&ov->lock);
1295         subpicture_region_ChainDelete(ov->p_regions);
1296         free(ov);
1297
1298         p_sys->p_overlays[plane] = NULL;
1299     }
1300
1301     for (int i = 0; i < MAX_OVERLAY; i++)
1302         if (p_sys->p_overlays[i])
1303             return;
1304
1305     /* All overlays have been closed */
1306     blurayReleaseVout(p_demux);
1307 }
1308
1309 /*
1310  * Mark the overlay as "ToDisplay" status.
1311  * This will not send the overlay to the vout instantly, as the vout
1312  * may not be acquired (not acquirable) yet.
1313  * If is has already been acquired, the overlay has already been sent to it,
1314  * therefore, we only flag the overlay as "Outdated"
1315  */
1316 static void blurayActivateOverlay(demux_t *p_demux, int plane)
1317 {
1318     demux_sys_t *p_sys = p_demux->p_sys;
1319     bluray_overlay_t *ov = p_sys->p_overlays[plane];
1320
1321     /*
1322      * If the overlay is already displayed, mark the picture as outdated.
1323      * We must NOT use vout_PutSubpicture if a picture is already displayed.
1324      */
1325     vlc_mutex_lock(&ov->lock);
1326     if (ov->status >= Displayed && p_sys->p_vout) {
1327         ov->status = Outdated;
1328         vlc_mutex_unlock(&ov->lock);
1329         return;
1330     }
1331
1332     /*
1333      * Mark the overlay as available, but don't display it right now.
1334      * the blurayDemuxMenu will send it to vout, as it may be unavailable when
1335      * the overlay is computed
1336      */
1337     ov->status = ToDisplay;
1338     vlc_mutex_unlock(&ov->lock);
1339 }
1340
1341 static void blurayInitOverlay(demux_t *p_demux, int plane, int width, int height)
1342 {
1343     demux_sys_t *p_sys = p_demux->p_sys;
1344
1345     assert(p_sys->p_overlays[plane] == NULL);
1346
1347     bluray_overlay_t *ov = calloc(1, sizeof(*ov));
1348     if (unlikely(ov == NULL))
1349         return;
1350
1351     ov->width = width;
1352     ov->height = height;
1353     ov->i_channel = -1;
1354
1355     vlc_mutex_init(&ov->lock);
1356
1357     p_sys->p_overlays[plane] = ov;
1358 }
1359
1360 /**
1361  * Destroy every regions in the subpicture.
1362  * This is done in two steps:
1363  * - Wiping our private regions list
1364  * - Flagging the overlay as outdated, so the changes are replicated from
1365  *   the subpicture_updater_t::pf_update
1366  * This doesn't destroy the subpicture, as the overlay may be used again by libbluray.
1367  */
1368 static void blurayClearOverlay(demux_t *p_demux, int plane)
1369 {
1370     demux_sys_t *p_sys = p_demux->p_sys;
1371     bluray_overlay_t *ov = p_sys->p_overlays[plane];
1372
1373     vlc_mutex_lock(&ov->lock);
1374
1375     subpicture_region_ChainDelete(ov->p_regions);
1376     ov->p_regions = NULL;
1377     ov->status = Outdated;
1378
1379     vlc_mutex_unlock(&ov->lock);
1380 }
1381
1382 /*
1383  * This will draw to the overlay by adding a region to our region list
1384  * This will have to be copied to the subpicture used to render the overlay.
1385  */
1386 static void blurayDrawOverlay(demux_t *p_demux, const BD_OVERLAY* const ov)
1387 {
1388     demux_sys_t *p_sys = p_demux->p_sys;
1389
1390     /*
1391      * Compute a subpicture_region_t.
1392      * It will be copied and sent to the vout later.
1393      */
1394     vlc_mutex_lock(&p_sys->p_overlays[ov->plane]->lock);
1395
1396     /* Find a region to update */
1397     subpicture_region_t **pp_reg = &p_sys->p_overlays[ov->plane]->p_regions;
1398     subpicture_region_t *p_reg = p_sys->p_overlays[ov->plane]->p_regions;
1399     subpicture_region_t *p_last = NULL;
1400     while (p_reg != NULL) {
1401         p_last = p_reg;
1402         if (p_reg->i_x == ov->x && p_reg->i_y == ov->y &&
1403                 p_reg->fmt.i_width == ov->w && p_reg->fmt.i_height == ov->h)
1404             break;
1405         pp_reg = &p_reg->p_next;
1406         p_reg = p_reg->p_next;
1407     }
1408
1409     if (!ov->img) {
1410         if (p_reg) {
1411             /* drop region */
1412             *pp_reg = p_reg->p_next;
1413             subpicture_region_Delete(p_reg);
1414         }
1415         vlc_mutex_unlock(&p_sys->p_overlays[ov->plane]->lock);
1416         return;
1417     }
1418
1419     /* If there is no region to update, create a new one. */
1420     if (!p_reg) {
1421         video_format_t fmt;
1422         video_format_Init(&fmt, 0);
1423         video_format_Setup(&fmt, VLC_CODEC_YUVP, ov->w, ov->h, ov->w, ov->h, 1, 1);
1424
1425         p_reg = subpicture_region_New(&fmt);
1426         p_reg->i_x = ov->x;
1427         p_reg->i_y = ov->y;
1428         /* Append it to our list. */
1429         if (p_last != NULL)
1430             p_last->p_next = p_reg;
1431         else /* If we don't have a last region, then our list empty */
1432             p_sys->p_overlays[ov->plane]->p_regions = p_reg;
1433     }
1434
1435     /* Now we can update the region, regardless it's an update or an insert */
1436     const BD_PG_RLE_ELEM *img = ov->img;
1437     for (int y = 0; y < ov->h; y++)
1438         for (int x = 0; x < ov->w;) {
1439             plane_t *p = &p_reg->p_picture->p[0];
1440             memset(&p->p_pixels[y * p->i_pitch + x], img->color, img->len);
1441             x += img->len;
1442             img++;
1443         }
1444
1445     if (ov->palette) {
1446         p_reg->fmt.p_palette->i_entries = 256;
1447         for (int i = 0; i < 256; ++i) {
1448             p_reg->fmt.p_palette->palette[i][0] = ov->palette[i].Y;
1449             p_reg->fmt.p_palette->palette[i][1] = ov->palette[i].Cb;
1450             p_reg->fmt.p_palette->palette[i][2] = ov->palette[i].Cr;
1451             p_reg->fmt.p_palette->palette[i][3] = ov->palette[i].T;
1452         }
1453     }
1454
1455     vlc_mutex_unlock(&p_sys->p_overlays[ov->plane]->lock);
1456     /*
1457      * /!\ The region is now stored in our internal list, but not in the subpicture /!\
1458      */
1459 }
1460
1461 static void blurayOverlayProc(void *ptr, const BD_OVERLAY *const overlay)
1462 {
1463     demux_t *p_demux = (demux_t*)ptr;
1464     demux_sys_t *p_sys = p_demux->p_sys;
1465
1466     if (!overlay) {
1467         msg_Info(p_demux, "Closing overlays.");
1468         if (p_sys->p_vout)
1469             for (int i = 0; i < MAX_OVERLAY; i++)
1470                 blurayCloseOverlay(p_demux, i);
1471         return;
1472     }
1473
1474     switch (overlay->cmd) {
1475     case BD_OVERLAY_INIT:
1476         msg_Info(p_demux, "Initializing overlay");
1477         vlc_mutex_lock(&p_sys->bdj_overlay_lock);
1478         blurayInitOverlay(p_demux, overlay->plane, overlay->w, overlay->h);
1479         vlc_mutex_unlock(&p_sys->bdj_overlay_lock);
1480         break;
1481     case BD_OVERLAY_CLOSE:
1482         vlc_mutex_lock(&p_sys->bdj_overlay_lock);
1483         blurayClearOverlay(p_demux, overlay->plane);
1484         blurayCloseOverlay(p_demux, overlay->plane);
1485         vlc_mutex_unlock(&p_sys->bdj_overlay_lock);
1486         break;
1487     case BD_OVERLAY_CLEAR:
1488         blurayClearOverlay(p_demux, overlay->plane);
1489         break;
1490     case BD_OVERLAY_FLUSH:
1491         blurayActivateOverlay(p_demux, overlay->plane);
1492         break;
1493     case BD_OVERLAY_DRAW:
1494     case BD_OVERLAY_WIPE:
1495         blurayDrawOverlay(p_demux, overlay);
1496         break;
1497     default:
1498         msg_Warn(p_demux, "Unknown BD overlay command: %u", overlay->cmd);
1499         break;
1500     }
1501 }
1502
1503 /*
1504  * ARGB overlay (BD-J)
1505  */
1506 static void blurayInitArgbOverlay(demux_t *p_demux, int plane, int width, int height)
1507 {
1508     demux_sys_t *p_sys = p_demux->p_sys;
1509
1510     blurayInitOverlay(p_demux, plane, width, height);
1511
1512     if (!p_sys->p_overlays[plane]->p_regions) {
1513         video_format_t fmt;
1514         video_format_Init(&fmt, 0);
1515         video_format_Setup(&fmt, VLC_CODEC_RGBA, width, height, width, height, 1, 1);
1516
1517         p_sys->p_overlays[plane]->p_regions = subpicture_region_New(&fmt);
1518     }
1519 }
1520
1521 static void blurayDrawArgbOverlay(demux_t *p_demux, const BD_ARGB_OVERLAY* const ov)
1522 {
1523     demux_sys_t *p_sys = p_demux->p_sys;
1524
1525     vlc_mutex_lock(&p_sys->p_overlays[ov->plane]->lock);
1526
1527     /* Find a region to update */
1528     subpicture_region_t *p_reg = p_sys->p_overlays[ov->plane]->p_regions;
1529     if (!p_reg) {
1530         vlc_mutex_unlock(&p_sys->p_overlays[ov->plane]->lock);
1531         return;
1532     }
1533
1534     /* Now we can update the region */
1535     const uint32_t *src0 = ov->argb;
1536     uint8_t        *dst0 = p_reg->p_picture->p[0].p_pixels +
1537                            p_reg->p_picture->p[0].i_pitch * ov->y +
1538                            ov->x * 4;
1539
1540     for (int y = 0; y < ov->h; y++) {
1541         // XXX: add support for this format ? Should be possible with OPENGL/VDPAU/...
1542         // - or add libbluray option to select the format ?
1543         for (int x = 0; x < ov->w; x++) {
1544             dst0[x*4  ] = src0[x]>>16; /* R */
1545             dst0[x*4+1] = src0[x]>>8;  /* G */
1546             dst0[x*4+2] = src0[x];     /* B */
1547             dst0[x*4+3] = src0[x]>>24; /* A */
1548         }
1549
1550         src0 += ov->stride;
1551         dst0 += p_reg->p_picture->p[0].i_pitch;
1552     }
1553
1554     vlc_mutex_unlock(&p_sys->p_overlays[ov->plane]->lock);
1555     /*
1556      * /!\ The region is now stored in our internal list, but not in the subpicture /!\
1557      */
1558 }
1559
1560 static void blurayArgbOverlayProc(void *ptr, const BD_ARGB_OVERLAY *const overlay)
1561 {
1562     demux_t *p_demux = (demux_t*)ptr;
1563     demux_sys_t *p_sys = p_demux->p_sys;
1564
1565     switch (overlay->cmd) {
1566     case BD_ARGB_OVERLAY_INIT:
1567         vlc_mutex_lock(&p_sys->bdj_overlay_lock);
1568         blurayInitArgbOverlay(p_demux, overlay->plane, overlay->w, overlay->h);
1569         vlc_mutex_unlock(&p_sys->bdj_overlay_lock);
1570         break;
1571     case BD_ARGB_OVERLAY_CLOSE:
1572         vlc_mutex_lock(&p_sys->bdj_overlay_lock);
1573         blurayClearOverlay(p_demux, overlay->plane);
1574         blurayCloseOverlay(p_demux, overlay->plane);
1575         vlc_mutex_unlock(&p_sys->bdj_overlay_lock);
1576         break;
1577     case BD_ARGB_OVERLAY_FLUSH:
1578         blurayActivateOverlay(p_demux, overlay->plane);
1579         break;
1580     case BD_ARGB_OVERLAY_DRAW:
1581         blurayDrawArgbOverlay(p_demux, overlay);
1582         break;
1583     default:
1584         msg_Warn(p_demux, "Unknown BD ARGB overlay command: %u", overlay->cmd);
1585         break;
1586     }
1587 }
1588
1589 static void bluraySendOverlayToVout(demux_t *p_demux, bluray_overlay_t *p_ov)
1590 {
1591     demux_sys_t *p_sys = p_demux->p_sys;
1592
1593     assert(p_ov != NULL);
1594     assert(p_ov->i_channel == -1);
1595
1596     if (p_ov->p_updater) {
1597         unref_subpicture_updater(p_ov->p_updater);
1598         p_ov->p_updater = NULL;
1599     }
1600
1601     subpicture_t *p_pic = bluraySubpictureCreate(p_ov);
1602     if (!p_pic) {
1603         msg_Err(p_demux, "bluraySubpictureCreate() failed");
1604         return;
1605     }
1606
1607     p_pic->i_start = p_pic->i_stop = mdate();
1608     p_pic->i_channel = vout_RegisterSubpictureChannel(p_sys->p_vout);
1609     p_ov->i_channel = p_pic->i_channel;
1610
1611     /*
1612      * After this point, the picture should not be accessed from the demux thread,
1613      * as it is held by the vout thread.
1614      * This must be done only once per subpicture, ie. only once between each
1615      * blurayInitOverlay & blurayCloseOverlay call.
1616      */
1617     vout_PutSubpicture(p_sys->p_vout, p_pic);
1618
1619     /*
1620      * Mark the picture as Outdated, as it contains no region for now.
1621      * This will make the subpicture_updater_t call pf_update
1622      */
1623     p_ov->status = Outdated;
1624 }
1625
1626 static void blurayUpdateTitleInfo(input_title_t *t, BLURAY_TITLE_INFO *title_info)
1627 {
1628     t->i_length = FROM_TICKS(title_info->duration);
1629
1630     for (int i = 0; i < t->i_seekpoint; i++)
1631         vlc_seekpoint_Delete( t->seekpoint[i] );
1632     TAB_CLEAN(t->i_seekpoint, t->seekpoint);
1633
1634         for (unsigned int j = 0; j < title_info->chapter_count; j++) {
1635             seekpoint_t *s = vlc_seekpoint_New();
1636             if (!s) {
1637                 break;
1638             }
1639             s->i_time_offset = title_info->chapters[j].offset;
1640
1641             TAB_APPEND(t->i_seekpoint, t->seekpoint, s);
1642         }
1643 }
1644
1645 static void blurayInitTitles(demux_t *p_demux, int menu_titles)
1646 {
1647     demux_sys_t *p_sys = p_demux->p_sys;
1648     const BLURAY_DISC_INFO *di = bd_get_disc_info(p_sys->bluray);
1649
1650     /* get and set the titles */
1651     unsigned i_title = menu_titles;
1652
1653     if (!p_sys->b_menu) {
1654         i_title = bd_get_titles(p_sys->bluray, TITLES_RELEVANT, 60);
1655         p_sys->i_longest_title = bd_get_main_title(p_sys->bluray);
1656     }
1657
1658     for (unsigned int i = 0; i < i_title; i++) {
1659         input_title_t *t = vlc_input_title_New();
1660         if (!t)
1661             break;
1662
1663         if (!p_sys->b_menu) {
1664             BLURAY_TITLE_INFO *title_info = bd_get_title_info(p_sys->bluray, i, 0);
1665             blurayUpdateTitleInfo(t, title_info);
1666             bd_free_title_info(title_info);
1667
1668         } else if (i == 0) {
1669             t->psz_name = strdup(_("Top Menu"));
1670             t->i_flags = INPUT_TITLE_MENU | INPUT_TITLE_INTERACTIVE;
1671         } else if (i == i_title - 1) {
1672             t->psz_name = strdup(_("First Play"));
1673             if (di && di->first_play && di->first_play->interactive) {
1674                 t->i_flags = INPUT_TITLE_INTERACTIVE;
1675             }
1676         } else {
1677             /* add possible title name from disc metadata */
1678             if (di && di->titles && i < di->num_titles) {
1679                 if (di->titles[i]->name) {
1680                     t->psz_name = strdup(di->titles[i]->name);
1681                 }
1682                 if (di->titles[i]->interactive) {
1683                     t->i_flags = INPUT_TITLE_INTERACTIVE;
1684                 }
1685             }
1686         }
1687
1688         TAB_APPEND(p_sys->i_title, p_sys->pp_title, t);
1689     }
1690 }
1691
1692 static void blurayResetParser(demux_t *p_demux)
1693 {
1694     /*
1695      * This is a hack and will have to be removed.
1696      * The parser should be flushed, and not destroy/created each time
1697      * we are changing title.
1698      */
1699     demux_sys_t *p_sys = p_demux->p_sys;
1700     if (p_sys->p_parser)
1701         stream_Delete(p_sys->p_parser);
1702
1703     p_sys->p_parser = stream_DemuxNew(p_demux, "ts", p_sys->p_out);
1704
1705     if (!p_sys->p_parser)
1706         msg_Err(p_demux, "Failed to create TS demuxer");
1707 }
1708
1709 /*****************************************************************************
1710  * bluraySetTitle: select new BD title
1711  *****************************************************************************/
1712 static int bluraySetTitle(demux_t *p_demux, int i_title)
1713 {
1714     demux_sys_t *p_sys = p_demux->p_sys;
1715
1716     if (p_sys->b_menu) {
1717         int result;
1718         if (i_title <= 0) {
1719             msg_Dbg(p_demux, "Playing TopMenu Title");
1720             result = bd_menu_call(p_sys->bluray, -1);
1721         } else if (i_title >= (int)p_sys->i_title - 1) {
1722             msg_Dbg(p_demux, "Playing FirstPlay Title");
1723             result = bd_play_title(p_sys->bluray, BLURAY_TITLE_FIRST_PLAY);
1724         } else {
1725             msg_Dbg(p_demux, "Playing Title %i", i_title);
1726             result = bd_play_title(p_sys->bluray, i_title);
1727         }
1728
1729         if (result == 0) {
1730             msg_Err(p_demux, "cannot play bd title '%d'", i_title);
1731             return VLC_EGENERIC;
1732         }
1733
1734         return VLC_SUCCESS;
1735     }
1736
1737     /* Looking for the main title, ie the longest duration */
1738     if (i_title < 0)
1739         i_title = p_sys->i_longest_title;
1740     else if ((unsigned)i_title > p_sys->i_title)
1741         return VLC_EGENERIC;
1742
1743     msg_Dbg(p_demux, "Selecting Title %i", i_title);
1744
1745     if (bd_select_title(p_sys->bluray, i_title) == 0) {
1746         msg_Err(p_demux, "cannot select bd title '%d'", i_title);
1747         return VLC_EGENERIC;
1748     }
1749
1750     blurayResetParser(p_demux);
1751
1752     return VLC_SUCCESS;
1753 }
1754
1755 #if BLURAY_VERSION < BLURAY_VERSION_CODE(0,9,2)
1756 #  define BLURAY_AUDIO_STREAM 0
1757 #endif
1758
1759 static void blurayStreamSelected(demux_sys_t *p_sys, int i_pid)
1760 {
1761     vlc_mutex_lock(&p_sys->pl_info_lock);
1762
1763     if (p_sys->p_clip_info) {
1764         if ((i_pid & 0xff00) == 0x1100) {
1765             // audio
1766             for (int i_id = 0; i_id < p_sys->p_clip_info->audio_stream_count; i_id++) {
1767                 if (i_pid == p_sys->p_clip_info->audio_streams[i_id].pid) {
1768                     p_sys->i_audio_stream_idx = i_id;
1769                     bd_select_stream(p_sys->bluray, BLURAY_AUDIO_STREAM, i_id + 1, 1);
1770                     break;
1771                 }
1772             }
1773         } else if ((i_pid & 0xff00) == 0x1400 || i_pid == 0x1800) {
1774             // subtitle
1775             for (int i_id = 0; i_id < p_sys->p_clip_info->pg_stream_count; i_id++) {
1776                 if (i_pid == p_sys->p_clip_info->pg_streams[i_id].pid) {
1777                     p_sys->i_spu_stream_idx = i_id;
1778                     bd_select_stream(p_sys->bluray, BLURAY_PG_TEXTST_STREAM, i_id + 1, 1);
1779                     break;
1780                 }
1781             }
1782         }
1783     }
1784
1785     vlc_mutex_unlock(&p_sys->pl_info_lock);
1786 }
1787
1788 /*****************************************************************************
1789  * blurayControl: handle the controls
1790  *****************************************************************************/
1791 static int blurayControl(demux_t *p_demux, int query, va_list args)
1792 {
1793     demux_sys_t *p_sys = p_demux->p_sys;
1794     bool     *pb_bool;
1795     int64_t  *pi_64;
1796
1797     switch (query) {
1798     case DEMUX_CAN_SEEK:
1799     case DEMUX_CAN_PAUSE:
1800     case DEMUX_CAN_CONTROL_PACE:
1801          pb_bool = (bool*)va_arg(args, bool *);
1802          *pb_bool = true;
1803          break;
1804
1805     case DEMUX_GET_PTS_DELAY:
1806         pi_64 = (int64_t*)va_arg(args, int64_t *);
1807         *pi_64 = INT64_C(1000) * var_InheritInteger(p_demux, "disc-caching");
1808         break;
1809
1810     case DEMUX_SET_PAUSE_STATE:
1811         /* Nothing to do */
1812         break;
1813     case DEMUX_SET_ES:
1814     {
1815         int i_id = (int)va_arg(args, int);
1816         blurayStreamSelected(p_sys, i_id);
1817         break;
1818     }
1819     case DEMUX_SET_TITLE:
1820     {
1821         int i_title = (int)va_arg(args, int);
1822         if (bluraySetTitle(p_demux, i_title) != VLC_SUCCESS) {
1823             /* make sure GUI restores the old setting in title menu ... */
1824             p_demux->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
1825             return VLC_EGENERIC;
1826         }
1827         break;
1828     }
1829     case DEMUX_SET_SEEKPOINT:
1830     {
1831         int i_chapter = (int)va_arg(args, int);
1832         bd_seek_chapter(p_sys->bluray, i_chapter);
1833         p_demux->info.i_update = INPUT_UPDATE_SEEKPOINT;
1834         break;
1835     }
1836
1837     case DEMUX_GET_TITLE_INFO:
1838     {
1839         input_title_t ***ppp_title = (input_title_t***)va_arg(args, input_title_t***);
1840         int *pi_int             = (int*)va_arg(args, int*);
1841         int *pi_title_offset    = (int*)va_arg(args, int*);
1842         int *pi_chapter_offset  = (int*)va_arg(args, int*);
1843
1844         /* */
1845         *pi_title_offset   = 0;
1846         *pi_chapter_offset = 0;
1847
1848         /* Duplicate local title infos */
1849         *pi_int = p_sys->i_title;
1850         *ppp_title = malloc(p_sys->i_title * sizeof(input_title_t *));
1851         for (unsigned int i = 0; i < p_sys->i_title; i++)
1852             (*ppp_title)[i] = vlc_input_title_Duplicate(p_sys->pp_title[i]);
1853
1854         return VLC_SUCCESS;
1855     }
1856
1857     case DEMUX_GET_LENGTH:
1858     {
1859         int64_t *pi_length = (int64_t*)va_arg(args, int64_t *);
1860         *pi_length = p_demux->info.i_title < (int)p_sys->i_title ? CUR_LENGTH : 0;
1861         return VLC_SUCCESS;
1862     }
1863     case DEMUX_SET_TIME:
1864     {
1865         int64_t i_time = (int64_t)va_arg(args, int64_t);
1866         bd_seek_time(p_sys->bluray, TO_TICKS(i_time));
1867         return VLC_SUCCESS;
1868     }
1869     case DEMUX_GET_TIME:
1870     {
1871         int64_t *pi_time = (int64_t*)va_arg(args, int64_t *);
1872         *pi_time = (int64_t)FROM_TICKS(bd_tell_time(p_sys->bluray));
1873         return VLC_SUCCESS;
1874     }
1875
1876     case DEMUX_GET_POSITION:
1877     {
1878         double *pf_position = (double*)va_arg(args, double *);
1879         *pf_position = p_demux->info.i_title < (int)p_sys->i_title && CUR_LENGTH > 0 ?
1880                       (double)FROM_TICKS(bd_tell_time(p_sys->bluray))/CUR_LENGTH : 0.0;
1881         return VLC_SUCCESS;
1882     }
1883     case DEMUX_SET_POSITION:
1884     {
1885         double f_position = (double)va_arg(args, double);
1886         bd_seek_time(p_sys->bluray, TO_TICKS(f_position*CUR_LENGTH));
1887         return VLC_SUCCESS;
1888     }
1889
1890     case DEMUX_GET_META:
1891     {
1892         vlc_meta_t *p_meta = (vlc_meta_t *) va_arg (args, vlc_meta_t*);
1893         const META_DL *meta = p_sys->p_meta;
1894         if (meta == NULL)
1895             return VLC_EGENERIC;
1896
1897         if (!EMPTY_STR(meta->di_name)) vlc_meta_SetTitle(p_meta, meta->di_name);
1898
1899         if (!EMPTY_STR(meta->language_code)) vlc_meta_AddExtra(p_meta, "Language", meta->language_code);
1900         if (!EMPTY_STR(meta->filename)) vlc_meta_AddExtra(p_meta, "Filename", meta->filename);
1901         if (!EMPTY_STR(meta->di_alternative)) vlc_meta_AddExtra(p_meta, "Alternative", meta->di_alternative);
1902
1903         // if (meta->di_set_number > 0) vlc_meta_SetTrackNum(p_meta, meta->di_set_number);
1904         // if (meta->di_num_sets > 0) vlc_meta_AddExtra(p_meta, "Discs numbers in Set", meta->di_num_sets);
1905
1906         if (p_sys->i_cover_idx >= 0 && p_sys->i_cover_idx < p_sys->i_attachments) {
1907             char psz_url[128];
1908             snprintf( psz_url, sizeof(psz_url), "attachment://%s",
1909                       p_sys->attachments[p_sys->i_cover_idx]->psz_name );
1910             vlc_meta_Set( p_meta, vlc_meta_ArtworkURL, psz_url );
1911         }
1912         else if (meta->thumb_count > 0 && meta->thumbnails && p_sys->psz_bd_path) {
1913             char *psz_thumbpath;
1914             if (asprintf(&psz_thumbpath, "%s" DIR_SEP "BDMV" DIR_SEP "META" DIR_SEP "DL" DIR_SEP "%s",
1915                           p_sys->psz_bd_path, meta->thumbnails[0].path) > 0) {
1916                 char *psz_thumburl = vlc_path2uri(psz_thumbpath, "file");
1917                 if (unlikely(psz_thumburl == NULL)) {
1918                     free(psz_thumbpath);
1919                     return VLC_ENOMEM;
1920                 }
1921
1922                 vlc_meta_SetArtURL(p_meta, psz_thumburl);
1923                 free(psz_thumburl);
1924             }
1925             free(psz_thumbpath);
1926         }
1927
1928         return VLC_SUCCESS;
1929     }
1930
1931     case DEMUX_GET_ATTACHMENTS:
1932     {
1933         input_attachment_t ***ppp_attach =
1934             (input_attachment_t ***)va_arg(args, input_attachment_t ***);
1935         int *pi_int = (int *)va_arg(args, int *);
1936
1937         if (p_sys->i_attachments <= 0)
1938             return VLC_EGENERIC;
1939
1940         *pi_int = p_sys->i_attachments;
1941         *ppp_attach = xmalloc(sizeof(input_attachment_t *) * p_sys->i_attachments);
1942         for (int i = 0; i < p_sys->i_attachments; i++)
1943             (*ppp_attach)[i] = vlc_input_attachment_Duplicate(p_sys->attachments[i]);
1944         return VLC_SUCCESS;
1945     }
1946
1947     case DEMUX_NAV_ACTIVATE:
1948         if (p_sys->b_popup_available && !p_sys->b_menu_open) {
1949             return sendKeyEvent(p_sys, BD_VK_POPUP);
1950         }
1951         return sendKeyEvent(p_sys, BD_VK_ENTER);
1952     case DEMUX_NAV_UP:
1953         return sendKeyEvent(p_sys, BD_VK_UP);
1954     case DEMUX_NAV_DOWN:
1955         return sendKeyEvent(p_sys, BD_VK_DOWN);
1956     case DEMUX_NAV_LEFT:
1957         return sendKeyEvent(p_sys, BD_VK_LEFT);
1958     case DEMUX_NAV_RIGHT:
1959         return sendKeyEvent(p_sys, BD_VK_RIGHT);
1960     case DEMUX_NAV_POPUP:
1961         return sendKeyEvent(p_sys, BD_VK_POPUP);
1962
1963     case DEMUX_CAN_RECORD:
1964     case DEMUX_GET_FPS:
1965     case DEMUX_SET_GROUP:
1966     case DEMUX_HAS_UNSUPPORTED_META:
1967         return VLC_EGENERIC;
1968     default:
1969         msg_Warn(p_demux, "unimplemented query (%d) in control", query);
1970         return VLC_EGENERIC;
1971     }
1972     return VLC_SUCCESS;
1973 }
1974
1975 /*****************************************************************************
1976  * libbluray event handling
1977  *****************************************************************************/
1978
1979 static void streamFlush( demux_sys_t *p_sys )
1980 {
1981     /*
1982      * MPEG-TS demuxer does not flush last video frame if size of PES packet is unknown.
1983      * Packet is flushed only when TS packet with PUSI flag set is received.
1984      *
1985      * Fix this by emitting (video) ts packet with PUSI flag set.
1986      * Add video sequence end code to payload so that also video decoder is flushed.
1987      * Set PES packet size in the payload so that it will be sent to decoder immediately.
1988      */
1989
1990     if (p_sys->b_flushed)
1991         return;
1992
1993     block_t *p_block = block_Alloc(192);
1994     if (!p_block)
1995         return;
1996
1997     static const uint8_t seq_end_pes[] = {
1998         0x00, 0x00, 0x01, 0xe0, 0x00, 0x07, 0x80, 0x00, 0x00,  /* PES header */
1999         0x00, 0x00, 0x01, 0xb7,                                /* PES payload: sequence end */
2000     };
2001     static const uint8_t vid_pusi_ts[] = {
2002         0x00, 0x00, 0x00, 0x00,                /* TP extra header (ATC) */
2003         0x47, 0x50, 0x11, 0x30,                /* TP header */
2004         (192 - (4 + 5) - sizeof(seq_end_pes)), /* adaptation field length */
2005         0x80,                                  /* adaptation field: discontinuity indicator */
2006     };
2007
2008     memset(p_block->p_buffer, 0, 192);
2009     memcpy(p_block->p_buffer, vid_pusi_ts, sizeof(vid_pusi_ts));
2010     memcpy(p_block->p_buffer + 192 - sizeof(seq_end_pes), seq_end_pes, sizeof(seq_end_pes));
2011     p_block->i_buffer = 192;
2012
2013     /* set correct sequence end code */
2014     vlc_mutex_lock(&p_sys->pl_info_lock);
2015     if (p_sys->p_clip_info != NULL) {
2016         if (p_sys->p_clip_info->video_streams[0].coding_type > 2) {
2017             /* VC1 / H.264 sequence end */
2018             p_block->p_buffer[191] = 0x0a;
2019         }
2020     }
2021     vlc_mutex_unlock(&p_sys->pl_info_lock);
2022
2023     stream_DemuxSend(p_sys->p_parser, p_block);
2024     p_sys->b_flushed = true;
2025 }
2026
2027 static void blurayResetStillImage( demux_t *p_demux )
2028 {
2029     demux_sys_t *p_sys = p_demux->p_sys;
2030
2031     if (p_sys->i_still_end_time) {
2032         p_sys->i_still_end_time = 0;
2033
2034         blurayResetParser(p_demux);
2035         es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
2036     }
2037 }
2038
2039 static void blurayStillImage( demux_t *p_demux, unsigned i_timeout )
2040 {
2041     demux_sys_t *p_sys = p_demux->p_sys;
2042
2043     /* time period elapsed ? */
2044     if (p_sys->i_still_end_time > 0 && p_sys->i_still_end_time <= mdate()) {
2045         msg_Dbg(p_demux, "Still image end");
2046         bd_read_skip_still(p_sys->bluray);
2047
2048         blurayResetStillImage(p_demux);
2049         return;
2050     }
2051
2052     /* show last frame as still image */
2053     if (!p_sys->i_still_end_time) {
2054         if (i_timeout) {
2055             msg_Dbg(p_demux, "Still image (%d seconds)", i_timeout);
2056             p_sys->i_still_end_time = mdate() + i_timeout * CLOCK_FREQ;
2057         } else {
2058             msg_Dbg(p_demux, "Still image (infinite)");
2059             p_sys->i_still_end_time = -1;
2060         }
2061
2062         /* flush demuxer and decoder (there won't be next video packet starting with ts PUSI) */
2063         streamFlush(p_sys);
2064
2065         /* stop buffering */
2066         bool b_empty;
2067         es_out_Control( p_demux->out, ES_OUT_GET_EMPTY, &b_empty );
2068     }
2069
2070     /* avoid busy loops (read returns no data) */
2071     msleep( 40000 );
2072 }
2073
2074 static void blurayStreamSelect(demux_t *p_demux, uint32_t i_type, uint32_t i_id)
2075 {
2076     demux_sys_t *p_sys = p_demux->p_sys;
2077     int i_pid = -1;
2078
2079     /* The param we get is the real stream id, not an index, ie. it starts from 1 */
2080     i_id--;
2081
2082     if (i_type == BD_EVENT_AUDIO_STREAM) {
2083         p_sys->i_audio_stream_idx = i_id;
2084         i_pid = blurayEsPid(p_sys, AUDIO_ES, i_id);
2085     } else if (i_type == BD_EVENT_PG_TEXTST_STREAM) {
2086         p_sys->i_spu_stream_idx = i_id;
2087         i_pid = blurayEsPid(p_sys, SPU_ES, i_id);
2088     }
2089
2090     if (i_pid > 0) {
2091         int i_idx = findEsPairIndex(p_sys, i_pid);
2092         if (i_idx >= 0) {
2093             if (i_type == BD_EVENT_AUDIO_STREAM) {
2094                 var_SetInteger( p_demux->p_input, "audio-es", i_pid );
2095             } else if (i_type == BD_EVENT_PG_TEXTST_STREAM) {
2096                 var_SetInteger( p_demux->p_input, "spu-es", p_sys->b_spu_enable ? i_pid : -1 );
2097             }
2098         }
2099     }
2100 }
2101
2102 static void blurayUpdatePlaylist(demux_t *p_demux, unsigned i_playlist)
2103 {
2104     demux_sys_t *p_sys = p_demux->p_sys;
2105
2106     blurayResetParser(p_demux);
2107
2108     /* read title info and init some values */
2109     if (!p_sys->b_menu)
2110         p_demux->info.i_title = bd_get_current_title(p_sys->bluray);
2111     p_demux->info.i_seekpoint = 0;
2112     p_demux->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
2113
2114     BLURAY_TITLE_INFO *p_title_info = bd_get_playlist_info(p_sys->bluray, i_playlist, 0);
2115     if (p_title_info) {
2116         blurayUpdateTitleInfo(p_sys->pp_title[p_demux->info.i_title], p_title_info);
2117         if (p_sys->b_menu)
2118             p_demux->info.i_update |= INPUT_UPDATE_TITLE_LIST;
2119     }
2120     setTitleInfo(p_sys, p_title_info);
2121
2122     blurayResetStillImage(p_demux);
2123 }
2124
2125 static void blurayUpdateCurrentClip(demux_t *p_demux, uint32_t clip)
2126 {
2127     demux_sys_t *p_sys = p_demux->p_sys;
2128
2129     vlc_mutex_lock(&p_sys->pl_info_lock);
2130
2131     p_sys->p_clip_info = NULL;
2132     p_sys->i_video_stream = -1;
2133
2134     if (p_sys->p_pl_info && clip < p_sys->p_pl_info->clip_count) {
2135
2136         p_sys->p_clip_info = &p_sys->p_pl_info->clips[clip];
2137
2138     /* Let's assume a single video track for now.
2139      * This may brake later, but it's enough for now.
2140      */
2141         assert(p_sys->p_clip_info->video_stream_count >= 1);
2142         p_sys->i_video_stream = p_sys->p_clip_info->video_streams[0].pid;
2143     }
2144
2145     vlc_mutex_unlock(&p_sys->pl_info_lock);
2146
2147     blurayResetStillImage(p_demux);
2148 }
2149
2150 static void blurayHandleEvent(demux_t *p_demux, const BD_EVENT *e)
2151 {
2152     demux_sys_t *p_sys = p_demux->p_sys;
2153
2154     switch (e->event) {
2155     case BD_EVENT_TITLE:
2156         if (e->param == BLURAY_TITLE_FIRST_PLAY)
2157             p_demux->info.i_title = p_sys->i_title - 1;
2158         else
2159             p_demux->info.i_title = e->param;
2160         /* this is feature title, we don't know yet which playlist it will play (if any) */
2161         setTitleInfo(p_sys, NULL);
2162         /* reset title infos here ? */
2163         p_demux->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT; /* might be BD-J title with no video */
2164         break;
2165     case BD_EVENT_PLAYLIST:
2166         /* Start of playlist playback (?????.mpls) */
2167         blurayUpdatePlaylist(p_demux, e->param);
2168         if (p_sys->b_pl_playing) {
2169             /* previous playlist was stopped in middle. flush to avoid delay */
2170             msg_Info(p_demux, "Stopping playlist playback");
2171             blurayResetParser(p_demux);
2172             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
2173         }
2174         p_sys->b_pl_playing = true;
2175         break;
2176     case BD_EVENT_PLAYITEM:
2177         blurayUpdateCurrentClip(p_demux, e->param);
2178         break;
2179     case BD_EVENT_CHAPTER:
2180         if (e->param && e->param < 0xffff)
2181           p_demux->info.i_seekpoint = e->param - 1;
2182         else
2183           p_demux->info.i_seekpoint = 0;
2184         p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
2185         break;
2186     case BD_EVENT_PLAYMARK:
2187     case BD_EVENT_ANGLE:
2188         break;
2189 #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0,8,1)
2190     case BD_EVENT_UO_MASK_CHANGED:
2191         /* This event could be used to grey out unselectable items in title menu */
2192         break;
2193 #endif
2194     case BD_EVENT_MENU:
2195         p_sys->b_menu_open = e->param;
2196         break;
2197     case BD_EVENT_POPUP:
2198         p_sys->b_popup_available = e->param;
2199         /* TODO: show / hide pop-up menu button in gui ? */
2200         break;
2201
2202     /*
2203      * Errors
2204      */
2205     case BD_EVENT_ERROR:
2206         /* fatal error (with menus) */
2207         dialog_Fatal(p_demux, _("Blu-ray error"), "Playback with BluRay menus failed");
2208         p_sys->b_fatal_error = true;
2209         break;
2210     case BD_EVENT_ENCRYPTED:
2211         dialog_Fatal(p_demux, _("Blu-ray error"), "This disc seems to be encrypted");
2212         p_sys->b_fatal_error = true;
2213         break;
2214     case BD_EVENT_READ_ERROR:
2215         msg_Err(p_demux, "bluray: read error\n");
2216         break;
2217
2218     /*
2219      * stream selection events
2220      */
2221     case BD_EVENT_PG_TEXTST:
2222         p_sys->b_spu_enable = e->param;
2223         break;
2224     case BD_EVENT_AUDIO_STREAM:
2225     case BD_EVENT_PG_TEXTST_STREAM:
2226         blurayStreamSelect(p_demux, e->event, e->param);
2227         break;
2228     case BD_EVENT_IG_STREAM:
2229     case BD_EVENT_SECONDARY_AUDIO:
2230     case BD_EVENT_SECONDARY_AUDIO_STREAM:
2231     case BD_EVENT_SECONDARY_VIDEO:
2232     case BD_EVENT_SECONDARY_VIDEO_STREAM:
2233     case BD_EVENT_SECONDARY_VIDEO_SIZE:
2234         break;
2235
2236     /*
2237      * playback control events
2238      */
2239     case BD_EVENT_STILL_TIME:
2240         blurayStillImage(p_demux, e->param);
2241         break;
2242     case BD_EVENT_DISCONTINUITY:
2243         /* reset demuxer (partially decoded PES packets must be dropped) */
2244         blurayResetParser(p_demux);
2245         break;
2246     case BD_EVENT_END_OF_TITLE:
2247         p_sys->b_pl_playing = false;
2248         break;
2249     case BD_EVENT_IDLE:
2250         /* nothing to do (ex. BD-J is preparing menus, waiting user input or running animation) */
2251         /* avoid busy loop (bd_read() returns no data) */
2252         msleep( 40000 );
2253         break;
2254
2255     default:
2256         msg_Warn(p_demux, "event: %d param: %d", e->event, e->param);
2257         break;
2258     }
2259 }
2260
2261 static bool blurayIsBdjTitle(demux_t *p_demux)
2262 {
2263     demux_sys_t *p_sys = p_demux->p_sys;
2264     unsigned int i_title = p_demux->info.i_title;
2265     const BLURAY_DISC_INFO *di = bd_get_disc_info(p_sys->bluray);
2266
2267     if (di && di->titles) {
2268         if ((i_title <= di->num_titles && di->titles[i_title] && di->titles[i_title]->bdj) ||
2269             (i_title == p_sys->i_title - 1 && di->first_play && di->first_play->bdj)) {
2270           return true;
2271         }
2272     }
2273
2274     return false;
2275 }
2276
2277 static void blurayHandleOverlays(demux_t *p_demux, int nread)
2278 {
2279     demux_sys_t *p_sys = p_demux->p_sys;
2280
2281     vlc_mutex_lock(&p_sys->bdj_overlay_lock);
2282
2283     for (int i = 0; i < MAX_OVERLAY; i++) {
2284         bluray_overlay_t *ov = p_sys->p_overlays[i];
2285         if (!ov) {
2286             continue;
2287         }
2288         vlc_mutex_lock(&ov->lock);
2289         bool display = ov->status == ToDisplay;
2290         vlc_mutex_unlock(&ov->lock);
2291         if (display) {
2292             if (p_sys->p_vout == NULL) {
2293                 p_sys->p_vout = input_GetVout(p_demux->p_input);
2294                 if (p_sys->p_vout != NULL) {
2295                     var_AddCallback(p_sys->p_vout, "mouse-moved", onMouseEvent, p_demux);
2296                     var_AddCallback(p_sys->p_vout, "mouse-clicked", onMouseEvent, p_demux);
2297                 }
2298             }
2299
2300             /* NOTE: we might want to enable background video always when there's no video stream playing.
2301                Now, with some discs, there are perioids (even seconds) during which the video window
2302                disappears and just playlist is shown.
2303                (sometimes BD-J runs slowly ...)
2304             */
2305             if (!p_sys->p_vout && !p_sys->p_dummy_video && p_sys->b_menu &&
2306                 !p_sys->p_pl_info && nread == 0 &&
2307                 blurayIsBdjTitle(p_demux)) {
2308
2309                 /* Looks like there's no video stream playing.
2310                    Emit blank frame so that BD-J overlay can be drawn. */
2311                 startBackground(p_demux);
2312             }
2313
2314             if (p_sys->p_vout != NULL) {
2315                 bluraySendOverlayToVout(p_demux, ov);
2316             }
2317         }
2318     }
2319
2320     vlc_mutex_unlock(&p_sys->bdj_overlay_lock);
2321 }
2322
2323 static int onIntfEvent( vlc_object_t *p_input, char const *psz_var,
2324                         vlc_value_t oldval, vlc_value_t val, void *p_data )
2325 {
2326     (void)p_input; (void) psz_var; (void) oldval;
2327     demux_t *p_demux = p_data;
2328     demux_sys_t *p_sys = p_demux->p_sys;
2329
2330     if (val.i_int == INPUT_EVENT_VOUT) {
2331
2332         vlc_mutex_lock(&p_sys->bdj_overlay_lock);
2333         if( p_sys->p_vout != NULL ) {
2334             blurayReleaseVout(p_demux);
2335         }
2336         vlc_mutex_unlock(&p_sys->bdj_overlay_lock);
2337
2338         blurayHandleOverlays(p_demux, 1);
2339     }
2340
2341     return VLC_SUCCESS;
2342 }
2343
2344 #define BD_TS_PACKET_SIZE (192)
2345 #define NB_TS_PACKETS (200)
2346
2347 static int blurayDemux(demux_t *p_demux)
2348 {
2349     demux_sys_t *p_sys = p_demux->p_sys;
2350     BD_EVENT e;
2351
2352     block_t *p_block = block_Alloc(NB_TS_PACKETS * (int64_t)BD_TS_PACKET_SIZE);
2353     if (!p_block)
2354         return VLC_DEMUXER_EGENERIC;
2355
2356     int nread;
2357
2358     if (p_sys->b_menu == false) {
2359         while (bd_get_event(p_sys->bluray, &e))
2360             blurayHandleEvent(p_demux, &e);
2361
2362         nread = bd_read(p_sys->bluray, p_block->p_buffer,
2363                         NB_TS_PACKETS * BD_TS_PACKET_SIZE);
2364     } else {
2365         nread = bd_read_ext(p_sys->bluray, p_block->p_buffer,
2366                             NB_TS_PACKETS * BD_TS_PACKET_SIZE, &e);
2367         while (e.event != BD_EVENT_NONE) {
2368             blurayHandleEvent(p_demux, &e);
2369             bd_get_event(p_sys->bluray, &e);
2370         }
2371     }
2372
2373     blurayHandleOverlays(p_demux, nread);
2374
2375     if (nread <= 0) {
2376         block_Release(p_block);
2377         if (p_sys->b_fatal_error || nread < 0) {
2378             msg_Err(p_demux, "bluray: stopping playback after fatal error\n");
2379             return VLC_DEMUXER_EGENERIC;
2380         }
2381         if (!p_sys->b_menu) {
2382             return VLC_DEMUXER_EOF;
2383         }
2384         return VLC_DEMUXER_SUCCESS;
2385     }
2386
2387     p_block->i_buffer = nread;
2388
2389     stopBackground(p_demux);
2390
2391     stream_DemuxSend(p_sys->p_parser, p_block);
2392
2393     p_sys->b_flushed = false;
2394
2395     return VLC_DEMUXER_SUCCESS;
2396 }