From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 06D484940E for ; Wed, 10 Apr 2024 17:42:02 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3179D68CFFF; Wed, 10 Apr 2024 20:41:59 +0300 (EEST) Received: from mail-qt1-f169.google.com (mail-qt1-f169.google.com [209.85.160.169]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id DC38A68BDE1 for ; Wed, 10 Apr 2024 20:41:52 +0300 (EEST) Received: by mail-qt1-f169.google.com with SMTP id d75a77b69052e-43477091797so22001cf.1 for ; Wed, 10 Apr 2024 10:41:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712770911; x=1713375711; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9FK+VCXcMtKA78CSX475Vi+poz97fckxi2Mb74BAX7U=; b=weNJZOMnoo4++PwpiwcMk8V9jf8y7bUAYvN2630tGokVNNJhl6iX/v+WYjBxOuMPsi CYTNg9nvAF6IQvfEgcX8HAqBJvgaeAO5tAW2BoluGbrSqxgYJqqoe4O3sQANaiQKIOAN CT6XlvIfZ4FpK+MK4b8f9+TK/PkHgcY+j3XWHquiqcvDAWbd/8EEvFdSeG/+anqBijmk 7q15NFOeDuofhQXfY/6bXBt5ifFNMXshK5tv0ZNEx+xJvUloPG0IIeOIxbeJM7JUkv8W 4fLjJw9fOkJuFPCy+OdsgXJEVMmUB1U+j12JTlxwQKoQUGiiQSFnhLSyaDWTqqwQJ1Cn iDdQ== X-Gm-Message-State: AOJu0YzcTuCihMnkFRu1G2LBwhW/6Fax2cxmJV2bmgVSzXjFdFXN/frc 1hPQEEJ+FffYJtNcntfX2pL6bhhySg/yfEiYHAYFHfJVnjBVy4pXVa4gTqle9DpJvBjD50W1exk C3Uss50j0foFwCakqTM1AfMOHTbhyqZPhDOYEqSMuvcj25HeoGtae X-Google-Smtp-Source: AGHT+IGE/u+FvxMRGbEgVLz7jklvf84BZAAmD1Y5e2e24Q8ebiUfsYmJRILe4rAbPzSQCokrN3QeaacC/BeDNbjw2i8= X-Received: by 2002:a05:622a:a13:b0:434:f614:2bf6 with SMTP id bv19-20020a05622a0a1300b00434f6142bf6mr4258qtb.10.1712770910461; Wed, 10 Apr 2024 10:41:50 -0700 (PDT) MIME-Version: 1.0 References: <20240408222733.1422670-1-asoulier@google.com> In-Reply-To: Date: Wed, 10 Apr 2024 10:41:39 -0700 Message-ID: To: FFmpeg development discussions and patches , Antoine Soulier Content-Type: multipart/mixed; boundary="000000000000b434f90615c18d50" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: Re: [FFmpeg-devel] [PATCH] avformat/lc3: Add file format for LC3/LC3plus transport X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Antoine Soulier via ffmpeg-devel Reply-To: FFmpeg development discussions and patches Cc: Antoine Soulier Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: --000000000000b434f90615c18d50 Content-Type: text/plain; charset="UTF-8" Sorry for that, I missed the rebasing. I have followed your recommendations, and put the muxer/demuxer in the same file. Here is the patch: >From f85989288a99130eb3583d5ae9c5bf441e961ed4 Mon Sep 17 00:00:00 2001 From: Antoine SOULIER Date: Thu, 4 Apr 2024 22:38:03 +0000 Subject: [PATCH] avformat/lc3: Add file format for LC3/LC3plus transport A file format is described in Bluetooth SIG LC3 and ETSI TS 103 634, for test purpose. This is the format implemented here. --- Changelog | 1 + doc/muxers.texi | 8 ++ libavformat/Makefile | 2 + libavformat/allformats.c | 2 + libavformat/lc3.c | 248 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 261 insertions(+) create mode 100644 libavformat/lc3.c diff --git a/Changelog b/Changelog index b7a1af4083..5c8f505211 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,7 @@ version : - Raw Captions with Time (RCWT) closed caption demuxer - LC3/LC3plus decoding/encoding using external library liblc3 - ffmpeg CLI filtergraph chaining +- LC3/LC3plus demuxer and muxer version 7.0: diff --git a/doc/muxers.texi b/doc/muxers.texi index 4b30970b78..032f48410e 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -2703,6 +2703,14 @@ This muxer accepts a single audio stream containing PCM data. @section ivf On2 IVF muxer. +@section lc3 +Bluetooth SIG Low Complexity Communication Codec audio (LC3), or +ETSI TS 103 634 Low Complexity Communication Codec plus (LC3plus). + +This muxer accepts a single @code{lc3} audio stream. + +@section matroska + IVF was developed by On2 Technologies (formerly known as Duck Corporation), to store internally developed codecs. diff --git a/libavformat/Makefile b/libavformat/Makefile index 9981799cc9..8efe26b6df 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -332,6 +332,8 @@ OBJS-$(CONFIG_KVAG_DEMUXER) += kvag.o OBJS-$(CONFIG_KVAG_MUXER) += kvag.o rawenc.o OBJS-$(CONFIG_LAF_DEMUXER) += lafdec.o OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o +OBJS-$(CONFIG_LC3_DEMUXER) += lc3.o +OBJS-$(CONFIG_LC3_MUXER) += lc3.o OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o rawdec.o OBJS-$(CONFIG_LUODAT_DEMUXER) += luodatdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index ae925dcf60..305fa46532 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -252,6 +252,8 @@ extern const FFInputFormat ff_kvag_demuxer; extern const FFOutputFormat ff_kvag_muxer; extern const FFInputFormat ff_laf_demuxer; extern const FFOutputFormat ff_latm_muxer; +extern const FFInputFormat ff_lc3_demuxer; +extern const FFOutputFormat ff_lc3_muxer; extern const FFInputFormat ff_lmlm4_demuxer; extern const FFInputFormat ff_loas_demuxer; extern const FFInputFormat ff_luodat_demuxer; diff --git a/libavformat/lc3.c b/libavformat/lc3.c new file mode 100644 index 0000000000..8b1ec62589 --- /dev/null +++ b/libavformat/lc3.c @@ -0,0 +1,248 @@ +/* + * LC3 demuxer + * Copyright (C) 2024 Antoine Soulier + * + * 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 + * Based on the file format specified by : + * + * - Bluetooth SIG - Low Complexity Communication Codec Test Suite + * https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=502301 + * 3.2.8.2 Reference LC3 Codec Bitstream Format + * + * - ETSI TI 103 634 V1.4.1 - Low Complexity Communication Codec plus + * https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.04.01_60/ts_103634v010401p.pdf + * LC3plus conformance script package + */ + +#include "config_components.h" + +#include "libavcodec/packet.h" +#include "libavutil/intreadwrite.h" + +#include "avformat.h" +#include "avio.h" +#include "demux.h" +#include "internal.h" +#include "mux.h" + +typedef struct LC3DemuxContext { + int frame_samples; + int64_t end_dts; +} LC3DemuxContext; + +static int check_frame_length(int srate_hz, int frame_us) +{ + if (srate_hz != 8000 && srate_hz != 16000 && srate_hz != 24000 && + srate_hz != 32000 && srate_hz != 48000 && srate_hz != 96000) + return -1; + + if (frame_us != 2500 && frame_us != 5000 && + frame_us != 7500 && frame_us != 10000) + return -1; + + return 0; +} + +static int lc3_read_probe(const AVProbeData *p) +{ + int frame_us, srate_hz; + + if (p->buf_size < 12) + return 0; + + if (AV_RB16(p->buf + 0) != 0x1ccc || + AV_RL16(p->buf + 2) < 9 * sizeof(uint16_t)) + return 0; + + srate_hz = AV_RL16(p->buf + 4) * 100; + frame_us = AV_RL16(p->buf + 10) * 10; + if (check_frame_length(srate_hz, frame_us) < 0) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static int lc3_read_header(AVFormatContext *s) +{ + LC3DemuxContext *lc3 = s->priv_data; + AVStream *st = NULL; + uint16_t tag, hdr_size; + uint32_t length; + int srate_hz, frame_us, channels, bit_rate; + int ep_mode, hr_mode; + int num_extra_params; + int delay, ret; + + tag = avio_rb16(s->pb); + hdr_size = avio_rl16(s->pb); + + if (tag != 0x1ccc || hdr_size < 9 * sizeof(uint16_t)) + return AVERROR_INVALIDDATA; + + num_extra_params = hdr_size / sizeof(uint16_t) - 9; + + srate_hz = avio_rl16(s->pb) * 100; + bit_rate = avio_rl16(s->pb) * 100; + channels = avio_rl16(s->pb); + frame_us = avio_rl16(s->pb) * 10; + ep_mode = avio_rl16(s->pb) != 0; + length = avio_rl32(s->pb); + hr_mode = num_extra_params >= 1 && avio_rl16(s->pb); + + if (check_frame_length(srate_hz, frame_us) < 0) { + av_log(s, AV_LOG_ERROR, "Invalid LC3 sample rate: %d Hz, " + "frame duration: %.1f ms.\n", + srate_hz, frame_us / 1000.f); + return AVERROR_INVALIDDATA; + } + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + avpriv_set_pts_info(st, 64, 1, srate_hz); + avpriv_update_cur_dts(s, st, 0); + st->duration = length; + + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; + st->codecpar->codec_id = AV_CODEC_ID_LC3; + st->codecpar->sample_rate = srate_hz; + st->codecpar->bit_rate = bit_rate; + st->codecpar->ch_layout.nb_channels = channels; + + if ((ret = ff_alloc_extradata(st->codecpar, 6)) < 0) + return ret; + + AV_WL16(st->codecpar->extradata + 0, frame_us / 10); + AV_WL16(st->codecpar->extradata + 2, ep_mode); + AV_WL16(st->codecpar->extradata + 4, hr_mode); + + lc3->frame_samples = av_rescale(frame_us, srate_hz, 1000*1000); + + delay = av_rescale(frame_us == 7500 ? 4000 : 2500, srate_hz, 1000*1000); + lc3->end_dts = length ? length + delay : -1; + + return 0; +} + +static int lc3_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + LC3DemuxContext *lc3 = s->priv_data; + AVStream *st = s->streams[0]; + AVIOContext *pb = s->pb; + int64_t pos = avio_tell(pb); + int64_t remaining_samples; + int ret; + + ret = av_get_packet(s->pb, pkt, avio_rl16(pb)); + if (ret < 0) + return ret; + + pkt->pos = pos; + + remaining_samples = lc3->end_dts < 0 ? lc3->frame_samples : + FFMAX(lc3->end_dts - ffstream(st)->cur_dts, 0); + pkt->duration = FFMIN(lc3->frame_samples, remaining_samples); + + return 0; +} + +static av_cold int lc3_muxer_init(AVFormatContext *s) +{ + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "This muxer only supports a single stream.\n"); + return AVERROR(EINVAL); + } + + return 0; +} + +static int lc3_write_header(AVFormatContext *s) +{ + AVStream *st = s->streams[0]; + int channels = st->codecpar->ch_layout.nb_channels; + int srate_hz = st->codecpar->sample_rate; + int bit_rate = st->codecpar->bit_rate; + int frame_us, ep_mode, hr_mode; + uint32_t nb_samples = av_rescale_q( + st->duration, st->time_base, (AVRational){ 1, srate_hz }); + + if (st->codecpar->extradata_size < 6) + return AVERROR_INVALIDDATA; + + frame_us = AV_RL16(st->codecpar->extradata + 0) * 10; + ep_mode = AV_RL16(st->codecpar->extradata + 2) != 0; + hr_mode = AV_RL16(st->codecpar->extradata + 4) != 0; + + if (check_frame_length(srate_hz, frame_us) < 0) { + av_log(s, AV_LOG_ERROR, "Invalid LC3 sample rate: %d Hz, " + "frame duration: %.1f ms.\n", + srate_hz, frame_us / 1000.f); + return AVERROR_INVALIDDATA; + } + + avio_wb16(s->pb, 0x1ccc); + avio_wl16(s->pb, (9 + hr_mode) * sizeof(uint16_t)); + avio_wl16(s->pb, srate_hz / 100); + avio_wl16(s->pb, bit_rate / 100); + avio_wl16(s->pb, channels); + avio_wl16(s->pb, frame_us / 10); + avio_wl16(s->pb, ep_mode); + avio_wl32(s->pb, nb_samples); + if (hr_mode) + avio_wl16(s->pb, hr_mode); + + return 0; +} + +static int lc3_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + avio_wl16(s->pb, pkt->size); + avio_write(s->pb, pkt->data, pkt->size); + return 0; +} + +#if CONFIG_LC3_DEMUXER +const FFInputFormat ff_lc3_demuxer = { + .p.name = "lc3", + .p.long_name = NULL_IF_CONFIG_SMALL("LC3 (Low Complexity Communication Codec)"), + .p.extensions = "lc3", + .p.flags = AVFMT_GENERIC_INDEX, + .priv_data_size = sizeof(LC3DemuxContext), + .read_probe = lc3_read_probe, + .read_header = lc3_read_header, + .read_packet = lc3_read_packet, +}; +#endif + +#if CONFIG_LC3_MUXER +const FFOutputFormat ff_lc3_muxer = { + .p.name = "lc3", + .p.long_name = NULL_IF_CONFIG_SMALL("LC3 (Low Complexity Communication Codec)"), + .p.extensions = "lc3", + .p.audio_codec = AV_CODEC_ID_LC3, + .p.video_codec = AV_CODEC_ID_NONE, + .p.flags = AVFMT_NOTIMESTAMPS, + .init = lc3_muxer_init, + .write_header = lc3_write_header, + .write_packet = lc3_write_packet, +}; +#endif -- 2.44.0.683.g7961c838ac-goog --000000000000b434f90615c18d50 Content-Type: text/x-patch; charset="US-ASCII"; name="0001-avformat-lc3-Add-file-format-for-LC3-LC3plus-transpo.patch" Content-Disposition: attachment; filename="0001-avformat-lc3-Add-file-format-for-LC3-LC3plus-transpo.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_luu3gifl0 RnJvbSBmODU5ODkyODhhOTkxMzBlYjM1ODNkNWFlOWM1YmY0NDFlOTYxZWQ0IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBBbnRvaW5lIFNPVUxJRVIgPGFzb3VsaWVyQGdvb2dsZS5jb20+ CkRhdGU6IFRodSwgNCBBcHIgMjAyNCAyMjozODowMyArMDAwMApTdWJqZWN0OiBbUEFUQ0hdIGF2 Zm9ybWF0L2xjMzogQWRkIGZpbGUgZm9ybWF0IGZvciBMQzMvTEMzcGx1cyB0cmFuc3BvcnQKCkEg ZmlsZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGluIEJsdWV0b290aCBTSUcgTEMzIGFuZCBFVFNJIFRT IDEwMyA2MzQsIGZvcgp0ZXN0IHB1cnBvc2UuIFRoaXMgaXMgdGhlIGZvcm1hdCBpbXBsZW1lbnRl ZCBoZXJlLgotLS0KIENoYW5nZWxvZyAgICAgICAgICAgICAgICB8ICAgMSArCiBkb2MvbXV4ZXJz LnRleGkgICAgICAgICAgfCAgIDggKysKIGxpYmF2Zm9ybWF0L01ha2VmaWxlICAgICB8ICAgMiAr CiBsaWJhdmZvcm1hdC9hbGxmb3JtYXRzLmMgfCAgIDIgKwogbGliYXZmb3JtYXQvbGMzLmMgICAg ICAgIHwgMjQ4ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogNSBmaWxl cyBjaGFuZ2VkLCAyNjEgaW5zZXJ0aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IGxpYmF2Zm9y bWF0L2xjMy5jCgpkaWZmIC0tZ2l0IGEvQ2hhbmdlbG9nIGIvQ2hhbmdlbG9nCmluZGV4IGI3YTFh ZjQwODMuLjVjOGY1MDUyMTEgMTAwNjQ0Ci0tLSBhL0NoYW5nZWxvZworKysgYi9DaGFuZ2Vsb2cK QEAgLTUsNiArNSw3IEBAIHZlcnNpb24gPG5leHQ+OgogLSBSYXcgQ2FwdGlvbnMgd2l0aCBUaW1l IChSQ1dUKSBjbG9zZWQgY2FwdGlvbiBkZW11eGVyCiAtIExDMy9MQzNwbHVzIGRlY29kaW5nL2Vu Y29kaW5nIHVzaW5nIGV4dGVybmFsIGxpYnJhcnkgbGlibGMzCiAtIGZmbXBlZyBDTEkgZmlsdGVy Z3JhcGggY2hhaW5pbmcKKy0gTEMzL0xDM3BsdXMgZGVtdXhlciBhbmQgbXV4ZXIKIAogCiB2ZXJz aW9uIDcuMDoKZGlmZiAtLWdpdCBhL2RvYy9tdXhlcnMudGV4aSBiL2RvYy9tdXhlcnMudGV4aQpp bmRleCA0YjMwOTcwYjc4Li4wMzJmNDg0MTBlIDEwMDY0NAotLS0gYS9kb2MvbXV4ZXJzLnRleGkK KysrIGIvZG9jL211eGVycy50ZXhpCkBAIC0yNzAzLDYgKzI3MDMsMTQgQEAgVGhpcyBtdXhlciBh Y2NlcHRzIGEgc2luZ2xlIGF1ZGlvIHN0cmVhbSBjb250YWluaW5nIFBDTSBkYXRhLgogQHNlY3Rp b24gaXZmCiBPbjIgSVZGIG11eGVyLgogCitAc2VjdGlvbiBsYzMKK0JsdWV0b290aCBTSUcgTG93 IENvbXBsZXhpdHkgQ29tbXVuaWNhdGlvbiBDb2RlYyBhdWRpbyAoTEMzKSwgb3IKK0VUU0kgVFMg MTAzIDYzNCBMb3cgQ29tcGxleGl0eSBDb21tdW5pY2F0aW9uIENvZGVjIHBsdXMgKExDM3BsdXMp LgorCitUaGlzIG11eGVyIGFjY2VwdHMgYSBzaW5nbGUgQGNvZGV7bGMzfSBhdWRpbyBzdHJlYW0u CisKK0BzZWN0aW9uIG1hdHJvc2thCisKIElWRiB3YXMgZGV2ZWxvcGVkIGJ5IE9uMiBUZWNobm9s b2dpZXMgKGZvcm1lcmx5IGtub3duIGFzIER1Y2sKIENvcnBvcmF0aW9uKSwgdG8gc3RvcmUgaW50 ZXJuYWxseSBkZXZlbG9wZWQgY29kZWNzLgogCmRpZmYgLS1naXQgYS9saWJhdmZvcm1hdC9NYWtl ZmlsZSBiL2xpYmF2Zm9ybWF0L01ha2VmaWxlCmluZGV4IDk5ODE3OTljYzkuLjhlZmUyNmI2ZGYg MTAwNjQ0Ci0tLSBhL2xpYmF2Zm9ybWF0L01ha2VmaWxlCisrKyBiL2xpYmF2Zm9ybWF0L01ha2Vm aWxlCkBAIC0zMzIsNiArMzMyLDggQEAgT0JKUy0kKENPTkZJR19LVkFHX0RFTVVYRVIpICAgICAg ICAgICAgICArPSBrdmFnLm8KIE9CSlMtJChDT05GSUdfS1ZBR19NVVhFUikgICAgICAgICAgICAg ICAgKz0ga3ZhZy5vIHJhd2VuYy5vCiBPQkpTLSQoQ09ORklHX0xBRl9ERU1VWEVSKSAgICAgICAg ICAgICAgICs9IGxhZmRlYy5vCiBPQkpTLSQoQ09ORklHX0xBVE1fTVVYRVIpICAgICAgICAgICAg ICAgICs9IGxhdG1lbmMubyByYXdlbmMubworT0JKUy0kKENPTkZJR19MQzNfREVNVVhFUikgICAg ICAgICAgICAgICArPSBsYzMubworT0JKUy0kKENPTkZJR19MQzNfTVVYRVIpICAgICAgICAgICAg ICAgICArPSBsYzMubwogT0JKUy0kKENPTkZJR19MTUxNNF9ERU1VWEVSKSAgICAgICAgICAgICAr PSBsbWxtNC5vCiBPQkpTLSQoQ09ORklHX0xPQVNfREVNVVhFUikgICAgICAgICAgICAgICs9IGxv YXNkZWMubyByYXdkZWMubwogT0JKUy0kKENPTkZJR19MVU9EQVRfREVNVVhFUikgICAgICAgICAg ICArPSBsdW9kYXRkZWMubwpkaWZmIC0tZ2l0IGEvbGliYXZmb3JtYXQvYWxsZm9ybWF0cy5jIGIv bGliYXZmb3JtYXQvYWxsZm9ybWF0cy5jCmluZGV4IGFlOTI1ZGNmNjAuLjMwNWZhNDY1MzIgMTAw NjQ0Ci0tLSBhL2xpYmF2Zm9ybWF0L2FsbGZvcm1hdHMuYworKysgYi9saWJhdmZvcm1hdC9hbGxm b3JtYXRzLmMKQEAgLTI1Miw2ICsyNTIsOCBAQCBleHRlcm4gY29uc3QgRkZJbnB1dEZvcm1hdCAg ZmZfa3ZhZ19kZW11eGVyOwogZXh0ZXJuIGNvbnN0IEZGT3V0cHV0Rm9ybWF0IGZmX2t2YWdfbXV4 ZXI7CiBleHRlcm4gY29uc3QgRkZJbnB1dEZvcm1hdCAgZmZfbGFmX2RlbXV4ZXI7CiBleHRlcm4g Y29uc3QgRkZPdXRwdXRGb3JtYXQgZmZfbGF0bV9tdXhlcjsKK2V4dGVybiBjb25zdCBGRklucHV0 Rm9ybWF0ICBmZl9sYzNfZGVtdXhlcjsKK2V4dGVybiBjb25zdCBGRk91dHB1dEZvcm1hdCBmZl9s YzNfbXV4ZXI7CiBleHRlcm4gY29uc3QgRkZJbnB1dEZvcm1hdCAgZmZfbG1sbTRfZGVtdXhlcjsK IGV4dGVybiBjb25zdCBGRklucHV0Rm9ybWF0ICBmZl9sb2FzX2RlbXV4ZXI7CiBleHRlcm4gY29u c3QgRkZJbnB1dEZvcm1hdCAgZmZfbHVvZGF0X2RlbXV4ZXI7CmRpZmYgLS1naXQgYS9saWJhdmZv cm1hdC9sYzMuYyBiL2xpYmF2Zm9ybWF0L2xjMy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAwMDAuLjhiMWVjNjI1ODkKLS0tIC9kZXYvbnVsbAorKysgYi9saWJhdmZvcm1hdC9s YzMuYwpAQCAtMCwwICsxLDI0OCBAQAorLyoKKyAqIExDMyBkZW11eGVyCisgKiBDb3B5cmlnaHQg KEMpIDIwMjQgIEFudG9pbmUgU291bGllciA8YXNvdWxpZXJAZ29vZ2xlLmNvbT4KKyAqCisgKiBU aGlzIGZpbGUgaXMgcGFydCBvZiBGRm1wZWcuCisgKgorICogRkZtcGVnIGlzIGZyZWUgc29mdHdh cmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5IGl0IHVuZGVyIHRo ZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYworICogTGljZW5zZSBhcyBw dWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCisgKiB2ZXJz aW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVy c2lvbi4KKyAqCisgKiBGRm1wZWcgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3 aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVu IHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBG T1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQorICogTGVzc2VyIEdlbmVyYWwg UHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KKyAqCisgKiBZb3Ugc2hvdWxkIGhhdmUg cmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCisgKiBMaWNl bnNlIGFsb25nIHdpdGggRkZtcGVnOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJl CisgKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBC b3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBCisgKi8KKworLyoqCisgKiBAZmlsZQorICogQmFzZWQg b24gdGhlIGZpbGUgZm9ybWF0IHNwZWNpZmllZCBieSA6CisgKgorICogLSBCbHVldG9vdGggU0lH IC0gTG93IENvbXBsZXhpdHkgQ29tbXVuaWNhdGlvbiBDb2RlYyBUZXN0IFN1aXRlCisgKiAgIGh0 dHBzOi8vd3d3LmJsdWV0b290aC5vcmcvZG9jbWFuL2hhbmRsZXJzL2Rvd25sb2FkZG9jLmFzaHg/ ZG9jX2lkPTUwMjMwMQorICogICAzLjIuOC4yIFJlZmVyZW5jZSBMQzMgQ29kZWMgQml0c3RyZWFt IEZvcm1hdAorICoKKyAqIC0gRVRTSSBUSSAxMDMgNjM0IFYxLjQuMSAtIExvdyBDb21wbGV4aXR5 IENvbW11bmljYXRpb24gQ29kZWMgcGx1cworICogICBodHRwczovL3d3dy5ldHNpLm9yZy9kZWxp dmVyL2V0c2lfdHMvMTAzNjAwXzEwMzY5OS8xMDM2MzQvMDEuMDQuMDFfNjAvdHNfMTAzNjM0djAx MDQwMXAucGRmCisgKiAgIExDM3BsdXMgY29uZm9ybWFuY2Ugc2NyaXB0IHBhY2thZ2UKKyAqLwor CisjaW5jbHVkZSAiY29uZmlnX2NvbXBvbmVudHMuaCIKKworI2luY2x1ZGUgImxpYmF2Y29kZWMv cGFja2V0LmgiCisjaW5jbHVkZSAibGliYXZ1dGlsL2ludHJlYWR3cml0ZS5oIgorCisjaW5jbHVk ZSAiYXZmb3JtYXQuaCIKKyNpbmNsdWRlICJhdmlvLmgiCisjaW5jbHVkZSAiZGVtdXguaCIKKyNp bmNsdWRlICJpbnRlcm5hbC5oIgorI2luY2x1ZGUgIm11eC5oIgorCit0eXBlZGVmIHN0cnVjdCBM QzNEZW11eENvbnRleHQgeworICAgIGludCBmcmFtZV9zYW1wbGVzOworICAgIGludDY0X3QgZW5k X2R0czsKK30gTEMzRGVtdXhDb250ZXh0OworCitzdGF0aWMgaW50IGNoZWNrX2ZyYW1lX2xlbmd0 aChpbnQgc3JhdGVfaHosIGludCBmcmFtZV91cykKK3sKKyAgICBpZiAoc3JhdGVfaHogIT0gIDgw MDAgJiYgc3JhdGVfaHogIT0gMTYwMDAgJiYgc3JhdGVfaHogIT0gMjQwMDAgJiYKKyAgICAgICAg c3JhdGVfaHogIT0gMzIwMDAgJiYgc3JhdGVfaHogIT0gNDgwMDAgJiYgc3JhdGVfaHogIT0gOTYw MDApCisgICAgICAgIHJldHVybiAtMTsKKworICAgIGlmIChmcmFtZV91cyAhPSAyNTAwICYmIGZy YW1lX3VzICE9ICA1MDAwICYmCisgICAgICAgIGZyYW1lX3VzICE9IDc1MDAgJiYgZnJhbWVfdXMg IT0gMTAwMDApCisgICAgICAgIHJldHVybiAtMTsKKworICAgIHJldHVybiAwOworfQorCitzdGF0 aWMgaW50IGxjM19yZWFkX3Byb2JlKGNvbnN0IEFWUHJvYmVEYXRhICpwKQoreworICAgIGludCBm cmFtZV91cywgc3JhdGVfaHo7CisKKyAgICBpZiAocC0+YnVmX3NpemUgPCAxMikKKyAgICAgICAg cmV0dXJuIDA7CisKKyAgICBpZiAoQVZfUkIxNihwLT5idWYgKyAwKSAhPSAweDFjY2MgfHwKKyAg ICAgICAgQVZfUkwxNihwLT5idWYgKyAyKSA8ICA5ICogc2l6ZW9mKHVpbnQxNl90KSkKKyAgICAg ICAgcmV0dXJuIDA7CisKKyAgICBzcmF0ZV9oeiA9IEFWX1JMMTYocC0+YnVmICsgNCkgKiAxMDA7 CisgICAgZnJhbWVfdXMgPSBBVl9STDE2KHAtPmJ1ZiArIDEwKSAqIDEwOworICAgIGlmIChjaGVj a19mcmFtZV9sZW5ndGgoc3JhdGVfaHosIGZyYW1lX3VzKSA8IDApCisgICAgICAgIHJldHVybiAw OworCisgICAgcmV0dXJuIEFWUFJPQkVfU0NPUkVfTUFYOworfQorCitzdGF0aWMgaW50IGxjM19y ZWFkX2hlYWRlcihBVkZvcm1hdENvbnRleHQgKnMpCit7CisgICAgTEMzRGVtdXhDb250ZXh0ICps YzMgPSBzLT5wcml2X2RhdGE7CisgICAgQVZTdHJlYW0gKnN0ID0gTlVMTDsKKyAgICB1aW50MTZf dCB0YWcsIGhkcl9zaXplOworICAgIHVpbnQzMl90IGxlbmd0aDsKKyAgICBpbnQgc3JhdGVfaHos IGZyYW1lX3VzLCBjaGFubmVscywgYml0X3JhdGU7CisgICAgaW50IGVwX21vZGUsIGhyX21vZGU7 CisgICAgaW50IG51bV9leHRyYV9wYXJhbXM7CisgICAgaW50IGRlbGF5LCByZXQ7CisKKyAgICB0 YWcgPSBhdmlvX3JiMTYocy0+cGIpOworICAgIGhkcl9zaXplID0gYXZpb19ybDE2KHMtPnBiKTsK KworICAgIGlmICh0YWcgIT0gMHgxY2NjIHx8IGhkcl9zaXplIDwgOSAqIHNpemVvZih1aW50MTZf dCkpCisgICAgICAgIHJldHVybiBBVkVSUk9SX0lOVkFMSUREQVRBOworCisgICAgbnVtX2V4dHJh X3BhcmFtcyA9IGhkcl9zaXplIC8gc2l6ZW9mKHVpbnQxNl90KSAtIDk7CisKKyAgICBzcmF0ZV9o eiA9IGF2aW9fcmwxNihzLT5wYikgKiAxMDA7CisgICAgYml0X3JhdGUgPSBhdmlvX3JsMTYocy0+ cGIpICogMTAwOworICAgIGNoYW5uZWxzID0gYXZpb19ybDE2KHMtPnBiKTsKKyAgICBmcmFtZV91 cyA9IGF2aW9fcmwxNihzLT5wYikgKiAxMDsKKyAgICBlcF9tb2RlICA9IGF2aW9fcmwxNihzLT5w YikgIT0gMDsKKyAgICBsZW5ndGggICA9IGF2aW9fcmwzMihzLT5wYik7CisgICAgaHJfbW9kZSAg PSBudW1fZXh0cmFfcGFyYW1zID49IDEgJiYgYXZpb19ybDE2KHMtPnBiKTsKKworICAgIGlmIChj aGVja19mcmFtZV9sZW5ndGgoc3JhdGVfaHosIGZyYW1lX3VzKSA8IDApIHsKKyAgICAgICAgYXZf bG9nKHMsIEFWX0xPR19FUlJPUiwgIkludmFsaWQgTEMzIHNhbXBsZSByYXRlOiAlZCBIeiwgIgor ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZnJhbWUgZHVyYXRpb246ICUuMWYgbXMu XG4iLAorICAgICAgICAgICAgICAgc3JhdGVfaHosIGZyYW1lX3VzIC8gMTAwMC5mKTsKKyAgICAg ICAgcmV0dXJuIEFWRVJST1JfSU5WQUxJRERBVEE7CisgICAgfQorCisgICAgc3QgPSBhdmZvcm1h dF9uZXdfc3RyZWFtKHMsIE5VTEwpOworICAgIGlmICghc3QpCisgICAgICAgIHJldHVybiBBVkVS Uk9SKEVOT01FTSk7CisKKyAgICBhdnByaXZfc2V0X3B0c19pbmZvKHN0LCA2NCwgMSwgc3JhdGVf aHopOworICAgIGF2cHJpdl91cGRhdGVfY3VyX2R0cyhzLCBzdCwgMCk7CisgICAgc3QtPmR1cmF0 aW9uID0gbGVuZ3RoOworCisgICAgc3QtPmNvZGVjcGFyLT5jb2RlY190eXBlID0gQVZNRURJQV9U WVBFX0FVRElPOworICAgIHN0LT5jb2RlY3Bhci0+Y29kZWNfaWQgPSBBVl9DT0RFQ19JRF9MQzM7 CisgICAgc3QtPmNvZGVjcGFyLT5zYW1wbGVfcmF0ZSA9IHNyYXRlX2h6OworICAgIHN0LT5jb2Rl Y3Bhci0+Yml0X3JhdGUgPSBiaXRfcmF0ZTsKKyAgICBzdC0+Y29kZWNwYXItPmNoX2xheW91dC5u Yl9jaGFubmVscyA9IGNoYW5uZWxzOworCisgICAgaWYgKChyZXQgPSBmZl9hbGxvY19leHRyYWRh dGEoc3QtPmNvZGVjcGFyLCA2KSkgPCAwKQorICAgICAgICByZXR1cm4gcmV0OworCisgICAgQVZf V0wxNihzdC0+Y29kZWNwYXItPmV4dHJhZGF0YSArIDAsIGZyYW1lX3VzIC8gMTApOworICAgIEFW X1dMMTYoc3QtPmNvZGVjcGFyLT5leHRyYWRhdGEgKyAyLCBlcF9tb2RlKTsKKyAgICBBVl9XTDE2 KHN0LT5jb2RlY3Bhci0+ZXh0cmFkYXRhICsgNCwgaHJfbW9kZSk7CisKKyAgICBsYzMtPmZyYW1l X3NhbXBsZXMgPSBhdl9yZXNjYWxlKGZyYW1lX3VzLCBzcmF0ZV9oeiwgMTAwMCoxMDAwKTsKKwor ICAgIGRlbGF5ID0gYXZfcmVzY2FsZShmcmFtZV91cyA9PSA3NTAwID8gNDAwMCA6IDI1MDAsIHNy YXRlX2h6LCAxMDAwKjEwMDApOworICAgIGxjMy0+ZW5kX2R0cyA9IGxlbmd0aCA/IGxlbmd0aCAr IGRlbGF5IDogLTE7CisKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBsYzNfcmVhZF9w YWNrZXQoQVZGb3JtYXRDb250ZXh0ICpzLCBBVlBhY2tldCAqcGt0KQoreworICAgIExDM0RlbXV4 Q29udGV4dCAqbGMzID0gcy0+cHJpdl9kYXRhOworICAgIEFWU3RyZWFtICpzdCA9IHMtPnN0cmVh bXNbMF07CisgICAgQVZJT0NvbnRleHQgKnBiID0gcy0+cGI7CisgICAgaW50NjRfdCBwb3MgPSBh dmlvX3RlbGwocGIpOworICAgIGludDY0X3QgcmVtYWluaW5nX3NhbXBsZXM7CisgICAgaW50IHJl dDsKKworICAgIHJldCA9IGF2X2dldF9wYWNrZXQocy0+cGIsIHBrdCwgYXZpb19ybDE2KHBiKSk7 CisgICAgaWYgKHJldCA8IDApCisgICAgICAgIHJldHVybiByZXQ7CisKKyAgICBwa3QtPnBvcyA9 IHBvczsKKworICAgIHJlbWFpbmluZ19zYW1wbGVzID0gbGMzLT5lbmRfZHRzIDwgMCA/IGxjMy0+ ZnJhbWVfc2FtcGxlcyA6CisgICAgICAgICAgICAgICAgICAgICAgICBGRk1BWChsYzMtPmVuZF9k dHMgLSBmZnN0cmVhbShzdCktPmN1cl9kdHMsIDApOworICAgIHBrdC0+ZHVyYXRpb24gPSBGRk1J TihsYzMtPmZyYW1lX3NhbXBsZXMsIHJlbWFpbmluZ19zYW1wbGVzKTsKKworICAgIHJldHVybiAw OworfQorCitzdGF0aWMgYXZfY29sZCBpbnQgbGMzX211eGVyX2luaXQoQVZGb3JtYXRDb250ZXh0 ICpzKQoreworICAgIGlmIChzLT5uYl9zdHJlYW1zICE9IDEpIHsKKyAgICAgICAgYXZfbG9nKHMs IEFWX0xPR19FUlJPUiwgIlRoaXMgbXV4ZXIgb25seSBzdXBwb3J0cyBhIHNpbmdsZSBzdHJlYW0u XG4iKTsKKyAgICAgICAgcmV0dXJuIEFWRVJST1IoRUlOVkFMKTsKKyAgICB9CisKKyAgICByZXR1 cm4gMDsKK30KKworc3RhdGljIGludCBsYzNfd3JpdGVfaGVhZGVyKEFWRm9ybWF0Q29udGV4dCAq cykKK3sKKyAgICBBVlN0cmVhbSAqc3QgPSBzLT5zdHJlYW1zWzBdOworICAgIGludCBjaGFubmVs cyA9IHN0LT5jb2RlY3Bhci0+Y2hfbGF5b3V0Lm5iX2NoYW5uZWxzOworICAgIGludCBzcmF0ZV9o eiA9IHN0LT5jb2RlY3Bhci0+c2FtcGxlX3JhdGU7CisgICAgaW50IGJpdF9yYXRlID0gc3QtPmNv ZGVjcGFyLT5iaXRfcmF0ZTsKKyAgICBpbnQgZnJhbWVfdXMsIGVwX21vZGUsIGhyX21vZGU7Cisg ICAgdWludDMyX3QgbmJfc2FtcGxlcyA9IGF2X3Jlc2NhbGVfcSgKKyAgICAgICAgc3QtPmR1cmF0 aW9uLCBzdC0+dGltZV9iYXNlLCAoQVZSYXRpb25hbCl7IDEsIHNyYXRlX2h6IH0pOworCisgICAg aWYgKHN0LT5jb2RlY3Bhci0+ZXh0cmFkYXRhX3NpemUgPCA2KQorICAgICAgICByZXR1cm4gQVZF UlJPUl9JTlZBTElEREFUQTsKKworICAgIGZyYW1lX3VzID0gQVZfUkwxNihzdC0+Y29kZWNwYXIt PmV4dHJhZGF0YSArIDApICogMTA7CisgICAgZXBfbW9kZSA9IEFWX1JMMTYoc3QtPmNvZGVjcGFy LT5leHRyYWRhdGEgKyAyKSAhPSAwOworICAgIGhyX21vZGUgPSBBVl9STDE2KHN0LT5jb2RlY3Bh ci0+ZXh0cmFkYXRhICsgNCkgIT0gMDsKKworICAgIGlmIChjaGVja19mcmFtZV9sZW5ndGgoc3Jh dGVfaHosIGZyYW1lX3VzKSA8IDApIHsKKyAgICAgICAgYXZfbG9nKHMsIEFWX0xPR19FUlJPUiwg IkludmFsaWQgTEMzIHNhbXBsZSByYXRlOiAlZCBIeiwgIgorICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAiZnJhbWUgZHVyYXRpb246ICUuMWYgbXMuXG4iLAorICAgICAgICAgICAgICAg c3JhdGVfaHosIGZyYW1lX3VzIC8gMTAwMC5mKTsKKyAgICAgICAgcmV0dXJuIEFWRVJST1JfSU5W QUxJRERBVEE7CisgICAgfQorCisgICAgYXZpb193YjE2KHMtPnBiLCAweDFjY2MpOworICAgIGF2 aW9fd2wxNihzLT5wYiwgKDkgKyBocl9tb2RlKSAqIHNpemVvZih1aW50MTZfdCkpOworICAgIGF2 aW9fd2wxNihzLT5wYiwgc3JhdGVfaHogLyAxMDApOworICAgIGF2aW9fd2wxNihzLT5wYiwgYml0 X3JhdGUgLyAxMDApOworICAgIGF2aW9fd2wxNihzLT5wYiwgY2hhbm5lbHMpOworICAgIGF2aW9f d2wxNihzLT5wYiwgZnJhbWVfdXMgLyAxMCk7CisgICAgYXZpb193bDE2KHMtPnBiLCBlcF9tb2Rl KTsKKyAgICBhdmlvX3dsMzIocy0+cGIsIG5iX3NhbXBsZXMpOworICAgIGlmIChocl9tb2RlKQor ICAgICAgICBhdmlvX3dsMTYocy0+cGIsIGhyX21vZGUpOworCisgICAgcmV0dXJuIDA7Cit9CisK K3N0YXRpYyBpbnQgbGMzX3dyaXRlX3BhY2tldChBVkZvcm1hdENvbnRleHQgKnMsIEFWUGFja2V0 ICpwa3QpCit7CisgICAgYXZpb193bDE2KHMtPnBiLCBwa3QtPnNpemUpOworICAgIGF2aW9fd3Jp dGUocy0+cGIsIHBrdC0+ZGF0YSwgcGt0LT5zaXplKTsKKyAgICByZXR1cm4gMDsKK30KKworI2lm IENPTkZJR19MQzNfREVNVVhFUgorY29uc3QgRkZJbnB1dEZvcm1hdCBmZl9sYzNfZGVtdXhlciA9 IHsKKyAgICAucC5uYW1lICAgICAgICAgPSAibGMzIiwKKyAgICAucC5sb25nX25hbWUgICAgPSBO VUxMX0lGX0NPTkZJR19TTUFMTCgiTEMzIChMb3cgQ29tcGxleGl0eSBDb21tdW5pY2F0aW9uIENv ZGVjKSIpLAorICAgIC5wLmV4dGVuc2lvbnMgICA9ICJsYzMiLAorICAgIC5wLmZsYWdzICAgICAg ICA9IEFWRk1UX0dFTkVSSUNfSU5ERVgsCisgICAgLnByaXZfZGF0YV9zaXplID0gc2l6ZW9mKExD M0RlbXV4Q29udGV4dCksCisgICAgLnJlYWRfcHJvYmUgICAgID0gbGMzX3JlYWRfcHJvYmUsCisg ICAgLnJlYWRfaGVhZGVyICAgID0gbGMzX3JlYWRfaGVhZGVyLAorICAgIC5yZWFkX3BhY2tldCAg ICA9IGxjM19yZWFkX3BhY2tldCwKK307CisjZW5kaWYKKworI2lmIENPTkZJR19MQzNfTVVYRVIK K2NvbnN0IEZGT3V0cHV0Rm9ybWF0IGZmX2xjM19tdXhlciA9IHsKKyAgICAucC5uYW1lICAgICAg ICA9ICJsYzMiLAorICAgIC5wLmxvbmdfbmFtZSAgID0gTlVMTF9JRl9DT05GSUdfU01BTEwoIkxD MyAoTG93IENvbXBsZXhpdHkgQ29tbXVuaWNhdGlvbiBDb2RlYykiKSwKKyAgICAucC5leHRlbnNp b25zICA9ICJsYzMiLAorICAgIC5wLmF1ZGlvX2NvZGVjID0gQVZfQ09ERUNfSURfTEMzLAorICAg IC5wLnZpZGVvX2NvZGVjID0gQVZfQ09ERUNfSURfTk9ORSwKKyAgICAucC5mbGFncyAgICAgICA9 IEFWRk1UX05PVElNRVNUQU1QUywKKyAgICAuaW5pdCAgICAgICAgICA9IGxjM19tdXhlcl9pbml0 LAorICAgIC53cml0ZV9oZWFkZXIgID0gbGMzX3dyaXRlX2hlYWRlciwKKyAgICAud3JpdGVfcGFj a2V0ICA9IGxjM193cml0ZV9wYWNrZXQsCit9OworI2VuZGlmCi0tIAoyLjQ0LjAuNjgzLmc3OTYx YzgzOGFjLWdvb2cKCg== --000000000000b434f90615c18d50 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". --000000000000b434f90615c18d50--