[FFmpeg-cvslog] avformat/hlsenc: write temp file for append single file by encryption mode

2020-08-10 Thread Steven Liu
ffmpeg | branch: master | Steven Liu  | Wed Jul 22 
17:15:29 2020 +0800| [40597add98a7378402b4a653fd3057426074def9] | committer: 
Steven Liu

avformat/hlsenc: write temp file for append single file by encryption mode

fix ticket: 8783
Because in single file by encryption mode, it cannot get the last one
block of the file, it need ff_format_io_close for get full file size,
then hlsenc can get the total size of the encryption content,
so write the content into temp file first, and get the temp file content
append the temp file content into append to single file, then hlsenc can
get the correct file/content size and offset.

Signed-off-by: Steven Liu 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=40597add98a7378402b4a653fd3057426074def9
---

 libavformat/hlsenc.c | 70 ++--
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 39ff1fa1e7..cb31d6aed7 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -69,6 +69,7 @@ typedef enum {
 #define KEYSIZE 16
 #define LINE_BUFFER_SIZE MAX_URL_SIZE
 #define HLS_MICROSECOND_UNIT   100
+#define BUFSIZE (16 * 1024)
 #define POSTFIX_PATTERN "_%d"
 
 typedef struct HLSSegment {
@@ -119,6 +120,7 @@ typedef struct VariantStream {
 ff_const59 AVOutputFormat *oformat;
 ff_const59 AVOutputFormat *vtt_oformat;
 AVIOContext *out;
+AVIOContext *out_single_file;
 int packets_written;
 int init_range_length;
 uint8_t *temp_buffer;
@@ -149,6 +151,7 @@ typedef struct VariantStream {
 HLSSegment *last_segment;
 HLSSegment *old_segments;
 
+char *basename_tmp;
 char *basename;
 char *vtt_basename;
 char *vtt_m3u8_name;
@@ -1722,12 +1725,34 @@ static int hls_start(AVFormatContext *s, VariantStream 
*vs)
 av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
 }
 if (c->flags & HLS_SINGLE_FILE) {
+if (c->key_info_file || c->encrypt) {
+av_dict_set(&options, "encryption_key", vs->key_string, 0);
+av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
+
+/* Write temp file with cryption content */
+av_freep(&vs->basename_tmp);
+vs->basename_tmp = av_asprintf("crypto:%s.tmp", oc->url);
+
+/* append temp file content into single file */
+av_freep(&vs->basename);
+vs->basename = av_asprintf("%s", oc->url);
+} else {
+vs->basename_tmp = vs->basename;
+}
 set_http_options(s, &options, c);
-if ((err = hlsenc_io_open(s, &vs->out, oc->url, &options)) < 0) {
+if (!vs->out_single_file)
+if ((err = hlsenc_io_open(s, &vs->out_single_file, 
vs->basename, &options)) < 0) {
+if (c->ignore_io_errors)
+err = 0;
+goto fail;
+}
+
+if ((err = hlsenc_io_open(s, &vs->out, vs->basename_tmp, 
&options)) < 0) {
 if (c->ignore_io_errors)
 err = 0;
 goto fail;
 }
+
 }
 }
 if (vs->vtt_basename) {
@@ -2258,6 +2283,38 @@ static int hls_init_file_resend(AVFormatContext *s, 
VariantStream *vs)
 return ret;
 }
 
+static int64_t append_single_file(AVFormatContext *s, VariantStream *vs)
+{
+int ret = 0;
+int64_t read_byte = 0;
+int64_t total_size = 0;
+char *filename = NULL;
+char buf[BUFSIZE];
+AVFormatContext *oc = vs->avf;
+
+hlsenc_io_close(s, &vs->out, vs->basename_tmp);
+filename = av_asprintf("%s.tmp", oc->url);
+ret = s->io_open(s, &vs->out, filename, AVIO_FLAG_READ, NULL);
+if (ret < 0) {
+av_free(filename);
+return ret;
+}
+
+do {
+memset(buf, 0, sizeof(BUFSIZE));
+read_byte = avio_read(vs->out, buf, BUFSIZE);
+avio_write(vs->out_single_file, buf, read_byte);
+if (read_byte > 0) {
+total_size += read_byte;
+ret = total_size;
+}
+} while (read_byte > 0);
+
+hlsenc_io_close(s, &vs->out, filename);
+av_free(filename);
+
+return ret;
+}
 static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
 HLSContext *hls = s->priv_data;
@@ -2383,6 +2440,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 return ret;
 }
 vs->size = range_length;
+if (hls->key_info_file || hls->encrypt)
+vs->size = append_single_file(s, vs);
 } else {
 if (oc->url[0]) {
 proto = avio_find_protocol_name(oc->url);
@@ -2484,6 +2543,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 
 if (hls->flags & HLS_SINGLE_FILE) {
 vs->start_pos += vs->size;
+if (hls->key_info_file || hls->encrypt)
+

[FFmpeg-cvslog] avformat/hls: support avio_seek in encryption mode

2020-08-10 Thread Steven Liu
ffmpeg | branch: master | Steven Liu  | Wed Jul 22 
17:15:28 2020 +0800| [6e4bba40557613282a10dadb5a0a9c5f5f500987] | committer: 
Steven Liu

avformat/hls: support avio_seek in encryption mode

Signed-off-by: Steven Liu 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6e4bba40557613282a10dadb5a0a9c5f5f500987
---

 libavformat/hls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index cf0b71d65d..84f0a5f323 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1291,7 +1291,7 @@ static int open_input(HLSContext *c, struct playlist 
*pls, struct segment *seg,
  * as would be expected. Wrong offset received from the server will not be
  * noticed without the call, though.
  */
-if (ret == 0 && !is_http && seg->key_type == KEY_NONE && seg->url_offset) {
+if (ret == 0 && !is_http && seg->url_offset) {
 int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET);
 if (seekret < 0) {
 av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset 
%"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-cvslog] dnn/native: add native support for avg_pool

2020-08-10 Thread Ting Fu
ffmpeg | branch: master | Ting Fu  | Mon Aug 10 00:33:13 
2020 +0800| [91efc41a69f223bd1ed92b8916ad9e9de63e9d9e] | committer: Guo, Yejun

dnn/native: add native support for avg_pool

Not support pooling strides in channel dimension yet.

Signed-off-by: Ting Fu 
Reviewed-by: Guo, Yejun 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=91efc41a69f223bd1ed92b8916ad9e9de63e9d9e
---

 libavfilter/dnn/Makefile   |   1 +
 libavfilter/dnn/dnn_backend_native.h   |   2 +
 libavfilter/dnn/dnn_backend_native_layer_avgpool.c | 141 +
 libavfilter/dnn/dnn_backend_native_layer_avgpool.h |  40 ++
 libavfilter/dnn/dnn_backend_native_layer_conv2d.h  |   3 +-
 libavfilter/dnn/dnn_backend_native_layers.c|   2 +
 tools/python/convert_from_tensorflow.py|  37 +-
 7 files changed, 223 insertions(+), 3 deletions(-)

diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile
index d90137ec42..e0957073ee 100644
--- a/libavfilter/dnn/Makefile
+++ b/libavfilter/dnn/Makefile
@@ -1,6 +1,7 @@
 OBJS-$(CONFIG_DNN)   += dnn/dnn_interface.o
 OBJS-$(CONFIG_DNN)   += dnn/dnn_backend_native.o
 OBJS-$(CONFIG_DNN)   += dnn/dnn_backend_native_layers.o
+OBJS-$(CONFIG_DNN)   += 
dnn/dnn_backend_native_layer_avgpool.o
 OBJS-$(CONFIG_DNN)   += 
dnn/dnn_backend_native_layer_pad.o
 OBJS-$(CONFIG_DNN)   += 
dnn/dnn_backend_native_layer_conv2d.o
 OBJS-$(CONFIG_DNN)   += 
dnn/dnn_backend_native_layer_depth2space.o
diff --git a/libavfilter/dnn/dnn_backend_native.h 
b/libavfilter/dnn/dnn_backend_native.h
index 62191ffe88..26e9a33387 100644
--- a/libavfilter/dnn/dnn_backend_native.h
+++ b/libavfilter/dnn/dnn_backend_native.h
@@ -43,10 +43,12 @@ typedef enum {
 DLT_MAXIMUM = 4,
 DLT_MATH_BINARY = 5,
 DLT_MATH_UNARY = 6,
+DLT_AVG_POOL = 7,
 DLT_COUNT
 } DNNLayerType;
 
 typedef enum {DOT_INPUT = 1, DOT_OUTPUT = 2, DOT_INTERMEDIATE = DOT_INPUT | 
DOT_OUTPUT} DNNOperandType;
+typedef enum {VALID, SAME, SAME_CLAMP_TO_EDGE} DNNPaddingParam;
 
 typedef struct Layer{
 DNNLayerType type;
diff --git a/libavfilter/dnn/dnn_backend_native_layer_avgpool.c 
b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c
new file mode 100644
index 00..d745c35b4a
--- /dev/null
+++ b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2020
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * DNN native backend implementation.
+ */
+
+#include "libavutil/avassert.h"
+#include "dnn_backend_native_layer_avgpool.h"
+
+int dnn_load_layer_avg_pool(Layer *layer, AVIOContext *model_file_context, int 
file_size, int operands_num)
+{
+AvgPoolParams *avgpool_params;
+int dnn_size = 0;
+avgpool_params = av_malloc(sizeof(*avgpool_params));
+if(!avgpool_params)
+return 0;
+
+avgpool_params->strides = (int32_t)avio_rl32(model_file_context);
+avgpool_params->padding_method = (int32_t)avio_rl32(model_file_context);
+avgpool_params->kernel_size = (int32_t)avio_rl32(model_file_context);
+dnn_size += 12;
+
+if (dnn_size > file_size || avgpool_params->kernel_size <= 0 || 
avgpool_params->strides <=0){
+av_freep(&avgpool_params);
+return 0;
+}
+
+layer->params = avgpool_params;
+layer->input_operand_indexes[0] = (int32_t)avio_rl32(model_file_context);
+layer->output_operand_index = (int32_t)avio_rl32(model_file_context);
+dnn_size += 8;
+
+if (layer->input_operand_indexes[0] >= operands_num || 
layer->output_operand_index >= operands_num) {
+return 0;
+}
+return dnn_size;
+}
+
+int dnn_execute_layer_avg_pool(DnnOperand *operands, const int32_t 
*input_operand_indexes,
+ int32_t output_operand_index, const void 
*parameters)
+{
+float *output;
+int height_end, width_end, height_radius, width_radius, output_height, 
output_width, kernel_area;
+int32_t input_operand_index = input_operand_indexes[0];
+int number = operands[input_operand_index].dims[0];
+int height = operands[input_operand_index].dims[

[FFmpeg-cvslog] FATE/dnn: add unit test for dnn avgpool layer

2020-08-10 Thread Ting Fu
ffmpeg | branch: master | Ting Fu  | Mon Aug 10 00:33:14 
2020 +0800| [de5cb6c060236c4667eac1006dfd1e54f06bde9f] | committer: Guo, Yejun

FATE/dnn: add unit test for dnn avgpool layer

'make fate-dnn-layer-avgpool' to run the test

Signed-off-by: Ting Fu 
Reviewed-by: Guo, Yejun 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=de5cb6c060236c4667eac1006dfd1e54f06bde9f
---

 tests/dnn/.gitignore   |   1 +
 tests/dnn/Makefile |   1 +
 tests/dnn/dnn-layer-avgpool-test.c | 197 +
 tests/fate/dnn.mak |   5 +
 4 files changed, 204 insertions(+)

diff --git a/tests/dnn/.gitignore b/tests/dnn/.gitignore
index 1fcd2410b4..b847a01177 100644
--- a/tests/dnn/.gitignore
+++ b/tests/dnn/.gitignore
@@ -4,3 +4,4 @@
 /dnn-layer-pad-test
 /dnn-layer-mathbinary-test
 /dnn-layer-mathunary-test
+/dnn-layer-avgpool-test
diff --git a/tests/dnn/Makefile b/tests/dnn/Makefile
index 64591b7851..8afdfab5d3 100644
--- a/tests/dnn/Makefile
+++ b/tests/dnn/Makefile
@@ -4,6 +4,7 @@ DNNTESTPROGS += dnn-layer-depth2space
 DNNTESTPROGS += dnn-layer-mathbinary
 DNNTESTPROGS += dnn-layer-maximum
 DNNTESTPROGS += dnn-layer-mathunary
+DNNTESTPROGS += dnn-layer-avgpool
 
 DNNTESTOBJS  := $(DNNTESTOBJS:%=$(DNNTESTSDIR)%) 
$(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test.o)
 DNNTESTPROGS := $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test$(EXESUF))
diff --git a/tests/dnn/dnn-layer-avgpool-test.c 
b/tests/dnn/dnn-layer-avgpool-test.c
new file mode 100644
index 00..d7c33a0e88
--- /dev/null
+++ b/tests/dnn/dnn-layer-avgpool-test.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2020
+ *
+ * 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 
+#include "libavfilter/dnn/dnn_backend_native_layer_avgpool.h"
+
+#define EPSON 0.1
+
+static int test_with_same(void)
+{
+// the input data and expected data are generated with below python code.
+/*
+import tensorflow as tf
+import numpy as np
+
+x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
+y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], 
padding='VALID')
+data = np.random.rand(1, 5, 6, 3);
+
+sess=tf.Session()
+sess.run(tf.global_variables_initializer())
+
+output = sess.run(y, feed_dict={x: data})
+
+print("input:")
+print(data.shape)
+print(list(data.flatten()))
+
+print("output:")
+print(output.shape)
+print(list(output.flatten()))
+*/
+
+AvgPoolParams params;
+DnnOperand operands[2];
+int32_t input_indexes[1];
+float input[1*5*6*3] = {
+0.7461309859908424, 0.7567538372797069, 0.07662743569678687, 
0.8882112610336333, 0.9720443314026668, 0.3337200343220823, 0.4421032129780248,
+0.14940809044964876, 0.6773177061961277, 0.9778844630669781, 
0.6522650522626998, 0.0317651530878591, 0.31259897552911364, 0.6235936821891896,
+0.40016094349542775, 0.4599222930032276, 0.7893807222960093, 
0.8475986363538283, 0.5058802717647394, 0.7827005363222633, 0.3032188123727916,
+0.8983728631302361, 0.20622408444965523, 0.22966072303869878, 
0.09535751273161308, 0.8760709100995375, 0.9982324154558745, 0.7904595468621013,
+0.13883671508879347, 0.9332751439533138, 0.0010861680752152214, 
0.3607210449251048, 0.6600652759586171, 0.7629572058138805, 0.29441975810476106,
+0.2683471432889405, 0.22574580829831536, 0.8893251976212904, 
0.3907737043801005, 0.6421829842863968, 0.6670373870457297, 0.9383850793160277,
+0.4120458907436003, 0.3589847212711481, 0.48047736550128983, 
0.6428192648418949, 0.0313661686292348, 0.429357100401472, 0.5123413386514056,
+0.8492446404097114, 0.9045286128486804, 0.8123708563814285, 
0.3943245008451698, 0.9576713003177785, 0.5985610965938726, 0.9350833279543561,
+0.8010079897491659, 0.45882114217642866, 0.35275037908941487, 
0.4555844661432271, 0.12352455940255314, 0.37801756635035544, 
0.2824056214573083,
+0.6229462823245029, 0.7235305681391472, 0.5408259266122064, 
0.12142224381781208, 0.34431198802873686, 0.7112823816321276, 
0.6307144385115417,
+0.8136734589018082, 0.842095618140585, 0.8602767724004784, 
0.6649236853766185, 0.5184782829419623, 0.9119607270982825, 0.3084111974561645,
+0.3946070563816136

[FFmpeg-cvslog] avcodec/jpeg2000dec: Check remaining data in packed_headers_stream before use

2020-08-10 Thread Michael Niedermayer
ffmpeg | branch: master | Michael Niedermayer  | Sun 
Aug  2 01:15:34 2020 +0200| [a5ac81952e8ea3b071190d36a41b7bab4e957f66] | 
committer: Michael Niedermayer

avcodec/jpeg2000dec: Check remaining data in packed_headers_stream before use

Fixes: out of array read
Fixes: 
24487/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_JPEG2000_fuzzer-5165847820369920
Fixes: 
24636/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_JPEG2000_fuzzer-5700973918683136
Fixes: 
24683/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_JPEG2000_fuzzer-6202883897556992

Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a5ac81952e8ea3b071190d36a41b7bab4e957f66
---

 libavcodec/jpeg2000dec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index a4c20f45c5..624542c2f8 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -2184,7 +2184,9 @@ static int 
jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
 }
 
 if (s->has_ppm) {
-uint32_t tp_header_size = 
bytestream2_get_be32u(&s->packed_headers_stream);
+uint32_t tp_header_size = 
bytestream2_get_be32(&s->packed_headers_stream);
+if (bytestream2_get_bytes_left(&s->packed_headers_stream) < 
tp_header_size)
+return AVERROR_INVALIDDATA;
 bytestream2_init(&tp->header_tpg, 
s->packed_headers_stream.buffer, tp_header_size);
 bytestream2_skip(&s->packed_headers_stream, tp_header_size);
 }

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-cvslog] avformat/mpegts: Don't leave context in inconsistent state upon error

2020-08-10 Thread Andreas Rheinhardt
ffmpeg | branch: master | Andreas Rheinhardt  | 
Mon Aug 10 14:20:58 2020 +0200| [1ead176d874acb489827ace3935fc71e1eea7e0e] | 
committer: Andreas Rheinhardt

avformat/mpegts: Don't leave context in inconsistent state upon error

Up until now, opening a section filter works as follows: A filter is
opened and (on success) attached to the MpegTSContext. Then a buffer for
said filter is allocated and upon success attached to the section
filter; on error, the filter is simply freed without removing it from
the MpegTSContext, leaving the latter in an inconsistent state. This
leads to use-after-frees lateron.

This commit fixes this by allocating the buffer first; the filter is
only opened if the buffer could be successfully allocated.

Reviewed-by: Marton Balint 
Signed-off-by: Andreas Rheinhardt 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1ead176d874acb489827ace3935fc71e1eea7e0e
---

 libavformat/mpegts.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index c6fd3e1cef..f71f18a57d 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -510,20 +510,22 @@ static MpegTSFilter 
*mpegts_open_section_filter(MpegTSContext *ts,
 {
 MpegTSFilter *filter;
 MpegTSSectionFilter *sec;
+uint8_t *section_buf = av_mallocz(MAX_SECTION_SIZE);
 
-if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION)))
+if (!section_buf)
 return NULL;
+
+if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION))) {
+av_free(section_buf);
+return NULL;
+}
 sec = &filter->u.section_filter;
 sec->section_cb  = section_cb;
 sec->opaque  = opaque;
-sec->section_buf = av_mallocz(MAX_SECTION_SIZE);
+sec->section_buf = section_buf;
 sec->check_crc   = check_crc;
 sec->last_ver= -1;
 
-if (!sec->section_buf) {
-av_free(filter);
-return NULL;
-}
 return filter;
 }
 

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".