add_savefile: remove callback parameter
[vlc/asuraparaju-public.git] / modules / access / bluray.c
blob9610cb37809b880b3f6b7759d19fa281d6a305ce
1 /*****************************************************************************
2 * bluray.c: Blu-ray disc support plugin
3 *****************************************************************************
4 * Copyright (C) 2010 VideoLAN, VLC authors and libbluray AUTHORS
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #ifdef HAVE_SYS_STAT_H
26 # include <sys/stat.h>
27 #endif
29 #include <assert.h>
30 #include <limits.h>
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_access.h>
35 #include <vlc_messages.h>
37 #include <libbluray/bluray.h>
39 /*****************************************************************************
40 * Module descriptor
41 *****************************************************************************/
42 #define CACHING_TEXT N_("Caching value in ms")
43 #define CACHING_LONGTEXT N_( "Caching value for BDs. This "\
44 "value should be set in milliseconds." )
46 /* Callbacks */
47 static int blurayOpen ( vlc_object_t * );
48 static void blurayClose( vlc_object_t * );
50 vlc_module_begin ()
51 set_shortname( N_("BluRay") )
52 set_description( N_("Blu-Ray Disc support (libbluray)") )
54 set_category( CAT_INPUT )
55 set_subcategory( SUBCAT_INPUT_ACCESS )
56 set_capability( "access", 60 )
58 add_integer( "bluray-caching", 1000, NULL,
59 CACHING_TEXT, CACHING_LONGTEXT, true )
61 add_shortcut( "bluray" )
62 add_shortcut( "file" )
64 set_callbacks( blurayOpen, blurayClose )
65 vlc_module_end ()
67 /*****************************************************************************
68 * Local prototypes
69 *****************************************************************************/
71 struct access_sys_t
73 BLURAY *bluray; /* */
74 int i_bd_delay;
77 static ssize_t blurayRead (access_t *, uint8_t *, size_t);
78 static int bluraySeek (access_t *, uint64_t);
79 static int blurayControl(access_t *, int, va_list);
80 static int bluraySetTitle(access_t *p_access, int i_tile);
82 /*****************************************************************************
83 * blurayOpen: module init function
84 *****************************************************************************/
85 static int blurayOpen( vlc_object_t *object )
87 access_t *p_access = (access_t*)object;
89 access_sys_t *p_sys;
90 char *pos_title;
91 int i_title = -1;
92 char bd_path[PATH_MAX];
94 if( strcmp( p_access->psz_access, "bluray" ) ) {
95 // TODO BDMV support, once we figure out what to do in libbluray
96 return VLC_EGENERIC;
99 /* init access fields */
100 access_InitFields(p_access);
102 /* register callback function for communication */
103 ACCESS_SET_CALLBACKS(blurayRead, NULL, blurayControl, bluraySeek);
105 p_access->p_sys = p_sys = malloc(sizeof(access_sys_t));
106 if (unlikely(!p_sys)) {
107 return VLC_ENOMEM;
110 /* store current bd_path */
111 strncpy(bd_path, p_access->psz_location, sizeof(bd_path));
112 bd_path[PATH_MAX - 1] = '\0';
114 if ( (pos_title = strrchr(bd_path, ':')) ) {
115 /* found character ':' for title information */
116 *(pos_title++) = '\0';
117 i_title = atoi(pos_title);
120 p_sys->bluray = bd_open(bd_path, NULL);
121 if ( !p_sys->bluray ) {
122 free(p_sys);
123 return VLC_EGENERIC;
126 /* set start title number */
127 if ( bluraySetTitle(p_access, i_title) != VLC_SUCCESS ) {
128 blurayClose(object);
129 return VLC_EGENERIC;
132 p_sys->i_bd_delay = var_InheritInteger(p_access, "bluray-caching");
134 return VLC_SUCCESS;
138 /*****************************************************************************
139 * blurayClose: module destroy function
140 *****************************************************************************/
141 static void blurayClose( vlc_object_t *object )
143 access_t *p_access = (access_t*)object;
144 access_sys_t *p_sys = p_access->p_sys;
146 /* bd_close( NULL ) can crash */
147 assert(p_sys->bluray);
148 bd_close(p_sys->bluray);
149 free(p_sys);
153 /*****************************************************************************
154 * bluraySetTitle: select new BD title
155 *****************************************************************************/
156 static int bluraySetTitle(access_t *p_access, int i_title)
158 access_sys_t *p_sys = p_access->p_sys;
160 unsigned int i_nb_titles = bd_get_titles(p_sys->bluray, TITLES_RELEVANT);
162 /* Looking for the main title, ie the longest duration */
163 if (i_title == -1) {
164 uint64_t duration=0;
165 for (unsigned int i = 0; i < i_nb_titles; i++) {
166 BLURAY_TITLE_INFO *info = bd_get_title_info(p_sys->bluray, i);
167 if (info->duration > duration) {
168 i_title = i;
169 duration = info->duration;
174 /* Select Blu-Ray title */
175 if ( bd_select_title(p_access->p_sys->bluray, i_title) == 0 ) {
176 msg_Err( p_access, "cannot select bd title '%d'", p_access->info.i_title);
177 return VLC_EGENERIC;
180 /* read title length and init some values */
181 p_access->info.i_title = i_title;
182 p_access->info.i_size = bd_get_title_size(p_sys->bluray);
183 p_access->info.i_pos = 0;
184 p_access->info.b_eof = false;
185 p_access->info.i_seekpoint = 0;
187 return VLC_SUCCESS;
191 /*****************************************************************************
192 * blurayControl: handle the controls
193 *****************************************************************************/
194 static int blurayControl(access_t *p_access, int query, va_list args)
196 access_sys_t *p_sys = p_access->p_sys;
197 bool *pb_bool;
198 int64_t *pi_64;
200 switch (query) {
201 case ACCESS_CAN_SEEK:
202 case ACCESS_CAN_FASTSEEK:
203 case ACCESS_CAN_PAUSE:
204 case ACCESS_CAN_CONTROL_PACE:
205 pb_bool = (bool*)va_arg( args, bool * );
206 *pb_bool = true;
207 break;
209 case ACCESS_GET_PTS_DELAY:
210 pi_64 = (int64_t*)va_arg( args, int64_t * );
211 *pi_64 = p_sys->i_bd_delay;
212 break;
214 case ACCESS_SET_PAUSE_STATE:
215 /* Nothing to do */
216 break;
218 case ACCESS_SET_TITLE:
220 int i_title = (int)va_arg( args, int );
221 if( bluraySetTitle( p_access, i_title ) != VLC_SUCCESS )
222 return VLC_EGENERIC;
223 break;
225 case ACCESS_SET_SEEKPOINT:
227 int i_chapter = (int)va_arg( args, int );
228 bd_seek_chapter( p_sys->bluray, i_chapter );
229 break;
231 case ACCESS_GET_META:
232 case ACCESS_GET_TITLE_INFO:
233 case ACCESS_SET_PRIVATE_ID_STATE:
234 case ACCESS_GET_CONTENT_TYPE:
235 return VLC_EGENERIC;
237 default:
238 msg_Warn( p_access, "unimplemented query (%d) in control", query );
239 return VLC_EGENERIC;
242 return VLC_SUCCESS;
246 /*****************************************************************************
247 * bluraySeek: seek to the given position
248 *****************************************************************************/
249 static int bluraySeek(access_t *p_access, uint64_t position)
251 access_sys_t *p_sys = p_access->p_sys;
253 p_access->info.i_pos = bd_seek(p_sys->bluray, position);
254 p_access->info.b_eof = false;
256 return VLC_SUCCESS;
260 /*****************************************************************************
261 * blurayRead: read BD data into buffer
262 *****************************************************************************/
263 static ssize_t blurayRead(access_t *p_access, uint8_t *data, size_t size)
265 access_sys_t *p_sys = p_access->p_sys;
266 int nread;
268 if (p_access->info.b_eof) {
269 return 0;
272 /* read data into buffer with given length */
273 nread = bd_read(p_sys->bluray, data, size);
275 if( nread == 0 ) {
276 p_access->info.b_eof = true;
278 else if( nread > 0 ) {
279 p_access->info.i_pos += nread;
282 return nread;