From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH 81/87] avcodec: Move all AVCodecParser.split functions to remove_extradata_bsf Date: Thu, 12 May 2022 17:43:57 +0200 Message-ID: <DB6PR0101MB221432CF063B4FDBB71402448FCB9@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com> (raw) In-Reply-To: <a6188d2f11b67e45b98f7954f408901269471faa.camel@jetheaddev.com> John Stebbins: > Hi all, > > I know this happened quite some time ago, but we just noticed the > change. > > This effectively disables the public API AVCodecParser.split for these > codecs. HandBrake uses this API to split out extradata for a few > codecs. Any chance we can bring these back? Otherwise, we will have to > replicate this code in HandBrake 😕️ > I know that AVCodecParser was lacking the typical public-private demarkation, but you are actually not supposed to call these function pointers directly. In fact, it is not publically documented at all what AVCodecParser.split does. Anyway, use the extract_extradata BSF. It is the intended replacement for this feature. It is also what avformat_find_stream_info() uses to extract extradata in case the container doesn't provide any. > On Mon, 2021-04-19 at 11:10 -0300, James Almer wrote: >> From: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> >> >> The remove_extradata bsf is the only user of these functions. >> >> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> >> --- >> libavcodec/Makefile | 4 +- >> libavcodec/av1_parser.c | 25 +--- >> libavcodec/avs2_parser.c | 1 - >> libavcodec/avs3_parser.c | 1 - >> libavcodec/cavs_parser.c | 1 - >> libavcodec/h264_parser.c | 38 ------ >> libavcodec/hevc_parser.c | 34 ----- >> libavcodec/mpeg4video_parser.c | 1 - >> libavcodec/mpegvideo_parser.c | 18 --- >> libavcodec/parser.c | 14 --- >> libavcodec/remove_extradata_bsf.c | 201 +++++++++++++++++++++++++--- >> -- >> libavcodec/vc1_parser.c | 19 --- >> 12 files changed, 171 insertions(+), 186 deletions(-) >> >> diff --git a/libavcodec/Makefile b/libavcodec/Makefile >> index a640c548e5..c19a3cb60d 100644 >> --- a/libavcodec/Makefile >> +++ b/libavcodec/Makefile >> @@ -1075,7 +1075,7 @@ OBJS-$(CONFIG_AAC_PARSER) += >> aac_parser.o aac_ac3_parser.o \ >> mpeg4audio.o >> OBJS-$(CONFIG_AC3_PARSER) += ac3tab.o aac_ac3_parser.o >> OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o >> -OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o >> +OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o >> OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o >> OBJS-$(CONFIG_AVS3_PARSER) += avs3_parser.o >> OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o >> @@ -1159,7 +1159,7 @@ OBJS-$(CONFIG_NULL_BSF) += >> null_bsf.o >> OBJS-$(CONFIG_OPUS_METADATA_BSF) += opus_metadata_bsf.o >> OBJS-$(CONFIG_PCM_RECHUNK_BSF) += pcm_rechunk_bsf.o >> OBJS-$(CONFIG_PRORES_METADATA_BSF) += prores_metadata_bsf.o >> -OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o >> +OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o >> av1_parse.o >> OBJS-$(CONFIG_SETTS_BSF) += setts_bsf.o >> OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o >> OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o >> diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c >> index 578f5293c8..b6c8004ee3 100644 >> --- a/libavcodec/av1_parser.c >> +++ b/libavcodec/av1_parser.c >> @@ -20,7 +20,7 @@ >> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA >> 02110-1301 USA >> */ >> >> -#include "av1_parse.h" >> +#include "libavutil/avassert.h" >> #include "cbs.h" >> #include "cbs_av1.h" >> #include "internal.h" >> @@ -205,33 +205,10 @@ static void >> av1_parser_close(AVCodecParserContext *ctx) >> ff_cbs_close(&s->cbc); >> } >> >> -static int av1_parser_split(AVCodecContext *avctx, >> - const uint8_t *buf, int buf_size) >> -{ >> - AV1OBU obu; >> - const uint8_t *ptr = buf, *end = buf + buf_size; >> - >> - while (ptr < end) { >> - int len = ff_av1_extract_obu(&obu, ptr, buf_size, avctx); >> - if (len < 0) >> - break; >> - >> - if (obu.type == AV1_OBU_FRAME_HEADER || >> - obu.type == AV1_OBU_FRAME) { >> - return ptr - buf; >> - } >> - ptr += len; >> - buf_size -= len; >> - } >> - >> - return 0; >> -} >> - >> const AVCodecParser ff_av1_parser = { >> .codec_ids = { AV_CODEC_ID_AV1 }, >> .priv_data_size = sizeof(AV1ParseContext), >> .parser_init = av1_parser_init, >> .parser_close = av1_parser_close, >> .parser_parse = av1_parser_parse, >> - .split = av1_parser_split, >> }; >> diff --git a/libavcodec/avs2_parser.c b/libavcodec/avs2_parser.c >> index 059faf77c5..b7d5d7774e 100644 >> --- a/libavcodec/avs2_parser.c >> +++ b/libavcodec/avs2_parser.c >> @@ -91,5 +91,4 @@ const AVCodecParser ff_avs2_parser = { >> .priv_data_size = sizeof(ParseContext), >> .parser_parse = avs2_parse, >> .parser_close = ff_parse_close, >> - .split = ff_mpeg4video_split, >> }; >> diff --git a/libavcodec/avs3_parser.c b/libavcodec/avs3_parser.c >> index b0e720a844..1a05ea042e 100644 >> --- a/libavcodec/avs3_parser.c >> +++ b/libavcodec/avs3_parser.c >> @@ -175,5 +175,4 @@ const AVCodecParser ff_avs3_parser = { >> .priv_data_size = sizeof(ParseContext), >> .parser_parse = avs3_parse, >> .parser_close = ff_parse_close, >> - .split = ff_mpeg4video_split, >> }; >> diff --git a/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c >> index 20adca1dbc..03f392c2e5 100644 >> --- a/libavcodec/cavs_parser.c >> +++ b/libavcodec/cavs_parser.c >> @@ -102,5 +102,4 @@ const AVCodecParser ff_cavsvideo_parser = { >> .priv_data_size = sizeof(ParseContext), >> .parser_parse = cavsvideo_parse, >> .parser_close = ff_parse_close, >> - .split = ff_mpeg4video_split, >> }; >> diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c >> index 880ccb50fa..d3c56cc188 100644 >> --- a/libavcodec/h264_parser.c >> +++ b/libavcodec/h264_parser.c >> @@ -644,43 +644,6 @@ static int h264_parse(AVCodecParserContext *s, >> return next; >> } >> >> -static int h264_split(AVCodecContext *avctx, >> - const uint8_t *buf, int buf_size) >> -{ >> - uint32_t state = -1; >> - int has_sps = 0; >> - int has_pps = 0; >> - const uint8_t *ptr = buf, *end = buf + buf_size; >> - int nalu_type; >> - >> - while (ptr < end) { >> - ptr = avpriv_find_start_code(ptr, end, &state); >> - if ((state & 0xFFFFFF00) != 0x100) >> - break; >> - nalu_type = state & 0x1F; >> - if (nalu_type == H264_NAL_SPS) { >> - has_sps = 1; >> - } else if (nalu_type == H264_NAL_PPS) >> - has_pps = 1; >> - /* else if (nalu_type == 0x01 || >> - * nalu_type == 0x02 || >> - * nalu_type == 0x05) { >> - * } >> - */ >> - else if ((nalu_type != H264_NAL_SEI || has_pps) && >> - nalu_type != H264_NAL_AUD && nalu_type != >> H264_NAL_SPS_EXT && >> - nalu_type != 0x0f) { >> - if (has_sps) { >> - while (ptr - 4 > buf && ptr[-5] == 0) >> - ptr--; >> - return ptr - 4 - buf; >> - } >> - } >> - } >> - >> - return 0; >> -} >> - >> static void h264_close(AVCodecParserContext *s) >> { >> H264ParseContext *p = s->priv_data; >> @@ -708,5 +671,4 @@ const AVCodecParser ff_h264_parser = { >> .parser_init = init, >> .parser_parse = h264_parse, >> .parser_close = h264_close, >> - .split = h264_split, >> }; >> diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c >> index 320d4eb562..c944a6aacd 100644 >> --- a/libavcodec/hevc_parser.c >> +++ b/libavcodec/hevc_parser.c >> @@ -336,39 +336,6 @@ static int hevc_parse(AVCodecParserContext *s, >> AVCodecContext *avctx, >> return next; >> } >> >> -// Split after the parameter sets at the beginning of the stream if >> they exist. >> -static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int >> buf_size) >> -{ >> - const uint8_t *ptr = buf, *end = buf + buf_size; >> - uint32_t state = -1; >> - int has_vps = 0; >> - int has_sps = 0; >> - int has_pps = 0; >> - int nut; >> - >> - while (ptr < end) { >> - ptr = avpriv_find_start_code(ptr, end, &state); >> - if ((state >> 8) != START_CODE) >> - break; >> - nut = (state >> 1) & 0x3F; >> - if (nut == HEVC_NAL_VPS) >> - has_vps = 1; >> - else if (nut == HEVC_NAL_SPS) >> - has_sps = 1; >> - else if (nut == HEVC_NAL_PPS) >> - has_pps = 1; >> - else if ((nut != HEVC_NAL_SEI_PREFIX || has_pps) && >> - nut != HEVC_NAL_AUD) { >> - if (has_vps && has_sps) { >> - while (ptr - 4 > buf && ptr[-5] == 0) >> - ptr--; >> - return ptr - 4 - buf; >> - } >> - } >> - } >> - return 0; >> -} >> - >> static void hevc_parser_close(AVCodecParserContext *s) >> { >> HEVCParserContext *ctx = s->priv_data; >> @@ -385,5 +352,4 @@ const AVCodecParser ff_hevc_parser = { >> .priv_data_size = sizeof(HEVCParserContext), >> .parser_parse = hevc_parse, >> .parser_close = hevc_parser_close, >> - .split = hevc_split, >> }; >> diff --git a/libavcodec/mpeg4video_parser.c >> b/libavcodec/mpeg4video_parser.c >> index afa10c7727..1b0e2555da 100644 >> --- a/libavcodec/mpeg4video_parser.c >> +++ b/libavcodec/mpeg4video_parser.c >> @@ -159,5 +159,4 @@ const AVCodecParser ff_mpeg4video_parser = { >> .parser_init = mpeg4video_parse_init, >> .parser_parse = mpeg4video_parse, >> .parser_close = ff_parse_close, >> - .split = ff_mpeg4video_split, >> }; >> diff --git a/libavcodec/mpegvideo_parser.c >> b/libavcodec/mpegvideo_parser.c >> index 4e4f569b13..7864224643 100644 >> --- a/libavcodec/mpegvideo_parser.c >> +++ b/libavcodec/mpegvideo_parser.c >> @@ -213,23 +213,6 @@ static int mpegvideo_parse(AVCodecParserContext >> *s, >> return next; >> } >> >> -static int mpegvideo_split(AVCodecContext *avctx, >> - const uint8_t *buf, int buf_size) >> -{ >> - int i; >> - uint32_t state= -1; >> - int found=0; >> - >> - for(i=0; i<buf_size; i++){ >> - state= (state<<8) | buf[i]; >> - if(state == 0x1B3){ >> - found=1; >> - }else if(found && state != 0x1B5 && state < 0x200 && state >>> = 0x100) >> - return i-3; >> - } >> - return 0; >> -} >> - >> static int mpegvideo_parse_init(AVCodecParserContext *s) >> { >> s->pict_type = AV_PICTURE_TYPE_NONE; // first frame might be >> partial >> @@ -242,5 +225,4 @@ const AVCodecParser ff_mpegvideo_parser = { >> .parser_init = mpegvideo_parse_init, >> .parser_parse = mpegvideo_parse, >> .parser_close = ff_parse_close, >> - .split = mpegvideo_split, >> }; >> diff --git a/libavcodec/parser.c b/libavcodec/parser.c >> index f81a62d592..fc57246965 100644 >> --- a/libavcodec/parser.c >> +++ b/libavcodec/parser.c >> @@ -285,17 +285,3 @@ void ff_parse_close(AVCodecParserContext *s) >> >> av_freep(&pc->buffer); >> } >> - >> -int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, >> int buf_size) >> -{ >> - uint32_t state = -1; >> - const uint8_t *ptr = buf, *end = buf + buf_size; >> - >> - while (ptr < end) { >> - ptr = avpriv_find_start_code(ptr, end, &state); >> - if (state == 0x1B3 || state == 0x1B6) >> - return ptr - 4 - buf; >> - } >> - >> - return 0; >> -} >> diff --git a/libavcodec/remove_extradata_bsf.c >> b/libavcodec/remove_extradata_bsf.c >> index 5783b075f0..1d5f193f89 100644 >> --- a/libavcodec/remove_extradata_bsf.c >> +++ b/libavcodec/remove_extradata_bsf.c >> @@ -21,9 +21,13 @@ >> #include "libavutil/log.h" >> #include "libavutil/opt.h" >> >> -#include "avcodec.h" >> +#include "av1_parse.h" >> #include "bsf.h" >> #include "bsf_internal.h" >> +#include "h264.h" >> +#include "hevc.h" >> +#include "internal.h" >> +#include "vc1_common.h" >> >> enum RemoveFreq { >> REMOVE_FREQ_KEYFRAME, >> @@ -31,63 +35,196 @@ enum RemoveFreq { >> REMOVE_FREQ_NONKEYFRAME, >> }; >> >> +#define START_CODE 0x000001 >> + >> typedef struct RemoveExtradataContext { >> const AVClass *class; >> int freq; >> - >> - AVCodecParserContext *parser; >> - AVCodecContext *avctx; >> } RemoveExtradataContext; >> >> -static int remove_extradata(AVBSFContext *ctx, AVPacket *pkt) >> +static int av1_split(const uint8_t *buf, int buf_size, void *logctx) >> { >> - RemoveExtradataContext *s = ctx->priv_data; >> + AV1OBU obu; >> + const uint8_t *ptr = buf, *end = buf + buf_size; >> >> - int ret; >> + while (ptr < end) { >> + int len = ff_av1_extract_obu(&obu, ptr, buf_size, logctx); >> + if (len < 0) >> + break; >> >> - ret = ff_bsf_get_packet_ref(ctx, pkt); >> - if (ret < 0) >> - return ret; >> + if (obu.type == AV1_OBU_FRAME_HEADER || >> + obu.type == AV1_OBU_FRAME) { >> + return ptr - buf; >> + } >> + ptr += len; >> + buf_size -= len; >> + } >> + >> + return 0; >> +} >> >> - if (s->parser && s->parser->parser->split) { >> - if (s->freq == REMOVE_FREQ_ALL || >> - (s->freq == REMOVE_FREQ_NONKEYFRAME && !(pkt->flags & >> AV_PKT_FLAG_KEY)) || >> - (s->freq == REMOVE_FREQ_KEYFRAME && pkt->flags & >> AV_PKT_FLAG_KEY)) { >> - int i = s->parser->parser->split(s->avctx, pkt->data, >> pkt->size); >> - pkt->data += i; >> - pkt->size -= i; >> +static int h264_split(const uint8_t *buf, int buf_size) >> +{ >> + const uint8_t *ptr = buf, *end = buf + buf_size; >> + uint32_t state = -1; >> + int has_sps = 0; >> + int has_pps = 0; >> + int nalu_type; >> + >> + while (ptr < end) { >> + ptr = avpriv_find_start_code(ptr, end, &state); >> + if ((state & 0xFFFFFF00) != 0x100) >> + break; >> + nalu_type = state & 0x1F; >> + if (nalu_type == H264_NAL_SPS) { >> + has_sps = 1; >> + } else if (nalu_type == H264_NAL_PPS) >> + has_pps = 1; >> + /* else if (nalu_type == 0x01 || >> + * nalu_type == 0x02 || >> + * nalu_type == 0x05) { >> + * } >> + */ >> + else if ((nalu_type != H264_NAL_SEI || has_pps) && >> + nalu_type != H264_NAL_AUD && nalu_type != >> H264_NAL_SPS_EXT && >> + nalu_type != 0x0f) { >> + if (has_sps) { >> + while (ptr - 4 > buf && ptr[-5] == 0) >> + ptr--; >> + return ptr - 4 - buf; >> + } >> } >> } >> >> return 0; >> } >> >> -static int remove_extradata_init(AVBSFContext *ctx) >> +// Split after the parameter sets at the beginning of the stream if >> they exist. >> +static int hevc_split(const uint8_t *buf, int buf_size) >> { >> - RemoveExtradataContext *s = ctx->priv_data; >> - int ret; >> + const uint8_t *ptr = buf, *end = buf + buf_size; >> + uint32_t state = -1; >> + int has_vps = 0; >> + int has_sps = 0; >> + int has_pps = 0; >> + int nut; >> + >> + while (ptr < end) { >> + ptr = avpriv_find_start_code(ptr, end, &state); >> + if ((state >> 8) != START_CODE) >> + break; >> + nut = (state >> 1) & 0x3F; >> + if (nut == HEVC_NAL_VPS) >> + has_vps = 1; >> + else if (nut == HEVC_NAL_SPS) >> + has_sps = 1; >> + else if (nut == HEVC_NAL_PPS) >> + has_pps = 1; >> + else if ((nut != HEVC_NAL_SEI_PREFIX || has_pps) && >> + nut != HEVC_NAL_AUD) { >> + if (has_vps && has_sps) { >> + while (ptr - 4 > buf && ptr[-5] == 0) >> + ptr--; >> + return ptr - 4 - buf; >> + } >> + } >> + } >> + return 0; >> +} >> >> - s->parser = av_parser_init(ctx->par_in->codec_id); >> +static int mpegvideo_split(const uint8_t *buf, int buf_size) >> +{ >> + uint32_t state = -1; >> + int found = 0; >> + >> + for (int i = 0; i < buf_size; i++) { >> + state = (state << 8) | buf[i]; >> + if (state == 0x1B3) { >> + found = 1; >> + } else if (found && state != 0x1B5 && state < 0x200 && state >>> = 0x100) >> + return i - 3; >> + } >> + return 0; >> +} >> >> - if (s->parser) { >> - s->avctx = avcodec_alloc_context3(NULL); >> - if (!s->avctx) >> - return AVERROR(ENOMEM); >> +static int mpeg4video_split(const uint8_t *buf, int buf_size) >> +{ >> + const uint8_t *ptr = buf, *end = buf + buf_size; >> + uint32_t state = -1; >> >> - ret = avcodec_parameters_to_context(s->avctx, ctx->par_in); >> - if (ret < 0) >> - return ret; >> + while (ptr < end) { >> + ptr = avpriv_find_start_code(ptr, end, &state); >> + if (state == 0x1B3 || state == 0x1B6) >> + return ptr - 4 - buf; >> } >> >> return 0; >> } >> >> -static void remove_extradata_close(AVBSFContext *ctx) >> +static int vc1_split(const uint8_t *buf, int buf_size) >> +{ >> + const uint8_t *ptr = buf, *end = buf + buf_size; >> + uint32_t state = -1; >> + int charged = 0; >> + >> + while (ptr < end) { >> + ptr = avpriv_find_start_code(ptr, end, &state); >> + if (state == VC1_CODE_SEQHDR || state == >> VC1_CODE_ENTRYPOINT) { >> + charged = 1; >> + } else if (charged && IS_MARKER(state)) >> + return ptr - 4 - buf; >> + } >> + >> + return 0; >> +} >> + >> +static int remove_extradata(AVBSFContext *ctx, AVPacket *pkt) >> { >> RemoveExtradataContext *s = ctx->priv_data; >> >> - avcodec_free_context(&s->avctx); >> - av_parser_close(s->parser); >> + int ret; >> + >> + ret = ff_bsf_get_packet_ref(ctx, pkt); >> + if (ret < 0) >> + return ret; >> + >> + if (s->freq == REMOVE_FREQ_ALL || >> + (s->freq == REMOVE_FREQ_NONKEYFRAME && !(pkt->flags & >> AV_PKT_FLAG_KEY)) || >> + (s->freq == REMOVE_FREQ_KEYFRAME && pkt->flags & >> AV_PKT_FLAG_KEY)) { >> + int i; >> + >> + switch (ctx->par_in->codec_id) { >> + case AV_CODEC_ID_AV1: >> + i = av1_split(pkt->data, pkt->size, ctx); >> + break; >> + case AV_CODEC_ID_AVS2: >> + case AV_CODEC_ID_AVS3: >> + case AV_CODEC_ID_CAVS: >> + case AV_CODEC_ID_MPEG4: >> + i = mpeg4video_split(pkt->data, pkt->size); >> + break; >> + case AV_CODEC_ID_H264: >> + i = h264_split(pkt->data, pkt->size); >> + break; >> + case AV_CODEC_ID_HEVC: >> + i = hevc_split(pkt->data, pkt->size); >> + break; >> + case AV_CODEC_ID_MPEG1VIDEO: >> + case AV_CODEC_ID_MPEG2VIDEO: >> + i = mpegvideo_split(pkt->data, pkt->size); >> + break; >> + case AV_CODEC_ID_VC1: >> + i = vc1_split(pkt->data, pkt->size); >> + break; >> + default: >> + i = 0; >> + } >> + >> + pkt->data += i; >> + pkt->size -= i; >> + } >> + >> + return 0; >> } >> >> #define OFFSET(x) offsetof(RemoveExtradataContext, x) >> @@ -112,7 +249,5 @@ const AVBitStreamFilter ff_remove_extradata_bsf = >> { >> .name = "remove_extra", >> .priv_data_size = sizeof(RemoveExtradataContext), >> .priv_class = &remove_extradata_class, >> - .init = remove_extradata_init, >> - .close = remove_extradata_close, >> .filter = remove_extradata, >> }; >> diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c >> index 0f17d299e1..00896ddb09 100644 >> --- a/libavcodec/vc1_parser.c >> +++ b/libavcodec/vc1_parser.c >> @@ -256,24 +256,6 @@ static int vc1_parse(AVCodecParserContext *s, >> return next; >> } >> >> -static int vc1_split(AVCodecContext *avctx, >> - const uint8_t *buf, int buf_size) >> -{ >> - uint32_t state = -1; >> - int charged = 0; >> - const uint8_t *ptr = buf, *end = buf + buf_size; >> - >> - while (ptr < end) { >> - ptr = avpriv_find_start_code(ptr, end, &state); >> - if (state == VC1_CODE_SEQHDR || state == >> VC1_CODE_ENTRYPOINT) { >> - charged = 1; >> - } else if (charged && IS_MARKER(state)) >> - return ptr - 4 - buf; >> - } >> - >> - return 0; >> -} >> - >> static av_cold int vc1_parse_init(AVCodecParserContext *s) >> { >> VC1ParseContext *vpc = s->priv_data; >> @@ -293,5 +275,4 @@ const AVCodecParser ff_vc1_parser = { >> .parser_init = vc1_parse_init, >> .parser_parse = vc1_parse, >> .parser_close = ff_parse_close, >> - .split = vc1_split, >> }; > _______________________________________________ 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".
next prev parent reply other threads:[~2022-05-12 15:44 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <20210419141024.8174-1-jamrial@gmail.com> [not found] ` <20210419141024.8174-82-jamrial@gmail.com> 2022-05-12 15:14 ` John Stebbins 2022-05-12 15:43 ` Andreas Rheinhardt [this message] 2022-05-12 15:48 ` John Stebbins
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=DB6PR0101MB221432CF063B4FDBB71402448FCB9@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com \ --to=andreas.rheinhardt@outlook.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git