FFmpeg  2.1.1
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
int size
AVIOInterruptCB interrupt_callback
Definition: url.h:50
#define AVSEEK_SIZE
Passing this as the &quot;whence&quot; parameter to a seek function causes it to return the filesize without se...
Definition: avio.h:222
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
URLContext * inner
Definition: cache.c:51
void av_freep(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:234
int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx)
Wrapper to work around the lack of mkstemp() on mingw.
Definition: file.c:140
miscellaneous OS support macros and functions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:67
URLProtocol ff_cache_protocol
Definition: cache.c:133
int64_t end
Definition: cache.c:49
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: avcodec.h:4147
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:103
const char * arg
Definition: jacosubdec.c:69
static int cache_close(URLContext *h)
Definition: cache.c:124
#define FFMIN(a, b)
Definition: avcodec.h:925
static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
Definition: cache.c:95
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:538
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
const char * name
Definition: url.h:55
static int flags
Definition: cpu.c:45
int ffurl_close(URLContext *h)
Definition: avio.c:368
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
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:337
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:256
static double c[64]
Main libavformat public API header.
#define AVERROR(e)
unbuffered private I/O API
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:312