demux: hls: fix unused variable warning
[vlc.git] / src / input / access.c
blob2e7c1aea1da5cdcb2ea22daf3e08ce3cee6844e7
1 /*****************************************************************************
2 * access.c
3 *****************************************************************************
4 * Copyright (C) 1999-2008 VLC authors and VideoLAN
5 * $Id$
7 * Author: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
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.
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.
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 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include <vlc_common.h>
33 #include <vlc_url.h>
34 #include <vlc_modules.h>
35 #include <vlc_interrupt.h>
37 #include <libvlc.h>
38 #include "stream.h"
39 #include "input_internal.h"
41 /* Decode URL (which has had its scheme stripped earlier) to a file path. */
42 char *get_path(const char *location)
44 char *url, *path;
46 /* Prepending "file://" is a bit hackish. But then again, we do not want
47 * to hard-code the list of schemes that use file paths in vlc_uri2path().
49 if (asprintf(&url, "file://%s", location) == -1)
50 return NULL;
52 path = vlc_uri2path (url);
53 free (url);
54 return path;
57 static void vlc_access_Destroy(stream_t *access)
59 module_unneed(access, access->p_module);
60 free(access->psz_filepath);
61 free(access->psz_name);
64 #define MAX_REDIR 5
66 /*****************************************************************************
67 * access_New:
68 *****************************************************************************/
69 static stream_t *access_New(vlc_object_t *parent, input_thread_t *input,
70 bool preparsing, const char *mrl)
72 char *redirv[MAX_REDIR];
73 unsigned redirc = 0;
75 stream_t *access = vlc_stream_CommonNew(parent, vlc_access_Destroy);
76 if (unlikely(access == NULL))
77 return NULL;
79 access->p_input = input;
80 access->psz_name = NULL;
81 access->psz_url = strdup(mrl);
82 access->psz_filepath = NULL;
83 access->b_preparsing = preparsing;
85 if (unlikely(access->psz_url == NULL))
86 goto error;
88 while (redirc < MAX_REDIR)
90 char *url = access->psz_url;
91 msg_Dbg(access, "creating access: %s", url);
93 const char *p = strstr(url, "://");
94 if (p == NULL)
95 goto error;
97 access->psz_name = strndup(url, p - url);
98 if (unlikely(access->psz_name == NULL))
99 goto error;
101 access->psz_location = p + 3;
102 access->psz_filepath = get_path(access->psz_location);
103 if (access->psz_filepath != NULL)
104 msg_Dbg(access, " (path: %s)", access->psz_filepath);
106 access->p_module = module_need(access, "access", access->psz_name,
107 true);
108 if (access->p_module != NULL) /* success */
110 while (redirc > 0)
111 free(redirv[--redirc]);
113 assert(access->pf_control != NULL);
114 return access;
117 if (access->psz_url == url) /* failure (no redirection) */
118 goto error;
120 /* redirection */
121 msg_Dbg(access, "redirecting to: %s", access->psz_url);
122 redirv[redirc++] = url;
124 for (unsigned j = 0; j < redirc; j++)
125 if (!strcmp(redirv[j], access->psz_url))
127 msg_Err(access, "redirection loop");
128 goto error;
131 free(access->psz_filepath);
132 free(access->psz_name);
133 access->psz_filepath = access->psz_name = NULL;
136 msg_Err(access, "too many redirections");
137 error:
138 while (redirc > 0)
139 free(redirv[--redirc]);
140 free(access->psz_filepath);
141 free(access->psz_name);
142 stream_CommonDelete(access);
143 return NULL;
146 stream_t *vlc_access_NewMRL(vlc_object_t *parent, const char *mrl)
148 return access_New(parent, NULL, false, mrl);
151 /*****************************************************************************
152 * access_vaDirectoryControlHelper:
153 *****************************************************************************/
154 int access_vaDirectoryControlHelper( stream_t *p_access, int i_query, va_list args )
156 VLC_UNUSED( p_access );
158 switch( i_query )
160 case STREAM_CAN_SEEK:
161 case STREAM_CAN_FASTSEEK:
162 case STREAM_CAN_PAUSE:
163 case STREAM_CAN_CONTROL_PACE:
164 *va_arg( args, bool* ) = false;
165 break;
166 case STREAM_GET_PTS_DELAY:
167 *va_arg( args, int64_t * ) = 0;
168 break;
169 case STREAM_IS_DIRECTORY:
170 break;
171 default:
172 return VLC_EGENERIC;
174 return VLC_SUCCESS;
177 static int AStreamNoReadDir(stream_t *s, input_item_node_t *p_node)
179 (void) s; (void) p_node;
180 return VLC_EGENERIC;;
183 /* Block access */
184 static block_t *AStreamReadBlock(stream_t *s, bool *restrict eof)
186 stream_t *access = s->p_sys;
187 input_thread_t *input = s->p_input;
188 block_t * block;
190 if (vlc_stream_Eof(access))
192 *eof = true;
193 return NULL;
195 if (vlc_killed())
196 return NULL;
198 block = vlc_stream_ReadBlock(access);
200 if (block != NULL && input != NULL)
202 uint64_t total;
204 vlc_mutex_lock(&input_priv(input)->counters.counters_lock);
205 stats_Update(input_priv(input)->counters.p_read_bytes,
206 block->i_buffer, &total);
207 stats_Update(input_priv(input)->counters.p_input_bitrate, total, NULL);
208 stats_Update(input_priv(input)->counters.p_read_packets, 1, NULL);
209 vlc_mutex_unlock(&input_priv(input)->counters.counters_lock);
212 return block;
215 /* Read access */
216 static ssize_t AStreamReadStream(stream_t *s, void *buf, size_t len)
218 stream_t *access = s->p_sys;
219 input_thread_t *input = s->p_input;
221 if (vlc_stream_Eof(access))
222 return 0;
223 if (vlc_killed())
224 return -1;
226 ssize_t val = vlc_stream_ReadPartial(access, buf, len);
228 if (val > 0 && input != NULL)
230 uint64_t total;
232 vlc_mutex_lock(&input_priv(input)->counters.counters_lock);
233 stats_Update(input_priv(input)->counters.p_read_bytes, val, &total);
234 stats_Update(input_priv(input)->counters.p_input_bitrate, total, NULL);
235 stats_Update(input_priv(input)->counters.p_read_packets, 1, NULL);
236 vlc_mutex_unlock(&input_priv(input)->counters.counters_lock);
239 return val;
242 /* Directory */
243 static int AStreamReadDir(stream_t *s, input_item_node_t *p_node)
245 stream_t *access = s->p_sys;
247 return access->pf_readdir(access, p_node);
250 /* Common */
251 static int AStreamSeek(stream_t *s, uint64_t offset)
253 stream_t *access = s->p_sys;
255 return vlc_stream_Seek(access, offset);
258 static int AStreamControl(stream_t *s, int cmd, va_list args)
260 stream_t *access = s->p_sys;
262 return vlc_stream_vaControl(access, cmd, args);
265 static void AStreamDestroy(stream_t *s)
267 stream_t *access = s->p_sys;
269 vlc_stream_Delete(access);
272 stream_t *stream_AccessNew(vlc_object_t *parent, input_thread_t *input,
273 bool preparsing, const char *url)
275 stream_t *s = vlc_stream_CommonNew(parent, AStreamDestroy);
276 if (unlikely(s == NULL))
277 return NULL;
279 stream_t *access = access_New(VLC_OBJECT(s), input, preparsing, url);
280 if (access == NULL)
282 stream_CommonDelete(s);
283 return NULL;
286 s->p_input = input;
287 s->psz_url = strdup(access->psz_url);
289 const char *cachename;
291 if (access->pf_block != NULL)
293 s->pf_block = AStreamReadBlock;
294 cachename = "prefetch,cache_block";
296 else
297 if (access->pf_read != NULL)
299 s->pf_read = AStreamReadStream;
300 cachename = "prefetch,cache_read";
302 else
304 cachename = NULL;
307 if (access->pf_readdir != NULL)
308 s->pf_readdir = AStreamReadDir;
309 else
310 s->pf_readdir = AStreamNoReadDir;
312 s->pf_seek = AStreamSeek;
313 s->pf_control = AStreamControl;
314 s->p_sys = access;
316 if (cachename != NULL)
317 s = stream_FilterChainNew(s, cachename);
318 return stream_FilterAutoNew(s);