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