mirror of https://github.com/FFmpeg/FFmpeg.git
Originally committed as revision 26073 to svn://svn.ffmpeg.org/ffmpeg/trunkoldabi
parent
1ce9d6b85f
commit
0328b9ea39
7 changed files with 184 additions and 1 deletions
@ -0,0 +1,123 @@ |
||||
/*
|
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include "file.h" |
||||
#include <fcntl.h> |
||||
#include <sys/stat.h> |
||||
#include <unistd.h> |
||||
#if HAVE_MMAP |
||||
#include <sys/mman.h> |
||||
#endif |
||||
|
||||
typedef struct { |
||||
const AVClass *class; |
||||
int log_offset; |
||||
void *log_ctx; |
||||
} FileLogContext; |
||||
|
||||
static const AVClass file_log_ctx_class = { |
||||
"FILE", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, |
||||
offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx) |
||||
}; |
||||
|
||||
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, |
||||
int log_offset, void *log_ctx) |
||||
{ |
||||
FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx }; |
||||
int err, fd = open(filename, O_RDONLY); |
||||
struct stat st; |
||||
av_unused void *ptr; |
||||
off_t off_size; |
||||
char errbuf[128]; |
||||
size_t max_size = HAVE_MMAP ? SIZE_MAX : FF_INTERNAL_MEM_TYPE_MAX_VALUE; |
||||
*bufptr = NULL; |
||||
|
||||
if (fd < 0) { |
||||
err = AVERROR(errno); |
||||
av_strerror(err, errbuf, sizeof(errbuf)); |
||||
av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf); |
||||
return err; |
||||
} |
||||
|
||||
if (lstat(filename, &st) < 0) { |
||||
err = AVERROR(errno); |
||||
av_strerror(err, errbuf, sizeof(errbuf)); |
||||
av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in lstat(): %s\n", errbuf); |
||||
close(fd); |
||||
return err; |
||||
} |
||||
|
||||
off_size = st.st_size; |
||||
if (off_size > max_size) { |
||||
av_log(&file_log_ctx, AV_LOG_ERROR, |
||||
"File size for file '%s' is too big\n", filename); |
||||
close(fd); |
||||
return AVERROR(EINVAL); |
||||
} |
||||
*size = off_size; |
||||
|
||||
#if HAVE_MMAP |
||||
ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); |
||||
if ((int)(ptr) == -1) { |
||||
err = AVERROR(errno); |
||||
av_strerror(err, errbuf, sizeof(errbuf)); |
||||
av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf); |
||||
close(fd); |
||||
return err; |
||||
} |
||||
*bufptr = ptr; |
||||
#else |
||||
*bufptr = av_malloc(*size); |
||||
if (!*bufptr) { |
||||
av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n"); |
||||
close(fd); |
||||
return AVERROR(ENOMEM); |
||||
} |
||||
read(fd, *bufptr, *size); |
||||
#endif |
||||
|
||||
close(fd); |
||||
return 0; |
||||
} |
||||
|
||||
void av_file_unmap(uint8_t *bufptr, size_t size) |
||||
{ |
||||
#if HAVE_MMAP |
||||
munmap(bufptr, size); |
||||
#else |
||||
av_free(bufptr); |
||||
#endif |
||||
} |
||||
|
||||
#ifdef TEST |
||||
|
||||
#undef printf |
||||
|
||||
int main(void) |
||||
{ |
||||
uint8_t *buf; |
||||
size_t size; |
||||
if (av_file_map("file.c", &buf, &size, 0, NULL) < 0) |
||||
return 1; |
||||
|
||||
buf[0] = 's'; |
||||
printf("%s", buf); |
||||
av_file_unmap(buf, size); |
||||
return 0; |
||||
} |
||||
#endif |
@ -0,0 +1,51 @@ |
||||
/*
|
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef AVUTIL_FILE_H |
||||
#define AVUTIL_FILE_H |
||||
|
||||
#include "avutil.h" |
||||
|
||||
/**
|
||||
* @file misc file utilities |
||||
*/ |
||||
|
||||
/**
|
||||
* Read the file with name filename, and put its content in a newly |
||||
* allocated buffer or map it with mmap() when available. |
||||
* In case of success set *bufptr to the read or mmapped buffer, and |
||||
* *size to the size in bytes of the buffer in *bufptr. |
||||
* The returned buffer must be released with av_file_unmap(). |
||||
* |
||||
* @param log_offset loglevel offset used for logging |
||||
* @param log_ctx context used for logging |
||||
* @return a non negative number in case of success, a negative value |
||||
* corresponding to an AVERROR error code in case of failure |
||||
*/ |
||||
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, |
||||
int log_offset, void *log_ctx); |
||||
|
||||
/**
|
||||
* Unmap or free the buffer bufptr created by av_file_map(). |
||||
* |
||||
* @param size size in bytes of bufptr, must be the same as returned |
||||
* by av_file_map() |
||||
*/ |
||||
void av_file_unmap(uint8_t *bufptr, size_t size); |
||||
|
||||
#endif /* AVUTIL_FILE_H */ |
Loading…
Reference in new issue