From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Subject: [FFmpeg-devel] [PATCH 06/20] avformat/matroskdec: Factor audio parsing out of matroska_parse_tracks() Date: Mon, 4 Sep 2023 13:27:45 +0200 Message-ID: <AS8P250MB074465384F786A81C277C5688FE9A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw) In-Reply-To: <AS8P250MB0744314AD7A516CFC71F61BF8FE9A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> More exactly, factor codec-specific audio parsing out of matroska_parse_tracks(). This is intended to improve readability. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavformat/matroskadec.c | 424 ++++++++++++++++++++++---------------- 1 file changed, 243 insertions(+), 181 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index e1524a5943..8846e9358d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2501,9 +2501,241 @@ static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID * return 0; } +/* An enum with potential return values of the functions for parsing a track. + * Apart from that all these functions can also indicate ordinary errors via + * negative return values. */ +enum { + SKIP_TRACK = 1, +}; + #define AAC_MAX_EXTRADATA_SIZE 5 #define TTA_EXTRADATA_SIZE 22 #define WAVPACK_EXTRADATA_SIZE 2 +/* Performs the codec-specific part of parsing an audio track. */ +static int mka_parse_audio_codec(MatroskaTrack *track, AVCodecParameters *par, + const MatroskaDemuxContext *matroska, + AVFormatContext *s, int *extradata_offset) +{ + uint8_t extradata[FFMAX3(AAC_MAX_EXTRADATA_SIZE, + TTA_EXTRADATA_SIZE, + WAVPACK_EXTRADATA_SIZE)]; + int extradata_size = 0; // > 0 means that the extradata buffer is used + int ret; + + if (!strcmp(track->codec_id, "A_MS/ACM") && + track->codec_priv.size >= 14 && + track->codec_priv.data) { + FFIOContext b; + int ret; + ffio_init_context(&b, track->codec_priv.data, + track->codec_priv.size, + 0, NULL, NULL, NULL, NULL); + ret = ff_get_wav_header(s, &b.pub, par, + track->codec_priv.size, 0); + if (ret < 0) + return ret; + *extradata_offset = FFMIN(track->codec_priv.size, 18); + return 0; + } else if (!strcmp(track->codec_id, "A_QUICKTIME") + /* Normally 36, but allow noncompliant private data */ + && (track->codec_priv.size >= 32) + && (track->codec_priv.data)) { + enum AVCodecID codec_id; + uint32_t fourcc; + uint16_t sample_size; + int ret = get_qt_codec(track, &fourcc, &codec_id); + if (ret < 0) + return ret; + sample_size = AV_RB16(track->codec_priv.data + 26); + if (fourcc == 0) { + if (sample_size == 8) { + fourcc = MKTAG('r','a','w',' '); + codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); + } else if (sample_size == 16) { + fourcc = MKTAG('t','w','o','s'); + codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); + } + } + if ((fourcc == MKTAG('t','w','o','s') || + fourcc == MKTAG('s','o','w','t')) && + sample_size == 8) + codec_id = AV_CODEC_ID_PCM_S8; + par->codec_id = codec_id; + par->codec_tag = fourcc; + return 0; + } + + switch (par->codec_id) { + case AV_CODEC_ID_PCM_S16BE: + switch (track->audio.bitdepth) { + case 8: + par->codec_id = AV_CODEC_ID_PCM_U8; + break; + case 24: + par->codec_id = AV_CODEC_ID_PCM_S24BE; + break; + case 32: + par->codec_id = AV_CODEC_ID_PCM_S32BE; + break; + } + break; + case AV_CODEC_ID_PCM_S16LE: + switch (track->audio.bitdepth) { + case 8: + par->codec_id = AV_CODEC_ID_PCM_U8; + break; + case 24: + par->codec_id = AV_CODEC_ID_PCM_S24LE; + break; + case 32: + par->codec_id = AV_CODEC_ID_PCM_S32LE; + break; + } + break; + case AV_CODEC_ID_PCM_F32LE: + if (track->audio.bitdepth == 64) + par->codec_id = AV_CODEC_ID_PCM_F64LE; + break; + case AV_CODEC_ID_AAC: + if (!track->codec_priv.size) { + int profile = matroska_aac_profile(track->codec_id); + int sri = matroska_aac_sri(track->audio.samplerate); + + extradata[0] = (profile << 3) | ((sri & 0x0E) >> 1); + extradata[1] = ((sri & 0x01) << 7) | (track->audio.channels << 3); + if (strstr(track->codec_id, "SBR")) { + sri = matroska_aac_sri(track->audio.out_samplerate); + extradata[2] = 0x56; + extradata[3] = 0xE5; + extradata[4] = 0x80 | (sri << 3); + extradata_size = 5; + } else + extradata_size = 2; + } + break; + case AV_CODEC_ID_ALAC: + if (track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - AV_INPUT_BUFFER_PADDING_SIZE) { + /* Only ALAC's magic cookie is stored in Matroska's track headers. + * Create the "atom size", "tag", and "tag version" fields the + * decoder expects manually. */ + ret = ff_alloc_extradata(par, 12 + track->codec_priv.size); + if (ret < 0) + return ret; + AV_WB32(par->extradata, par->extradata_size); + AV_WB32(&par->extradata[4], MKBETAG('a', 'l', 'a', 'c')); + AV_WB32(&par->extradata[8], 0); + memcpy(&par->extradata[12], track->codec_priv.data, + track->codec_priv.size); + } + break; + case AV_CODEC_ID_TTA: + { + uint8_t *ptr; + if (track->audio.channels > UINT16_MAX || + track->audio.bitdepth > UINT16_MAX) { + av_log(matroska->ctx, AV_LOG_WARNING, + "Too large audio channel number %"PRIu64 + " or bitdepth %"PRIu64". Skipping track.\n", + track->audio.channels, track->audio.bitdepth); + if (matroska->ctx->error_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + else + return SKIP_TRACK; + } + if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX) + return AVERROR_INVALIDDATA; + extradata_size = TTA_EXTRADATA_SIZE; + ptr = extradata; + bytestream_put_be32(&ptr, AV_RB32("TTA1")); + bytestream_put_le16(&ptr, 1); + bytestream_put_le16(&ptr, track->audio.channels); + bytestream_put_le16(&ptr, track->audio.bitdepth); + bytestream_put_le32(&ptr, track->audio.out_samplerate); + bytestream_put_le32(&ptr, av_rescale(matroska->duration * matroska->time_scale, + track->audio.out_samplerate, + AV_TIME_BASE * 1000)); + break; + } + case AV_CODEC_ID_RA_144: + track->audio.out_samplerate = 8000; + track->audio.channels = 1; + break; + case AV_CODEC_ID_RA_288: + case AV_CODEC_ID_COOK: + case AV_CODEC_ID_ATRAC3: + case AV_CODEC_ID_SIPR: + { + const uint8_t *ptr = track->codec_priv.data; + int flavor; + + if (!track->codec_priv.size) + break; + + if (track->codec_priv.size < 46) + return AVERROR_INVALIDDATA; + ptr += 22; + flavor = bytestream_get_be16(&ptr); + track->audio.coded_framesize = bytestream_get_be32(&ptr); + ptr += 12; + track->audio.sub_packet_h = bytestream_get_be16(&ptr); + track->audio.frame_size = bytestream_get_be16(&ptr); + track->audio.sub_packet_size = bytestream_get_be16(&ptr); + if (track->audio.coded_framesize <= 0 || + track->audio.sub_packet_h <= 0 || + track->audio.frame_size <= 0) + return AVERROR_INVALIDDATA; + + if (par->codec_id == AV_CODEC_ID_RA_288) { + if (track->audio.sub_packet_h & 1 || 2 * track->audio.frame_size + != (int64_t)track->audio.sub_packet_h * track->audio.coded_framesize) + return AVERROR_INVALIDDATA; + par->block_align = track->audio.coded_framesize; + track->codec_priv.size = 0; + } else { + if (par->codec_id == AV_CODEC_ID_SIPR) { + static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; + if (flavor > 3) + return AVERROR_INVALIDDATA; + track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; + par->bit_rate = sipr_bit_rate[flavor]; + } else if (track->audio.sub_packet_size <= 0 || + track->audio.frame_size % track->audio.sub_packet_size) + return AVERROR_INVALIDDATA; + par->block_align = track->audio.sub_packet_size; + *extradata_offset = 78; + } + track->audio.buf = av_malloc_array(track->audio.sub_packet_h, + track->audio.frame_size); + if (!track->audio.buf) + return AVERROR(ENOMEM); + break; + } + case AV_CODEC_ID_FLAC: + if (track->codec_priv.size) { + ret = matroska_parse_flac(s, track, extradata_offset); + if (ret < 0) + return ret; + } + break; + case AV_CODEC_ID_WAVPACK: + if (track->codec_priv.size < 2) { + av_log(matroska->ctx, AV_LOG_INFO, "Assuming WavPack version 4.10 " + "in absence of valid CodecPrivate.\n"); + extradata_size = WAVPACK_EXTRADATA_SIZE; + AV_WL16(extradata, 0x410); + } + break; + } + + if (extradata_size > 0) { + ret = ff_alloc_extradata(par, extradata_size); + if (ret < 0) + return ret; + memcpy(par->extradata, extradata, extradata_size); + } + + return 0; +} static int matroska_parse_tracks(AVFormatContext *s) { @@ -2518,10 +2750,6 @@ static int matroska_parse_tracks(AVFormatContext *s) EbmlList *encodings_list = &track->encodings; MatroskaTrackEncoding *encodings = encodings_list->elem; AVCodecParameters *par; - uint8_t extradata[FFMAX3(AAC_MAX_EXTRADATA_SIZE, - TTA_EXTRADATA_SIZE, - WAVPACK_EXTRADATA_SIZE)]; - int extradata_size = 0; // > 0 means that the extradata buffer is used int extradata_offset = 0; uint32_t fourcc = 0; FFIOContext b; @@ -2702,6 +2930,14 @@ static int matroska_parse_tracks(AVFormatContext *s) (AVRational){ 1, 1000000000 }, st->time_base); + if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { + ret = mka_parse_audio_codec(track, par, matroska, + s, &extradata_offset); + if (ret < 0) + return ret; + if (ret == SKIP_TRACK) + continue; + } else if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") && track->codec_priv.size >= 40 && track->codec_priv.data) { @@ -2714,43 +2950,6 @@ static int matroska_parse_tracks(AVFormatContext *s) par->codec_id = ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag); extradata_offset = 40; - } else if (!strcmp(track->codec_id, "A_MS/ACM") && - track->codec_priv.size >= 14 && - track->codec_priv.data) { - int ret; - ffio_init_context(&b, track->codec_priv.data, - track->codec_priv.size, - 0, NULL, NULL, NULL, NULL); - ret = ff_get_wav_header(s, &b.pub, par, - track->codec_priv.size, 0); - if (ret < 0) - return ret; - extradata_offset = FFMIN(track->codec_priv.size, 18); - } else if (!strcmp(track->codec_id, "A_QUICKTIME") - /* Normally 36, but allow noncompliant private data */ - && (track->codec_priv.size >= 32) - && (track->codec_priv.data)) { - uint32_t fourcc; - uint16_t sample_size; - int ret = get_qt_codec(track, &fourcc, &codec_id); - if (ret < 0) - return ret; - sample_size = AV_RB16(track->codec_priv.data + 26); - if (fourcc == 0) { - if (sample_size == 8) { - fourcc = MKTAG('r','a','w',' '); - codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); - } else if (sample_size == 16) { - fourcc = MKTAG('t','w','o','s'); - codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); - } - } - if ((fourcc == MKTAG('t','w','o','s') || - fourcc == MKTAG('s','o','w','t')) && - sample_size == 8) - codec_id = AV_CODEC_ID_PCM_S8; - par->codec_id = codec_id; - par->codec_tag = fourcc; } else if (!strcmp(track->codec_id, "V_QUICKTIME") && (track->codec_priv.size >= 21) && (track->codec_priv.data)) { @@ -2778,146 +2977,11 @@ static int matroska_parse_tracks(AVFormatContext *s) par->bits_per_coded_sample = bit_depth; } par->codec_tag = fourcc; - } else if (codec_id == AV_CODEC_ID_PCM_S16BE) { - switch (track->audio.bitdepth) { - case 8: - par->codec_id = AV_CODEC_ID_PCM_U8; - break; - case 24: - par->codec_id = AV_CODEC_ID_PCM_S24BE; - break; - case 32: - par->codec_id = AV_CODEC_ID_PCM_S32BE; - break; - } - } else if (codec_id == AV_CODEC_ID_PCM_S16LE) { - switch (track->audio.bitdepth) { - case 8: - par->codec_id = AV_CODEC_ID_PCM_U8; - break; - case 24: - par->codec_id = AV_CODEC_ID_PCM_S24LE; - break; - case 32: - par->codec_id = AV_CODEC_ID_PCM_S32LE; - break; - } - } else if (codec_id == AV_CODEC_ID_PCM_F32LE && - track->audio.bitdepth == 64) { - par->codec_id = AV_CODEC_ID_PCM_F64LE; - } else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) { - int profile = matroska_aac_profile(track->codec_id); - int sri = matroska_aac_sri(track->audio.samplerate); - - extradata[0] = (profile << 3) | ((sri & 0x0E) >> 1); - extradata[1] = ((sri & 0x01) << 7) | (track->audio.channels << 3); - if (strstr(track->codec_id, "SBR")) { - sri = matroska_aac_sri(track->audio.out_samplerate); - extradata[2] = 0x56; - extradata[3] = 0xE5; - extradata[4] = 0x80 | (sri << 3); - extradata_size = 5; - } else - extradata_size = 2; - } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - AV_INPUT_BUFFER_PADDING_SIZE) { - /* Only ALAC's magic cookie is stored in Matroska's track headers. - * Create the "atom size", "tag", and "tag version" fields the - * decoder expects manually. */ - ret = ff_alloc_extradata(par, 12 + track->codec_priv.size); - if (ret < 0) - return ret; - AV_WB32(par->extradata, par->extradata_size); - AV_WB32(&par->extradata[4], MKBETAG('a', 'l', 'a', 'c')); - AV_WB32(&par->extradata[8], 0); - memcpy(&par->extradata[12], track->codec_priv.data, - track->codec_priv.size); - } else if (codec_id == AV_CODEC_ID_TTA) { - uint8_t *ptr; - if (track->audio.channels > UINT16_MAX || - track->audio.bitdepth > UINT16_MAX) { - av_log(matroska->ctx, AV_LOG_WARNING, - "Too large audio channel number %"PRIu64 - " or bitdepth %"PRIu64". Skipping track.\n", - track->audio.channels, track->audio.bitdepth); - if (matroska->ctx->error_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - else - continue; - } - if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX) - return AVERROR_INVALIDDATA; - extradata_size = TTA_EXTRADATA_SIZE; - ptr = extradata; - bytestream_put_be32(&ptr, AV_RB32("TTA1")); - bytestream_put_le16(&ptr, 1); - bytestream_put_le16(&ptr, track->audio.channels); - bytestream_put_le16(&ptr, track->audio.bitdepth); - bytestream_put_le32(&ptr, track->audio.out_samplerate); - bytestream_put_le32(&ptr, av_rescale(matroska->duration * matroska->time_scale, - track->audio.out_samplerate, - AV_TIME_BASE * 1000)); } else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 || codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) { extradata_offset = 26; - } else if (codec_id == AV_CODEC_ID_RA_144) { - track->audio.out_samplerate = 8000; - track->audio.channels = 1; - } else if ((codec_id == AV_CODEC_ID_RA_288 || - codec_id == AV_CODEC_ID_COOK || - codec_id == AV_CODEC_ID_ATRAC3 || - codec_id == AV_CODEC_ID_SIPR) - && track->codec_priv.data) { - const uint8_t *ptr = track->codec_priv.data; - int flavor; - - if (track->codec_priv.size < 46) - return AVERROR_INVALIDDATA; - ptr += 22; - flavor = bytestream_get_be16(&ptr); - track->audio.coded_framesize = bytestream_get_be32(&ptr); - ptr += 12; - track->audio.sub_packet_h = bytestream_get_be16(&ptr); - track->audio.frame_size = bytestream_get_be16(&ptr); - track->audio.sub_packet_size = bytestream_get_be16(&ptr); - if (track->audio.coded_framesize <= 0 || - track->audio.sub_packet_h <= 0 || - track->audio.frame_size <= 0) - return AVERROR_INVALIDDATA; - - if (codec_id == AV_CODEC_ID_RA_288) { - if (track->audio.sub_packet_h & 1 || 2 * track->audio.frame_size - != (int64_t)track->audio.sub_packet_h * track->audio.coded_framesize) - return AVERROR_INVALIDDATA; - par->block_align = track->audio.coded_framesize; - track->codec_priv.size = 0; - } else { - if (codec_id == AV_CODEC_ID_SIPR) { - static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; - if (flavor > 3) - return AVERROR_INVALIDDATA; - track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; - par->bit_rate = sipr_bit_rate[flavor]; - } else if (track->audio.sub_packet_size <= 0 || - track->audio.frame_size % track->audio.sub_packet_size) - return AVERROR_INVALIDDATA; - par->block_align = track->audio.sub_packet_size; - extradata_offset = 78; - } - track->audio.buf = av_malloc_array(track->audio.sub_packet_h, - track->audio.frame_size); - if (!track->audio.buf) - return AVERROR(ENOMEM); - } else if (codec_id == AV_CODEC_ID_FLAC && track->codec_priv.size) { - ret = matroska_parse_flac(s, track, &extradata_offset); - if (ret < 0) - return ret; - } else if (codec_id == AV_CODEC_ID_WAVPACK && track->codec_priv.size < 2) { - av_log(matroska->ctx, AV_LOG_INFO, "Assuming WavPack version 4.10 " - "in absence of valid CodecPrivate.\n"); - extradata_size = WAVPACK_EXTRADATA_SIZE; - AV_WL16(extradata, 0x410); } else if (codec_id == AV_CODEC_ID_PRORES && track->codec_priv.size == 4) { par->codec_tag = AV_RL32(track->codec_priv.data); } else if (codec_id == AV_CODEC_ID_VP9) { @@ -2960,11 +3024,9 @@ static int matroska_parse_tracks(AVFormatContext *s) av_log(matroska->ctx, AV_LOG_INFO, "Unknown/unsupported AVCodecID %s.\n", track->codec_id); - if (!par->extradata && (extradata_size > 0 || track->codec_priv.size > 0)) { - const uint8_t *src = extradata_size > 0 ? extradata : - track->codec_priv.data + extradata_offset; - unsigned extra_size = extradata_size > 0 ? extradata_size : - track->codec_priv.size; + if (!par->extradata && track->codec_priv.size > 0) { + const uint8_t *src = track->codec_priv.data + extradata_offset; + unsigned extra_size = track->codec_priv.size; ret = ff_alloc_extradata(par, extra_size); if (ret < 0) return ret; -- 2.34.1 _______________________________________________ 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:[~2023-09-04 11:27 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-09-04 11:26 [FFmpeg-devel] [PATCH 01/20] fate/matroska: Add test for remuxing non-rotation displaymatrix Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 02/20] avformat/matroskadec: Set several stream parameters earlier Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 03/20] avformat/matroskadec: Use dedicated pointer for access to codecpar Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 04/20] avformat/matroskadec: Redo handling extradata allocation Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 05/20] avformat/matroskadec: Set AVCodecParameters earlier Andreas Rheinhardt 2023-09-04 11:27 ` Andreas Rheinhardt [this message] 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 07/20] avformat/matroskadec: Remove redundant checks Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 08/20] avformat/matroskadec: Reindent after the previous commit Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 09/20] avformat/matroskadec: Factor video parsing out of matroska_parse_tracks() Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 10/20] avformat/matroskadec: Reindent after the previous commit Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 11/20] avformat/matroskadec: Move reading color space to a better place Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 12/20] avformat/matroskadec: Avoid clobbering CodecPrivate size Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 13/20] avformat/matroskadec: Use av_dict_set_int() where appropriate Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 14/20] avformat/matroskadec: Factor parsing subtitle codecs out Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 15/20] avformat/matroskadec: Factor generic parsing of video tracks out Andreas Rheinhardt 2023-09-04 11:46 ` James Almer 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 16/20] avformat/matroskadec: Reindent after the previous commit Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 17/20] avformat/matroskadec: Factor generic parsing of audio tracks out Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 18/20] avformat/matroskdec: Reindent after the previous commit Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 19/20] avformat/matroskadec: Move WEBVTT code to mkv_parse_subtitle_codec() Andreas Rheinhardt 2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 20/20] avformat/matroskadec: Factor parsing content encodings out Andreas Rheinhardt 2023-09-06 9:37 ` [FFmpeg-devel] [PATCH 01/20] fate/matroska: Add test for remuxing non-rotation displaymatrix Andreas Rheinhardt
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=AS8P250MB074465384F786A81C277C5688FE9A@AS8P250MB0744.EURP250.PROD.OUTLOOK.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