mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-27 02:41:54 +08:00 
			
		
		
		
	avformat: Add tee protocol
Option passing support will be submitted seperately to the ML Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
		| @@ -3,6 +3,7 @@ releases are sorted from youngest to oldest. | ||||
|  | ||||
| version <next>: | ||||
| - libopenmpt demuxer | ||||
| - tee protocol | ||||
|  | ||||
|  | ||||
| version 3.1: | ||||
|   | ||||
| @@ -1159,6 +1159,15 @@ Play an AVI file directly from a TAR archive: | ||||
| subfile,,start,183241728,end,366490624,,:archive.tar | ||||
| @end example | ||||
|  | ||||
| @section tee | ||||
|  | ||||
| Writes the output to multiple protocols. The individual outputs are seperated | ||||
| by | | ||||
|  | ||||
| @example | ||||
| tee:file://path/to/local/this.avi|file://path/to/local/that.avi | ||||
| @end example | ||||
|  | ||||
| @section tcp | ||||
|  | ||||
| Transmission Control Protocol. | ||||
|   | ||||
| @@ -564,6 +564,7 @@ OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o | ||||
| OBJS-$(CONFIG_SCTP_PROTOCOL)             += sctp.o | ||||
| OBJS-$(CONFIG_SRTP_PROTOCOL)             += srtpproto.o srtp.o | ||||
| OBJS-$(CONFIG_SUBFILE_PROTOCOL)          += subfile.o | ||||
| OBJS-$(CONFIG_TEE_PROTOCOL)              += teeproto.o | ||||
| OBJS-$(CONFIG_TCP_PROTOCOL)              += tcp.o | ||||
| OBJS-$(CONFIG_TLS_GNUTLS_PROTOCOL)       += tls_gnutls.o tls.o | ||||
| OBJS-$(CONFIG_TLS_OPENSSL_PROTOCOL)      += tls_openssl.o tls.o | ||||
|   | ||||
| @@ -53,6 +53,7 @@ extern const URLProtocol ff_rtp_protocol; | ||||
| extern const URLProtocol ff_sctp_protocol; | ||||
| extern const URLProtocol ff_srtp_protocol; | ||||
| extern const URLProtocol ff_subfile_protocol; | ||||
| extern const URLProtocol ff_tee_protocol; | ||||
| extern const URLProtocol ff_tcp_protocol; | ||||
| extern const URLProtocol ff_tls_gnutls_protocol; | ||||
| extern const URLProtocol ff_tls_schannel_protocol; | ||||
|   | ||||
							
								
								
									
										137
									
								
								libavformat/teeproto.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								libavformat/teeproto.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| /* | ||||
|  * Tee output protocol | ||||
|  * Copyright (c) 2016 Michael Niedermayer | ||||
|  * | ||||
|  * 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 "libavutil/avstring.h" | ||||
| #include "libavutil/opt.h" | ||||
| #include "avformat.h" | ||||
| #include "avio_internal.h" | ||||
|  | ||||
| typedef struct ChildContext { | ||||
|     URLContext *url_context; | ||||
| } ChildContext; | ||||
|  | ||||
| typedef struct TeeContext { | ||||
|     const AVClass *class; | ||||
|     int child_count; | ||||
|     ChildContext *child; | ||||
| } TeeContext; | ||||
|  | ||||
| static const AVOption tee_options[] = { | ||||
|     { NULL } | ||||
| }; | ||||
|  | ||||
| static const AVClass tee_class = { | ||||
|     .class_name = "tee", | ||||
|     .item_name  = av_default_item_name, | ||||
|     .option     = tee_options, | ||||
|     .version    = LIBAVUTIL_VERSION_INT, | ||||
| }; | ||||
|  | ||||
| static const char *const child_delim = "|"; | ||||
|  | ||||
| static int tee_write(URLContext *h, const unsigned char *buf, int size) | ||||
| { | ||||
|     TeeContext *c = h->priv_data; | ||||
|     int i; | ||||
|     int main_ret = size; | ||||
|  | ||||
|     for (i=0; i<c->child_count; i++) { | ||||
|         int ret = ffurl_write(c->child[i].url_context, buf, size); | ||||
|         if (ret < 0) | ||||
|             main_ret = ret; | ||||
|     } | ||||
|     return main_ret; | ||||
| } | ||||
|  | ||||
| static int tee_close(URLContext *h) | ||||
| { | ||||
|     TeeContext *c = h->priv_data; | ||||
|     int i; | ||||
|     int main_ret = 0; | ||||
|  | ||||
|     for (i=0; i<c->child_count; i++) { | ||||
|         int ret = ffurl_closep(&c->child[i].url_context); | ||||
|         if (ret < 0) | ||||
|             main_ret = ret; | ||||
|     } | ||||
|  | ||||
|     av_freep(&c->child); | ||||
|     c->child_count = 0; | ||||
|     return main_ret; | ||||
| } | ||||
|  | ||||
| static int tee_open(URLContext *h, const char *filename, int flags) | ||||
| { | ||||
|     TeeContext *c = h->priv_data; | ||||
|     int ret, i; | ||||
|  | ||||
|     av_strstart(filename, "tee:", &filename); | ||||
|  | ||||
|     if (flags & AVIO_FLAG_READ) | ||||
|         return AVERROR(ENOSYS); | ||||
|  | ||||
|     while (*filename) { | ||||
|         char *child_name = av_get_token(&filename, child_delim); | ||||
|         void *tmp; | ||||
|         if (!child_name) { | ||||
|             ret = AVERROR(ENOMEM); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         tmp = av_realloc_array(c->child, c->child_count + 1, sizeof(*c->child)); | ||||
|         if (!tmp) { | ||||
|             ret = AVERROR(ENOMEM); | ||||
|             goto fail; | ||||
|         } | ||||
|         c->child = tmp; | ||||
|         memset(&c->child[c->child_count], 0, sizeof(&c->child[c->child_count])); | ||||
|  | ||||
|         ret = ffurl_open_whitelist(&c->child[c->child_count].url_context, child_name, flags, | ||||
|                                    &h->interrupt_callback, /*AVDictionary **options*/NULL, | ||||
|                                    h->protocol_whitelist, h->protocol_blacklist, | ||||
|                                    h); | ||||
|         av_free(child_name); | ||||
|         if (ret < 0) | ||||
|             goto fail; | ||||
|         c->child_count++; | ||||
|  | ||||
|         if (strspn(filename, child_delim)) | ||||
|             filename++; | ||||
|     } | ||||
|  | ||||
|     h->is_streamed = 0; | ||||
|     for (i=0; i<c->child_count; i++) { | ||||
|         h->is_streamed |= c->child[i].url_context->is_streamed; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| fail: | ||||
|     tee_close(h); | ||||
|     return ret; | ||||
| } | ||||
| const URLProtocol ff_tee_protocol = { | ||||
|     .name                = "tee", | ||||
|     .url_open            = tee_open, | ||||
|     .url_write           = tee_write, | ||||
|     .priv_data_size      = sizeof(TeeContext), | ||||
|     .priv_data_class     = &tee_class, | ||||
|     .default_whitelist   = "crypto,file,http,https,httpproxy,rtmp,tcp,tls" | ||||
| }; | ||||
| @@ -32,7 +32,7 @@ | ||||
| // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) | ||||
| // Also please add any ticket numbers that you belive might be affected here | ||||
| #define LIBAVFORMAT_VERSION_MAJOR  57 | ||||
| #define LIBAVFORMAT_VERSION_MINOR  42 | ||||
| #define LIBAVFORMAT_VERSION_MINOR  43 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 100 | ||||
|  | ||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Niedermayer
					Michael Niedermayer