From 5824eb7107a612880f68cc8e4f42cfff1bbf88ba Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 27 Feb 2015 19:44:39 +0100 Subject: stream_rar: treat rar files as playlists Refactors an older hack, which for some reason used a more complicated way. This generates the playlist representing the contents of the rar file in demux_playlist.c. The pseudo-demuxer could easily be separate from the the playlist parsers (and in fact there's almost no shared code), but I don't think this obscure feature deserves a separate file. Sample files created with: rar a -v20000k -m0 files.rar file1.mkv file1.mkv --- stream/stream.c | 6 ++-- stream/stream_rar.c | 79 ++++------------------------------------------------- 2 files changed, 8 insertions(+), 77 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index fd545da7e7..4e15f498d9 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -74,8 +74,7 @@ extern const stream_info_t stream_info_dvdnav; extern const stream_info_t stream_info_bdmv_dir; extern const stream_info_t stream_info_bluray; extern const stream_info_t stream_info_bdnav; -extern const stream_info_t stream_info_rar_filter; -extern const stream_info_t stream_info_rar_entry; +extern const stream_info_t stream_info_rar; extern const stream_info_t stream_info_edl; static const stream_info_t *const stream_list[] = { @@ -115,8 +114,7 @@ static const stream_info_t *const stream_list[] = { &stream_info_null, &stream_info_mf, &stream_info_edl, - &stream_info_rar_filter, - &stream_info_rar_entry, + &stream_info_rar, &stream_info_file, NULL }; diff --git a/stream/stream_rar.c b/stream/stream_rar.c index 58e6232092..e795c9cd78 100644 --- a/stream/stream_rar.c +++ b/stream/stream_rar.c @@ -43,11 +43,10 @@ This works as follows: - stream_open() with file01.rar - is opened as normal file (stream_file.c or others) first - - stream_info_rar_filter stream filter applies - - leads to rar_filter_open() + - the rar code in demux_playlist.c detects it - if multi-part, opens file02.rar, file03.rar, etc. as actual streams (recursive opening is prevented with the STREAM_NO_FILTERS flag) - - read accesses return a m3u playlist with entries like: + - it returns a playlist like this to the player: rar://bla01.rar|subfile.mkv (one such entry for each file contained in the rar) - stream_open() with the playlist entry, e.g. rar://bla01.rar|subfile.mkv @@ -143,76 +142,10 @@ static int rar_entry_open(stream_t *stream) return STREAM_OK; } -static int rar_filter_fill_buffer(stream_t *s, char *buffer, int max_len) -{ - struct stream *m = s->priv; - return stream_read_partial(m, buffer, max_len); -} - -static int rar_filter_seek(stream_t *s, int64_t newpos) -{ - struct stream *m = s->priv; - return stream_seek(m, newpos); -} - -static void rar_filter_close(stream_t *s) -{ - struct stream *m = s->priv; - free_stream(m); -} - -static int rar_filter_control(stream_t *s, int cmd, void *arg) -{ - struct stream *m = s->priv; - return stream_control(m, cmd, arg); -} - -static int rar_filter_open(stream_t *stream) -{ - struct stream *rar = stream->source; - if (!rar) - return STREAM_UNSUPPORTED; - - int count; - rar_file_t **files; - if (!rar || RarProbe(rar) || RarParse(rar, &count, &files)) - return STREAM_UNSUPPORTED; - - void *tmp = talloc_new(NULL); - - // Create a playlist containing all entries of the .rar file. The URLs - // link to rar_entry_open(). - char *prefix = mp_url_escape(tmp, stream->url, "~|"); - char *pl = talloc_strdup(tmp, "#EXTM3U\n"); - for (int n = 0; n < count; n++) { - pl = talloc_asprintf_append_buffer(pl, "rar://%s|%s\n", - prefix, files[n]->name); - RarFileDelete(files[n]); - } - talloc_free(files); - - struct stream *m = open_memory_stream(pl, strlen(pl)); - - stream->priv = m; - stream->fill_buffer = rar_filter_fill_buffer; - stream->seek = rar_filter_seek; - stream->seekable = true; - stream->close = rar_filter_close; - stream->control = rar_filter_control; - stream->safe_origin = true; - - talloc_free(tmp); - return STREAM_OK; -} - -const stream_info_t stream_info_rar_entry = { - .name = "rar_entry", +const stream_info_t stream_info_rar = { + .name = "rar", .open = rar_entry_open, .protocols = (const char*const[]){ "rar", NULL }, -}; - -const stream_info_t stream_info_rar_filter = { - .name = "rar_filter", - .open = rar_filter_open, - .stream_filter = true, + .is_safe = true, + .is_network = true, // safe over network }; -- cgit v1.2.3