libavutil/file.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "config.h"
20 #include "file.h"
21 #include "log.h"
22 #include "mem.h"
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #if HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28 #if HAVE_IO_H
29 #include <io.h>
30 #endif
31 #if HAVE_MMAP
32 #include <sys/mman.h>
33 #elif HAVE_MAPVIEWOFFILE
34 #include <windows.h>
35 #endif
36 
37 typedef struct {
38  const AVClass *class;
40  void *log_ctx;
42 
43 static const AVClass file_log_ctx_class = {
45  offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
46 };
47 
48 int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
49  int log_offset, void *log_ctx)
50 {
51  FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
52  int err, fd = open(filename, O_RDONLY);
53  struct stat st;
54  av_unused void *ptr;
55  off_t off_size;
56  char errbuf[128];
57  *bufptr = NULL;
58 
59  if (fd < 0) {
60  err = AVERROR(errno);
61  av_strerror(err, errbuf, sizeof(errbuf));
62  av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf);
63  return err;
64  }
65 
66  if (fstat(fd, &st) < 0) {
67  err = AVERROR(errno);
68  av_strerror(err, errbuf, sizeof(errbuf));
69  av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in fstat(): %s\n", errbuf);
70  close(fd);
71  return err;
72  }
73 
74  off_size = st.st_size;
75  if (off_size > SIZE_MAX) {
76  av_log(&file_log_ctx, AV_LOG_ERROR,
77  "File size for file '%s' is too big\n", filename);
78  close(fd);
79  return AVERROR(EINVAL);
80  }
81  *size = off_size;
82 
83 #if HAVE_MMAP
84  ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
85  if (ptr == MAP_FAILED) {
86  err = AVERROR(errno);
87  av_strerror(err, errbuf, sizeof(errbuf));
88  av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf);
89  close(fd);
90  return err;
91  }
92  *bufptr = ptr;
93 #elif HAVE_MAPVIEWOFFILE
94  {
95  HANDLE mh, fh = (HANDLE)_get_osfhandle(fd);
96 
97  mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
98  if (!mh) {
99  av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in CreateFileMapping()\n");
100  close(fd);
101  return -1;
102  }
103 
104  ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size);
105  CloseHandle(mh);
106  if (!ptr) {
107  av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile()\n");
108  close(fd);
109  return -1;
110  }
111 
112  *bufptr = ptr;
113  }
114 #else
115  *bufptr = av_malloc(*size);
116  if (!*bufptr) {
117  av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n");
118  close(fd);
119  return AVERROR(ENOMEM);
120  }
121  read(fd, *bufptr, *size);
122 #endif
123 
124  close(fd);
125  return 0;
126 }
127 
128 void av_file_unmap(uint8_t *bufptr, size_t size)
129 {
130 #if HAVE_MMAP
131  munmap(bufptr, size);
132 #elif HAVE_MAPVIEWOFFILE
133  UnmapViewOfFile(bufptr);
134 #else
135  av_free(bufptr);
136 #endif
137 }
138 
139 int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) {
140  FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
141  int fd=-1;
142 #if !HAVE_MKSTEMP
143  void *ptr= tempnam(NULL, prefix);
144  if(!ptr)
145  ptr= tempnam(".", prefix);
146  *filename = av_strdup(ptr);
147 #undef free
148  free(ptr);
149 #else
150  size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
151  *filename = av_malloc(len);
152 #endif
153  /* -----common section-----*/
154  if (*filename == NULL) {
155  av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
156  return AVERROR(ENOMEM);
157  }
158 #if !HAVE_MKSTEMP
159 # ifndef O_BINARY
160 # define O_BINARY 0
161 # endif
162 # ifndef O_EXCL
163 # define O_EXCL 0
164 # endif
165  fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
166 #else
167  snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
168  fd = mkstemp(*filename);
169 #ifdef _WIN32
170  if (fd < 0) {
171  snprintf(*filename, len, "./%sXXXXXX", prefix);
172  fd = mkstemp(*filename);
173  }
174 #endif
175 #endif
176  /* -----common section-----*/
177  if (fd < 0) {
178  int err = AVERROR(errno);
179  av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
180  av_freep(filename);
181  return err;
182  }
183  return fd; /* success */
184 }
185 
186 #ifdef TEST
187 
188 #undef printf
189 
190 int main(void)
191 {
192  uint8_t *buf;
193  size_t size;
194  if (av_file_map("file.c", &buf, &size, 0, NULL) < 0)
195  return 1;
196 
197  buf[0] = 's';
198  printf("%s", buf);
199  av_file_unmap(buf, size);
200  return 0;
201 }
202 #endif
203 
av_default_item_name
memory handling functions
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
uint8_t
Misc file utilities.
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int size
PVOID HANDLE
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
#define O_BINARY
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
char * av_strdup(const char *s)
Duplicate the string s.
Definition: mem.c:220
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
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
#define snprintf
Definition: snprintf.h:34
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
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:53
static const AVClass file_log_ctx_class
#define O_EXCL
int len
printf("static const uint8_t my_array[100] = {\n")
int main(int argc, char **argv)
Definition: main.c:22
#define av_unused
Definition: attributes.h:114
#define mh
MUSIC TECHNOLOGY GROUP UNIVERSITAT POMPEU FABRA Free Non Commercial Binary License Agreement UNIVERSITAT POMPEU OR INDICATING ACCEPTANCE BY SELECTING THE ACCEPT BUTTON ON ANY DOWNLOAD OR INSTALL YOU ACCEPT THE TERMS OF THE LICENSE SUMMARY TABLE Software MELODIA Melody Extraction vamp plug in Licensor Music Technology Group Universitat Pompeu Plaça de la Spain Permitted purposes Non commercial internal research and validation and educational purposes only All commercial uses in a production either internal or are prohibited by this license and require an additional commercial exploitation license TERMS AND CONDITIONS SOFTWARE Software means the software programs identified herein in binary any other machine readable any updates or error corrections provided by and any user programming guides and other documentation provided to you by UPF under this Agreement LICENSE Subject to the terms and conditions of this UPF grants you a royalty free