1 /*****************************************************************************
2 * mtp.c: mtp input (mtp: access plug-in)
3 *****************************************************************************
4 * Copyright (C) 2001-2006 VLC authors and VideoLAN
5 * Copyright © 2006-2008 Rémi Denis-Courmont
7 * Authors: Fabio Ritrovato <exsephiroth87@gmail.com>
8 * Original file.c: Christophe Massiot <massiot@via.ecp.fr>
9 * Rémi Denis-Courmont <rem # videolan # org>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
35 #include <sys/types.h>
40 #include <vlc_common.h>
41 #include <vlc_plugin.h>
42 #include <vlc_input.h>
43 #include <vlc_access.h>
44 #include <vlc_dialog.h>
49 /*****************************************************************************
51 *****************************************************************************/
53 static int Open ( vlc_object_t
* );
54 static void Close( vlc_object_t
* );
57 set_description( N_("MTP input") )
58 set_shortname( N_("MTP") )
59 set_category( CAT_INPUT
)
60 set_subcategory( SUBCAT_INPUT_ACCESS
)
61 set_capability( "access", 0 )
63 set_callbacks( Open
, Close
)
66 /*****************************************************************************
68 *****************************************************************************/
70 static int Seek( access_t
*, uint64_t );
71 static ssize_t
Read( access_t
*, uint8_t *, size_t );
72 static int Control( access_t
*, int, va_list );
74 static int open_file( access_t
*, const char * );
81 /*****************************************************************************
83 *****************************************************************************/
84 static int Open( vlc_object_t
*p_this
)
86 access_t
*p_access
= ( access_t
* )p_this
;
90 uint16_t i_product_id
;
92 LIBMTP_raw_device_t
*p_rawdevices
;
93 LIBMTP_mtpdevice_t
*p_device
;
97 if( sscanf( p_access
->psz_location
, "%"SCNu32
":%"SCNu8
":%"SCNu16
":%d",
98 &i_bus
, &i_dev
, &i_product_id
, &i_track_id
) != 4 )
100 i_ret
= LIBMTP_Detect_Raw_Devices( &p_rawdevices
, &i_numrawdevices
);
101 if( i_ret
!= 0 || i_numrawdevices
<= 0 || !p_rawdevices
)
104 for( int i
= 0; i
< i_numrawdevices
; i
++ )
106 if( i_bus
== p_rawdevices
[i
].bus_location
&&
107 i_dev
== p_rawdevices
[i
].devnum
&&
108 i_product_id
== p_rawdevices
[i
].device_entry
.product_id
)
110 if( ( p_device
= LIBMTP_Open_Raw_Device( &p_rawdevices
[i
] )
113 free( p_access
->psz_filepath
);
114 #warning Oooh no! Not tempnam()!
115 p_access
->psz_filepath
= tempnam( NULL
, "vlc" );
116 if( p_access
->psz_filepath
== NULL
)
118 LIBMTP_Release_Device( p_device
);
119 free( p_rawdevices
);
124 msg_Dbg( p_access
, "About to write %s",
125 p_access
->psz_filepath
);
126 LIBMTP_Get_File_To_File( p_device
, i_track_id
,
127 p_access
->psz_filepath
, NULL
,
129 LIBMTP_Release_Device( p_device
);
135 free( p_rawdevices
);
140 free( p_rawdevices
);
142 STANDARD_READ_ACCESS_INIT
;
143 int fd
= p_sys
->fd
= -1;
146 msg_Dbg( p_access
, "opening file `%s'", p_access
->psz_filepath
);
147 fd
= open_file( p_access
, p_access
->psz_filepath
);
159 /*****************************************************************************
160 * Close: close the target
161 *****************************************************************************/
162 static void Close( vlc_object_t
* p_this
)
164 access_t
*p_access
= ( access_t
* )p_this
;
165 access_sys_t
*p_sys
= p_access
->p_sys
;
168 if( vlc_unlink( p_access
->psz_filepath
) != 0 )
169 msg_Err( p_access
, "Error deleting file %s, %s",
170 p_access
->psz_filepath
, vlc_strerror_c(errno
) );
174 /*****************************************************************************
175 * Read: standard read on a file descriptor.
176 *****************************************************************************/
177 static ssize_t
Read( access_t
*p_access
, uint8_t *p_buffer
, size_t i_len
)
179 access_sys_t
*p_sys
= p_access
->p_sys
;
183 i_ret
= read( fd
, p_buffer
, i_len
);
194 msg_Err( p_access
, "read failed: %s", vlc_strerror_c(errno
) );
195 dialog_Fatal( p_access
, _( "File reading failed" ),
196 _( "VLC could not read the file: %s" ),
197 vlc_strerror(errno
) );
198 p_access
->info
.b_eof
= true;
203 p_access
->info
.i_pos
+= i_ret
;
205 p_access
->info
.b_eof
= true;
211 /*****************************************************************************
212 * Seek: seek to a specific location in a file
213 *****************************************************************************/
214 static int Seek( access_t
*p_access
, uint64_t i_pos
)
216 p_access
->info
.i_pos
= i_pos
;
217 p_access
->info
.b_eof
= false;
219 if (lseek( p_access
->p_sys
->fd
, i_pos
, SEEK_SET
) == (off_t
)-1)
224 /*****************************************************************************
226 *****************************************************************************/
227 static int Control( access_t
*p_access
, int i_query
, va_list args
)
229 access_sys_t
*sys
= p_access
->p_sys
;
235 case ACCESS_CAN_SEEK
:
236 case ACCESS_CAN_FASTSEEK
:
237 pb_bool
= ( bool* )va_arg( args
, bool* );
241 case ACCESS_CAN_PAUSE
:
242 case ACCESS_CAN_CONTROL_PACE
:
243 pb_bool
= ( bool* )va_arg( args
, bool* );
247 case ACCESS_GET_SIZE
:
249 uint64_t *s
= va_arg( args
, uint64_t * );
251 if( fstat( sys
->fd
, &st
) )
253 msg_Err( p_access
, "fstat error: %s", vlc_strerror_c(errno
) );
260 case ACCESS_GET_PTS_DELAY
:
261 pi_64
= ( int64_t* )va_arg( args
, int64_t * );
262 *pi_64
= INT64_C(1000)
263 * var_InheritInteger( p_access
, "file-caching" );
266 case ACCESS_SET_PAUSE_STATE
:
277 /*****************************************************************************
278 * open_file: Opens a specific file
279 *****************************************************************************/
280 static int open_file( access_t
*p_access
, const char *path
)
282 int fd
= vlc_open( path
, O_RDONLY
| O_NONBLOCK
);
285 msg_Err( p_access
, "cannot open file %s: %s", path
,
286 vlc_strerror_c(errno
) );
287 dialog_Fatal( p_access
, _( "File reading failed" ),
288 _( "VLC could not open the file \"%s\": %s" ), path
,
289 vlc_strerror(errno
) );
293 fcntl( fd
, F_RDAHEAD
, 1 );
296 fcntl( fd
, F_NOCACHE
, 0 );