Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * buffered file I/O
3
 * Copyright (c) 2001 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
 
22
#include "libavutil/avstring.h"
23
#include "libavutil/internal.h"
24
#include "libavutil/opt.h"
25
#include "avformat.h"
26
#include 
27
//#if HAVE_IO_H
28
//#include 
29
//#endif
30
#if HAVE_UNISTD_H
31
#include 
32
#endif
33
#include 
34
#include 
35
#include "os_support.h"
36
#include "url.h"
37
 
38
/* Some systems may not have S_ISFIFO */
39
#ifndef S_ISFIFO
40
#  ifdef S_IFIFO
41
#    define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
42
#  else
43
#    define S_ISFIFO(m) 0
44
#  endif
45
#endif
46
 
47
/* standard file protocol */
48
 
49
typedef struct FileContext {
50
    const AVClass *class;
51
    int fd;
52
    int trunc;
53
    int blocksize;
54
} FileContext;
55
 
56
static const AVOption file_options[] = {
57
    { "truncate", "Truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
58
    { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
59
    { NULL }
60
};
61
 
62
static const AVOption pipe_options[] = {
63
    { "blocksize", "set I/O operation maximum block size", offsetof(FileContext, blocksize), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
64
    { NULL }
65
};
66
 
67
static const AVClass file_class = {
68
    .class_name = "file",
69
    .item_name  = av_default_item_name,
70
    .option     = file_options,
71
    .version    = LIBAVUTIL_VERSION_INT,
72
};
73
 
74
static const AVClass pipe_class = {
75
    .class_name = "pipe",
76
    .item_name  = av_default_item_name,
77
    .option     = pipe_options,
78
    .version    = LIBAVUTIL_VERSION_INT,
79
};
80
 
81
static int file_read(URLContext *h, unsigned char *buf, int size)
82
{
83
    FileContext *c = h->priv_data;
84
    int r;
85
    size = FFMIN(size, c->blocksize);
86
    r = read(c->fd, buf, size);
87
    return (-1 == r)?AVERROR(errno):r;
88
}
89
 
90
static int file_write(URLContext *h, const unsigned char *buf, int size)
91
{
92
    FileContext *c = h->priv_data;
93
    int r;
94
    size = FFMIN(size, c->blocksize);
95
    r = write(c->fd, buf, size);
96
    return (-1 == r)?AVERROR(errno):r;
97
}
98
 
99
static int file_get_handle(URLContext *h)
100
{
101
    FileContext *c = h->priv_data;
102
    return c->fd;
103
}
104
 
105
static int file_check(URLContext *h, int mask)
106
{
107
 
108
 
109
    return AVIO_FLAG_READ | AVIO_FLAG_WRITE ;
110
}
111
 
112
#if CONFIG_FILE_PROTOCOL
113
 
114
static int file_open(URLContext *h, const char *filename, int flags)
115
{
116
    FileContext *c = h->priv_data;
117
    int access;
118
    int fd;
119
    struct stat st;
120
 
121
    av_strstart(filename, "file:", &filename);
122
 
123
    if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) {
124
        access = O_CREAT | O_RDWR;
125
        if (c->trunc)
126
            access |= O_TRUNC;
127
    } else if (flags & AVIO_FLAG_WRITE) {
128
        access = O_CREAT | O_WRONLY;
129
        if (c->trunc)
130
            access |= O_TRUNC;
131
    } else {
132
        access = O_RDONLY;
133
    }
134
#ifdef O_BINARY
135
    access |= O_BINARY;
136
#endif
137
    fd = avpriv_open(filename, access, 0666);
138
    if (fd == -1)
139
        return AVERROR(errno);
140
    c->fd = fd;
141
 
142
    h->is_streamed = !fstat(fd, &st) && S_ISFIFO(st.st_mode);
143
 
144
    return 0;
145
}
146
 
147
/* XXX: use llseek */
148
static int64_t file_seek(URLContext *h, int64_t pos, int whence)
149
{
150
    FileContext *c = h->priv_data;
151
    int64_t ret;
152
 
153
    if (whence == AVSEEK_SIZE) {
154
        struct stat st;
155
        ret = fstat(c->fd, &st);
156
        return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size);
157
    }
158
 
159
    ret = lseek(c->fd, pos, whence);
160
 
161
    return ret < 0 ? AVERROR(errno) : ret;
162
}
163
 
164
static int file_close(URLContext *h)
165
{
166
    FileContext *c = h->priv_data;
167
    return close(c->fd);
168
}
169
 
170
URLProtocol ff_file_protocol = {
171
    .name                = "file",
172
    .url_open            = file_open,
173
    .url_read            = file_read,
174
    .url_write           = file_write,
175
    .url_seek            = file_seek,
176
    .url_close           = file_close,
177
    .url_get_file_handle = file_get_handle,
178
    .url_check           = file_check,
179
    .priv_data_size      = sizeof(FileContext),
180
    .priv_data_class     = &file_class,
181
};
182
 
183
#endif /* CONFIG_FILE_PROTOCOL */
184
 
185
#if CONFIG_PIPE_PROTOCOL
186
 
187
static int pipe_open(URLContext *h, const char *filename, int flags)
188
{
189
    FileContext *c = h->priv_data;
190
    int fd;
191
    char *final;
192
    av_strstart(filename, "pipe:", &filename);
193
 
194
    fd = strtol(filename, &final, 10);
195
    if((filename == final) || *final ) {/* No digits found, or something like 10ab */
196
        if (flags & AVIO_FLAG_WRITE) {
197
            fd = 1;
198
        } else {
199
            fd = 0;
200
        }
201
    }
202
#if HAVE_SETMODE
203
    setmode(fd, O_BINARY);
204
#endif
205
    c->fd = fd;
206
    h->is_streamed = 1;
207
    return 0;
208
}
209
 
210
URLProtocol ff_pipe_protocol = {
211
    .name                = "pipe",
212
    .url_open            = pipe_open,
213
    .url_read            = file_read,
214
    .url_write           = file_write,
215
    .url_get_file_handle = file_get_handle,
216
    .url_check           = file_check,
217
    .priv_data_size      = sizeof(FileContext),
218
    .priv_data_class     = &pipe_class,
219
};
220
 
221
#endif /* CONFIG_PIPE_PROTOCOL */