--- this was created to test the idea proposed in https://trac.ffmpeg.org/ticket/4374 as result, i think a zip:// protocol has some problems
- strict uri syntax can only open files in current directory - user shouldn't have to specify the archive format. this should be autodetected (zip, rar, ... arj) - want ability to grab zip files over other protocols 'vfs:http://subtitles.org/amovie.zip:amovie.srt' - default action to open the first inner file? configure | 4 +++ libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/libzip.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 libavformat/libzip.c diff --git a/configure b/configure index a96bfb7..102361b 100755 --- a/configure +++ b/configure @@ -240,6 +240,7 @@ External library support: --enable-libsoxr enable Include libsoxr resampling [no] --enable-libspeex enable Speex de/encoding via libspeex [no] --enable-libssh enable SFTP protocol via libssh [no] + --enable-libzip enable zip protocol via libzip [no] --enable-libstagefright-h264 enable H.264 decoding via libstagefright [no] --enable-libtheora enable Theora encoding via libtheora [no] --enable-libtwolame enable MP2 encoding via libtwolame [no] @@ -1404,6 +1405,7 @@ EXTERNAL_LIBRARY_LIST=" libxcb_shape libxcb_xfixes libxvid + libzip libzmq libzvbi lzma @@ -2561,6 +2563,7 @@ librtmpt_protocol_deps="librtmp" librtmpte_protocol_deps="librtmp" libsmbclient_protocol_deps="libsmbclient gplv3" libssh_protocol_deps="libssh" +libzip_protocol_deps="libzip" mmsh_protocol_select="http_protocol" mmst_protocol_select="network" rtmp_protocol_deps="!librtmp_protocol" @@ -4996,6 +4999,7 @@ enabled libx265 && require_pkg_config x265 x265.h x265_encoder_encode die "ERROR: libx265 version must be >= 17."; } enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore +enabled libzip && require_pkg_config libzip zip.h zip_open enabled libzmq && require_pkg_config libzmq zmq.h zmq_ctx_new enabled libzvbi && require libzvbi libzvbi.h vbi_decoder_new -lzvbi enabled nvenc && { check_header nvEncodeAPI.h || die "ERROR: nvEncodeAPI.h not found."; } && diff --git a/libavformat/Makefile b/libavformat/Makefile index 2118ff2..325628c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -485,6 +485,7 @@ OBJS-$(CONFIG_LIBQUVI_DEMUXER) += libquvi.o OBJS-$(CONFIG_LIBRTMP) += librtmp.o OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o +OBJS-$(CONFIG_LIBZIP_PROTOCOL) += libzip.o # protocols I/O OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 26ccc27..93cd2e8 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -392,4 +392,5 @@ void av_register_all(void) REGISTER_PROTOCOL(LIBRTMPTE, librtmpte); REGISTER_PROTOCOL(LIBSSH, libssh); REGISTER_PROTOCOL(LIBSMBCLIENT, libsmbclient); + REGISTER_PROTOCOL(LIBZIP, libzip); } diff --git a/libavformat/libzip.c b/libavformat/libzip.c new file mode 100644 index 0000000..e6cfb50 --- /dev/null +++ b/libavformat/libzip.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Peter Ross <pr...@xvid.org> + * + * 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 <zip.h> +#include "avformat.h" +#include "internal.h" +#include "url.h" + +//FIXME: url syntax cannot distinguish 'real zip file path' from 'virtual file path' +// OK: zip://tarball.zip/lol.gif +// BROKEN: zip:///tmp/tarball.zip/lol.gif + +typedef struct { + const AVClass *class; + struct zip *zip; + struct zip_file *file; +} ZipContext; + +static av_cold int libzip_open(URLContext *h, const char *url, int flags) +{ + ZipContext *libzip = h->priv_data; + char proto[10], password[1024], hostname[1024], path[MAX_URL_SIZE], *p; + int error; + + av_url_split(proto, sizeof(proto), + password, sizeof(password), + hostname, sizeof(hostname), + NULL, + path, sizeof(path), + url); + + libzip->zip = zip_open(hostname, 0, &error); + if (!libzip->zip) { + char buf[1024]; + zip_error_to_str(buf, sizeof(buf), error, errno); + av_log(h, AV_LOG_ERROR, "zip_open: %s\n", buf); + return AVERROR(EIO); + } + + zip_set_default_password(libzip->zip, password); + + for (p = path; *p == '/'; p++) ; + libzip->file = zip_fopen(libzip->zip, p, 0); + if (!libzip->file) { + av_log(h, AV_LOG_ERROR, "zip_fopen: %s\n", zip_strerror(libzip->zip)); + zip_close(libzip->zip); + return AVERROR(EIO); + } + + return 0; +} + +static av_cold int libzip_close(URLContext *h) +{ + ZipContext *libzip = h->priv_data; + zip_fclose(libzip->file); + zip_close(libzip->zip); + return 0; +} + +static int libzip_read(URLContext *h, unsigned char *buf, int size) +{ + ZipContext *libzip = h->priv_data; + int bytes_read = zip_fread(libzip->file, buf, size); + return bytes_read < 0 ? AVERROR(EIO) : bytes_read; +} + +URLProtocol ff_libzip_protocol = { + .name = "zip", + .url_open = libzip_open, + .url_read = libzip_read, + .url_close = libzip_close, + .priv_data_size = sizeof(ZipContext), +}; -- 2.1.0 -- Peter (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel