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;
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 
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 };
support non continuous caching support keeping files support filling with a background thread ...
Definition: cache.c:47
AVIOInterruptCB interrupt_callback
Definition: url.h:50
URLContext * inner
Definition: cache.c:51
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
miscellaneous OS support macros and functions.
URLProtocol ff_cache_protocol
Definition: cache.c:133
int64_t end
Definition: cache.c:49
Misc file utilities.
struct Context Context
support non continuous caching support keeping files support filling with a background thread ...
static int cache_open(URLContext *h, const char *arg, int flags)
Definition: cache.c:54
int fd
Definition: cache.c:48
const char * r
Definition: vf_curves.c:94
const char * arg
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int size
static int cache_close(URLContext *h)
Definition: cache.c:124
#define FFMIN(a, b)
Definition: common.h:58
static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
Definition: cache.c:95
int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx)
Wrapper to work around the lack of mkstemp() on mingw.
NULL
Definition: eval.c:55
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
Definition: url.h:41
static int cache_read(URLContext *h, unsigned char *buf, int size)
Definition: cache.c:73
void * priv_data
Definition: url.h:44
int64_t pos
Definition: cache.c:50
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
const char * name
Definition: url.h:55
static int flags
Definition: cpu.c:23
int ffurl_close(URLContext *h)
Definition: avio.c:359
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:33
Main libavformat public API header.
int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
Change the position that will be used by the next read/write operation on the resource accessed by h...
Definition: avio.c:328
int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
Definition: avio.c:247
static double c[64]
#define AVSEEK_SIZE
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
Definition: avio.h:222
unbuffered private I/O API
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...
Definition: avio.c:303