FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
cache.c
Go to the documentation of this file.
1
/*
2
* Input cache protocol.
3
* Copyright (c) 2011 Michael Niedermayer
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
* Based on file.c by Fabrice Bellard
22
*/
23
24
/**
25
* @TODO
26
* support non continuous caching
27
* support keeping files
28
* support filling with a background thread
29
*/
30
31
#include "
libavutil/avassert.h
"
32
#include "
libavutil/avstring.h
"
33
#include "
libavutil/file.h
"
34
#include "
avformat.h
"
35
#include <fcntl.h>
36
#if HAVE_IO_H
37
#include <io.h>
38
#endif
39
#if HAVE_UNISTD_H
40
#include <unistd.h>
41
#endif
42
#include <sys/stat.h>
43
#include <stdlib.h>
44
#include "
os_support.h
"
45
#include "
url.h
"
46
47
typedef
struct
Context
{
48
int
fd
;
49
int64_t
end
;
50
int64_t
pos
;
51
URLContext
*
inner
;
52
}
Context
;
53
54
static
int
cache_open
(
URLContext
*h,
const
char
*
arg
,
int
flags
)
55
{
56
char
*buffername;
57
Context
*
c
= h->
priv_data
;
58
59
av_strstart
(arg,
"cache:"
, &arg);
60
61
c->
fd
=
av_tempfile
(
"ffcache"
, &buffername, 0, h);
62
if
(c->
fd
< 0){
63
av_log
(h,
AV_LOG_ERROR
,
"Failed to create tempfile\n"
);
64
return
c->
fd
;
65
}
66
67
unlink(buffername);
68
av_freep
(&buffername);
69
70
return
ffurl_open
(&c->
inner
, arg, flags, &h->
interrupt_callback
, NULL);
71
}
72
73
static
int
cache_read
(
URLContext
*h,
unsigned
char
*
buf
,
int
size
)
74
{
75
Context
*
c
= h->
priv_data
;
76
int
r
;
77
78
if
(c->
pos
<c->
end
){
79
r = read(c->
fd
, buf,
FFMIN
(size, c->
end
- c->
pos
));
80
if
(r>0)
81
c->
pos
+=
r
;
82
return
(-1 == r)?
AVERROR
(errno):
r
;
83
}
else
{
84
r =
ffurl_read
(c->
inner
, buf, size);
85
if
(r > 0){
86
int
r2= write(c->
fd
, buf, r);
87
av_assert0
(r2==r);
// FIXME handle cache failure
88
c->
pos
+=
r
;
89
c->
end
+=
r
;
90
}
91
return
r
;
92
}
93
}
94
95
static
int64_t
cache_seek
(
URLContext
*h, int64_t pos,
int
whence)
96
{
97
Context
*
c
= h->
priv_data
;
98
99
if
(whence ==
AVSEEK_SIZE
) {
100
pos=
ffurl_seek
(c->
inner
, pos, whence);
101
if
(pos <= 0){
102
pos=
ffurl_seek
(c->
inner
, -1, SEEK_END);
103
ffurl_seek
(c->
inner
, c->
end
, SEEK_SET);
104
if
(pos <= 0)
105
return
c->
end
;
106
}
107
return
pos;
108
}
109
110
pos= lseek(c->
fd
, pos, whence);
111
if
(pos<0){
112
return
pos;
113
}
else
if
(pos <= c->
end
){
114
c->
pos
= pos;
115
return
pos;
116
}
else
{
117
if
(lseek(c->
fd
, c->
pos
, SEEK_SET) < 0) {
118
av_log
(h,
AV_LOG_ERROR
,
"Failure to seek in cache\n"
);
119
}
120
return
AVERROR
(EPIPE);
121
}
122
}
123
124
static
int
cache_close
(
URLContext
*h)
125
{
126
Context
*
c
= h->
priv_data
;
127
close
(c->
fd
);
128
ffurl_close
(c->
inner
);
129
130
return
0;
131
}
132
133
URLProtocol
ff_cache_protocol
= {
134
.
name
=
"cache"
,
135
.url_open =
cache_open
,
136
.url_read =
cache_read
,
137
.url_seek =
cache_seek
,
138
.url_close =
cache_close
,
139
.priv_data_size =
sizeof
(
Context
),
140
};
Generated on Sat Jan 25 2014 19:52:02 for FFmpeg by
1.8.2