mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 12:36:41 +08:00 
			
		
		
		
	avformat: add a concat protocol that takes a line break delimited list of resources
Suggested-by: ffmpeg@fb.com Reviewed-by: Nicolas George <george@nsup.org> Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
		| @@ -7,6 +7,7 @@ version <next>: | ||||
| - ADPCM IMA Acorn Replay decoder | ||||
| - Argonaut Games CVG demuxer | ||||
| - Argonaut Games CVG muxer | ||||
| - Concatf protocol | ||||
|  | ||||
|  | ||||
| version 4.4: | ||||
|   | ||||
| @@ -215,6 +215,38 @@ ffplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg | ||||
| Note that you may need to escape the character "|" which is special for | ||||
| many shells. | ||||
|  | ||||
| @section concatf | ||||
|  | ||||
| Physical concatenation protocol using a line break delimited list of | ||||
| resources. | ||||
|  | ||||
| Read and seek from many resources in sequence as if they were | ||||
| a unique resource. | ||||
|  | ||||
| A URL accepted by this protocol has the syntax: | ||||
| @example | ||||
| concatf:@var{URL} | ||||
| @end example | ||||
|  | ||||
| where @var{URL} is the url containing a line break delimited list of | ||||
| resources to be concatenated, each one possibly specifying a distinct | ||||
| protocol. Special characters must be escaped with backslash or single | ||||
| quotes. See @ref{quoting_and_escaping,,the "Quoting and escaping" | ||||
| section in the ffmpeg-utils(1) manual,ffmpeg-utils}. | ||||
|  | ||||
| For example to read a sequence of files @file{split1.mpeg}, | ||||
| @file{split2.mpeg}, @file{split3.mpeg} listed in separate lines within | ||||
| a file @file{split.txt} with @command{ffplay} use the command: | ||||
| @example | ||||
| ffplay concatf:split.txt | ||||
| @end example | ||||
| Where @file{split.txt} contains the lines: | ||||
| @example | ||||
| split1.mpeg | ||||
| split2.mpeg | ||||
| split3.mpeg | ||||
| @end example | ||||
|  | ||||
| @section crypto | ||||
|  | ||||
| AES-encrypted stream reading protocol. | ||||
|   | ||||
| @@ -616,6 +616,7 @@ OBJS-$(CONFIG_APPLEHTTP_PROTOCOL)        += hlsproto.o | ||||
| OBJS-$(CONFIG_BLURAY_PROTOCOL)           += bluray.o | ||||
| OBJS-$(CONFIG_CACHE_PROTOCOL)            += cache.o | ||||
| OBJS-$(CONFIG_CONCAT_PROTOCOL)           += concat.o | ||||
| OBJS-$(CONFIG_CONCATF_PROTOCOL)          += concat.o | ||||
| OBJS-$(CONFIG_CRYPTO_PROTOCOL)           += crypto.o | ||||
| OBJS-$(CONFIG_DATA_PROTOCOL)             += data_uri.o | ||||
| OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL)      += rtmpcrypt.o rtmpdigest.o rtmpdh.o | ||||
|   | ||||
| @@ -22,9 +22,11 @@ | ||||
|  */ | ||||
|  | ||||
| #include "libavutil/avstring.h" | ||||
| #include "libavutil/bprint.h" | ||||
| #include "libavutil/mem.h" | ||||
|  | ||||
| #include "avformat.h" | ||||
| #include "avio_internal.h" | ||||
| #include "url.h" | ||||
|  | ||||
| #define AV_CAT_SEPARATOR "|" | ||||
| @@ -56,6 +58,7 @@ static av_cold int concat_close(URLContext *h) | ||||
|     return err < 0 ? -1 : 0; | ||||
| } | ||||
|  | ||||
| #if CONFIG_CONCAT_PROTOCOL | ||||
| static av_cold int concat_open(URLContext *h, const char *uri, int flags) | ||||
| { | ||||
|     char *node_uri = NULL; | ||||
| @@ -124,6 +127,7 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) | ||||
|     data->total_size = total_size; | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int concat_read(URLContext *h, unsigned char *buf, int size) | ||||
| { | ||||
| @@ -188,6 +192,7 @@ static int64_t concat_seek(URLContext *h, int64_t pos, int whence) | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| #if CONFIG_CONCAT_PROTOCOL | ||||
| const URLProtocol ff_concat_protocol = { | ||||
|     .name           = "concat", | ||||
|     .url_open       = concat_open, | ||||
| @@ -197,3 +202,107 @@ const URLProtocol ff_concat_protocol = { | ||||
|     .priv_data_size = sizeof(struct concat_data), | ||||
|     .default_whitelist = "concat,file,subfile", | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if CONFIG_CONCATF_PROTOCOL | ||||
| static av_cold int concatf_open(URLContext *h, const char *uri, int flags) | ||||
| { | ||||
|     AVBPrint bp; | ||||
|     struct concat_data *data = h->priv_data; | ||||
|     AVIOContext *in = NULL; | ||||
|     const char *cursor; | ||||
|     int64_t total_size = 0; | ||||
|     unsigned int nodes_size = 0; | ||||
|     size_t i = 0; | ||||
|     int err; | ||||
|  | ||||
|     if (!av_strstart(uri, "concatf:", &uri)) { | ||||
|         av_log(h, AV_LOG_ERROR, "URL %s lacks prefix\n", uri); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|  | ||||
|     /* handle input */ | ||||
|     if (!*uri) | ||||
|         return AVERROR(ENOENT); | ||||
|  | ||||
|     err = ffio_open_whitelist(&in, uri, AVIO_FLAG_READ, &h->interrupt_callback, | ||||
|                               NULL, h->protocol_whitelist, h->protocol_blacklist); | ||||
|     if (err < 0) | ||||
|         return err; | ||||
|  | ||||
|     av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); | ||||
|     err = avio_read_to_bprint(in, &bp, SIZE_MAX); | ||||
|     avio_closep(&in); | ||||
|     if (err < 0) { | ||||
|         av_bprint_finalize(&bp, NULL); | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     cursor = bp.str; | ||||
|     while (*cursor) { | ||||
|         struct concat_nodes *nodes; | ||||
|         URLContext *uc; | ||||
|         char *node_uri; | ||||
|         int64_t size; | ||||
|         size_t len = i; | ||||
|  | ||||
|         node_uri = av_get_token(&cursor, "\r\n"); | ||||
|         if (!node_uri) { | ||||
|             err = AVERROR(ENOMEM); | ||||
|             break; | ||||
|         } | ||||
|         cursor++; | ||||
|  | ||||
|         if (++len == SIZE_MAX / sizeof(*nodes)) { | ||||
|             av_free(node_uri); | ||||
|             err = AVERROR(ENAMETOOLONG); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         /* creating URLContext */ | ||||
|         err = ffurl_open_whitelist(&uc, node_uri, flags, | ||||
|                                    &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist, h); | ||||
|         av_free(node_uri); | ||||
|         if (err < 0) | ||||
|             break; | ||||
|  | ||||
|         /* creating size */ | ||||
|         if ((size = ffurl_size(uc)) < 0) { | ||||
|             ffurl_close(uc); | ||||
|             err = AVERROR(ENOSYS); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         nodes = av_fast_realloc(data->nodes, &nodes_size, sizeof(*nodes) * len); | ||||
|         if (!nodes) { | ||||
|             ffurl_close(uc); | ||||
|             err = AVERROR(ENOMEM); | ||||
|             break; | ||||
|         } | ||||
|         data->nodes = nodes; | ||||
|  | ||||
|         /* assembling */ | ||||
|         data->nodes[i].uc   = uc; | ||||
|         data->nodes[i++].size = size; | ||||
|         total_size += size; | ||||
|     } | ||||
|     av_bprint_finalize(&bp, NULL); | ||||
|     data->length = i; | ||||
|  | ||||
|     if (err < 0) | ||||
|         concat_close(h); | ||||
|  | ||||
|     data->total_size = total_size; | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| const URLProtocol ff_concatf_protocol = { | ||||
|     .name           = "concatf", | ||||
|     .url_open       = concatf_open, | ||||
|     .url_read       = concat_read, | ||||
|     .url_seek       = concat_seek, | ||||
|     .url_close      = concat_close, | ||||
|     .priv_data_size = sizeof(struct concat_data), | ||||
|     .default_whitelist = "concatf,concat,file,subfile", | ||||
| }; | ||||
| #endif | ||||
|   | ||||
| @@ -27,6 +27,7 @@ extern const URLProtocol ff_async_protocol; | ||||
| extern const URLProtocol ff_bluray_protocol; | ||||
| extern const URLProtocol ff_cache_protocol; | ||||
| extern const URLProtocol ff_concat_protocol; | ||||
| extern const URLProtocol ff_concatf_protocol; | ||||
| extern const URLProtocol ff_crypto_protocol; | ||||
| extern const URLProtocol ff_data_protocol; | ||||
| extern const URLProtocol ff_ffrtmpcrypt_protocol; | ||||
|   | ||||
| @@ -32,8 +32,8 @@ | ||||
| // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) | ||||
| // Also please add any ticket numbers that you believe might be affected here | ||||
| #define LIBAVFORMAT_VERSION_MAJOR  59 | ||||
| #define LIBAVFORMAT_VERSION_MINOR   3 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 101 | ||||
| #define LIBAVFORMAT_VERSION_MINOR   4 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 100 | ||||
|  | ||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
|                                                LIBAVFORMAT_VERSION_MINOR, \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 James Almer
					James Almer