Statistics
| Branch: | Revision:

ffmpeg / libavformat / avio.c @ 25f8db58

History | View | Annotate | Download (4.54 KB)

1 de6d9b64 Fabrice Bellard
/*
2
 * Unbuffered io for ffmpeg system
3 19720f15 Fabrice Bellard
 * Copyright (c) 2001 Fabrice Bellard
4 de6d9b64 Fabrice Bellard
 *
5 19720f15 Fabrice Bellard
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9 de6d9b64 Fabrice Bellard
 *
10 19720f15 Fabrice Bellard
 * This library is distributed in the hope that it will be useful,
11 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 19720f15 Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14 de6d9b64 Fabrice Bellard
 *
15 19720f15 Fabrice Bellard
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 de6d9b64 Fabrice Bellard
 */
19
#include "avformat.h"
20
21 019ac05a Fabrice Bellard
static int default_interrupt_cb(void);
22
23 de6d9b64 Fabrice Bellard
URLProtocol *first_protocol = NULL;
24 019ac05a Fabrice Bellard
URLInterruptCB *url_interrupt_cb = default_interrupt_cb;
25 de6d9b64 Fabrice Bellard
26
int register_protocol(URLProtocol *protocol)
27
{
28
    URLProtocol **p;
29
    p = &first_protocol;
30
    while (*p != NULL) p = &(*p)->next;
31
    *p = protocol;
32
    protocol->next = NULL;
33
    return 0;
34
}
35
36
int url_open(URLContext **puc, const char *filename, int flags)
37
{
38
    URLContext *uc;
39
    URLProtocol *up;
40
    const char *p;
41
    char proto_str[128], *q;
42
    int err;
43
44
    p = filename;
45
    q = proto_str;
46
    while (*p != '\0' && *p != ':') {
47 5d5fef0a Fabrice Bellard
        /* protocols can only contain alphabetic chars */
48
        if (!isalpha(*p))
49
            goto file_proto;
50 de6d9b64 Fabrice Bellard
        if ((q - proto_str) < sizeof(proto_str) - 1)
51
            *q++ = *p;
52
        p++;
53
    }
54 a74127c0 Fabrice Bellard
    /* if the protocol has length 1, we consider it is a dos drive */
55
    if (*p == '\0' || (q - proto_str) <= 1) {
56 5d5fef0a Fabrice Bellard
    file_proto:
57 de6d9b64 Fabrice Bellard
        strcpy(proto_str, "file");
58
    } else {
59
        *q = '\0';
60
    }
61
    
62
    up = first_protocol;
63
    while (up != NULL) {
64 a74127c0 Fabrice Bellard
        if (!strcmp(proto_str, up->name))
65 de6d9b64 Fabrice Bellard
            goto found;
66
        up = up->next;
67
    }
68 8a9488b5 Fabrice Bellard
    err = -ENOENT;
69
    goto fail;
70 de6d9b64 Fabrice Bellard
 found:
71 f746a046 Fabrice Bellard
    uc = av_malloc(sizeof(URLContext) + strlen(filename));
72 8a9488b5 Fabrice Bellard
    if (!uc) {
73
        err = -ENOMEM;
74
        goto fail;
75
    }
76 f746a046 Fabrice Bellard
    strcpy(uc->filename, filename);
77 de6d9b64 Fabrice Bellard
    uc->prot = up;
78
    uc->flags = flags;
79
    uc->is_streamed = 0; /* default = not streamed */
80 8a9488b5 Fabrice Bellard
    uc->max_packet_size = 0; /* default: stream file */
81 de6d9b64 Fabrice Bellard
    err = up->url_open(uc, filename, flags);
82
    if (err < 0) {
83 1ea4f593 Fabrice Bellard
        av_free(uc);
84 de6d9b64 Fabrice Bellard
        *puc = NULL;
85
        return err;
86
    }
87
    *puc = uc;
88
    return 0;
89 8a9488b5 Fabrice Bellard
 fail:
90
    *puc = NULL;
91
    return err;
92 de6d9b64 Fabrice Bellard
}
93
94
int url_read(URLContext *h, unsigned char *buf, int size)
95
{
96
    int ret;
97
    if (h->flags & URL_WRONLY)
98 0bd586c5 Mike Melanson
        return AVERROR_IO;
99 de6d9b64 Fabrice Bellard
    ret = h->prot->url_read(h, buf, size);
100
    return ret;
101
}
102
103 a9e35095 Diego Biurrun
#ifdef CONFIG_MUXERS
104 de6d9b64 Fabrice Bellard
int url_write(URLContext *h, unsigned char *buf, int size)
105
{
106
    int ret;
107 8a9488b5 Fabrice Bellard
    if (!(h->flags & (URL_WRONLY | URL_RDWR)))
108 0bd586c5 Mike Melanson
        return AVERROR_IO;
109 8a9488b5 Fabrice Bellard
    /* avoid sending too big packets */
110
    if (h->max_packet_size && size > h->max_packet_size)
111 0bd586c5 Mike Melanson
        return AVERROR_IO; 
112 de6d9b64 Fabrice Bellard
    ret = h->prot->url_write(h, buf, size);
113
    return ret;
114
}
115 a9e35095 Diego Biurrun
#endif //CONFIG_MUXERS
116 de6d9b64 Fabrice Bellard
117
offset_t url_seek(URLContext *h, offset_t pos, int whence)
118
{
119
    offset_t ret;
120
121
    if (!h->prot->url_seek)
122
        return -EPIPE;
123
    ret = h->prot->url_seek(h, pos, whence);
124
    return ret;
125
}
126
127
int url_close(URLContext *h)
128
{
129
    int ret;
130
131
    ret = h->prot->url_close(h);
132 1ea4f593 Fabrice Bellard
    av_free(h);
133 de6d9b64 Fabrice Bellard
    return ret;
134
}
135
136
int url_exist(const char *filename)
137
{
138
    URLContext *h;
139
    if (url_open(&h, filename, URL_RDONLY) < 0)
140
        return 0;
141
    url_close(h);
142
    return 1;
143
}
144
145
offset_t url_filesize(URLContext *h)
146
{
147
    offset_t pos, size;
148
    
149
    pos = url_seek(h, 0, SEEK_CUR);
150 31290c2b Michael Niedermayer
    size = url_seek(h, -1, SEEK_END)+1;
151 de6d9b64 Fabrice Bellard
    url_seek(h, pos, SEEK_SET);
152
    return size;
153
}
154 8a9488b5 Fabrice Bellard
155
/* 
156
 * Return the maximum packet size associated to packetized file
157
 * handle. If the file is not packetized (stream like http or file on
158
 * disk), then 0 is returned.
159
 * 
160
 * @param h file handle
161
 * @return maximum packet size in bytes
162
 */
163
int url_get_max_packet_size(URLContext *h)
164
{
165
    return h->max_packet_size;
166
}
167 f746a046 Fabrice Bellard
168
void url_get_filename(URLContext *h, char *buf, int buf_size)
169
{
170
    pstrcpy(buf, buf_size, h->filename);
171
}
172 019ac05a Fabrice Bellard
173
174
static int default_interrupt_cb(void)
175
{
176
    return 0;
177
}
178
179
/** 
180
 * The callback is called in blocking functions to test regulary if
181
 * asynchronous interruption is needed. -EINTR is returned in this
182
 * case by the interrupted function. 'NULL' means no interrupt
183
 * callback is given.  
184
 */
185
void url_set_interrupt_cb(URLInterruptCB *interrupt_cb)
186
{
187
    if (!interrupt_cb)
188
        interrupt_cb = default_interrupt_cb;
189
    url_interrupt_cb = interrupt_cb;
190
}