From: James Almer <jamrial@gmail.com> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 1/2] swresample/rematrix: split filling the matrix array into its own function Date: Sun, 2 Feb 2025 18:46:41 -0300 Message-ID: <20250202214642.5316-1-jamrial@gmail.com> (raw) Signed-off-by: James Almer <jamrial@gmail.com> --- libswresample/rematrix.c | 202 ++++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 96 deletions(-) diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index b9bf4dcac0..8b6e8ae1c5 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -124,85 +124,28 @@ static int sane_layout(AVChannelLayout *ch_layout) { return 1; } -av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout, - double center_mix_level, double surround_mix_level, - double lfe_mix_level, double maxval, - double rematrix_volume, double *matrix_param, - ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context) +static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout, + double center_mix_level, double surround_mix_level, + double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, + ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding) { - int i, j, out_i, ret; - AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; - int64_t unaccounted; + uint64_t unaccounted = in_ch_layout->u.mask & ~out_ch_layout->u.mask; double maxcoef=0; - char buf[128]; - - ret = clean_layout(&in_ch_layout, in_layout, log_context); - ret |= clean_layout(&out_ch_layout, out_layout, log_context); - if (ret < 0) - goto fail; - - if( !av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) - && !av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) - ) { - av_channel_layout_uninit(&out_ch_layout); - out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; - } - if( !av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) - && !av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) - ) { - av_channel_layout_uninit(&in_ch_layout); - in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; - } - if (!av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2) && - av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2)) { - av_channel_layout_from_mask(&in_ch_layout, (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER)); - av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); - av_log(log_context, AV_LOG_WARNING, - "Full-on remixing from 22.2 has not yet been implemented! " - "Processing the input as '%s'\n", - buf); - } - - if(!av_channel_layout_check(&in_ch_layout)) { - av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if(!sane_layout(&in_ch_layout)) { - av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); - av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); - ret = AVERROR(EINVAL); - goto fail; - } - - if(!av_channel_layout_check(&out_ch_layout)) { - av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if(!sane_layout(&out_ch_layout)) { - av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf)); - av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); - ret = AVERROR(EINVAL); - goto fail; - } + int i, j, out_i; for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ - if( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0 - && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0) + if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 + && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0) matrix[i][i]= 1.0; } - unaccounted = in_ch_layout.u.mask & ~out_ch_layout.u.mask; - //FIXME implement dolby surround //FIXME implement full ac3 - if(unaccounted & AV_CH_FRONT_CENTER){ - if (av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { - if (av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO)) { + if (av_channel_layout_subset(out_ch_layout, AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { + if (av_channel_layout_subset(in_ch_layout, AV_CH_LAYOUT_STEREO)) { matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level; matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level; } else { @@ -213,23 +156,23 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL av_assert0(0); } if(unaccounted & AV_CH_LAYOUT_STEREO){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2; matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2; - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2); }else av_assert0(0); } if(unaccounted & AV_CH_BACK_CENTER){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY || matrix_encoding == AV_MATRIX_ENCODING_DPLII) { if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) { @@ -243,24 +186,24 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_BACK_LEFT){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2; }else{ matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0; matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2; matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2; @@ -275,7 +218,7 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level; matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2; matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2; }else @@ -283,20 +226,20 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL } if(unaccounted & AV_CH_SIDE_LEFT){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { /* if back channels do not exist in the input, just copy side channels to back channels, otherwise mix side into back */ - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2; matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2; } else { matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0; matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2; matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2; @@ -311,7 +254,7 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level; matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2; matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2; }else @@ -319,10 +262,10 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL } if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){ - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0; matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2; matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2; }else @@ -330,20 +273,20 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL } if (unaccounted & AV_CH_TOP_FRONT_LEFT) { - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) { matrix[TOP_FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[TOP_FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2); - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { - if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += M_SQRT1_2; } else { matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0; matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += 1.0; } - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; } else @@ -352,29 +295,30 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL /* mix LFE into front left/right or center */ if (unaccounted & AV_CH_LOW_FREQUENCY) { - if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level; - } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; } else av_assert0(0); } + for(out_i=i=0; i<64; i++){ double sum=0; int in_i=0; - if (av_channel_layout_index_from_channel(&out_ch_layout, i) < 0) + if (av_channel_layout_index_from_channel(out_ch_layout, i) < 0) continue; for(j=0; j<64; j++){ - if (av_channel_layout_index_from_channel(&in_ch_layout, j) < 0) + if (av_channel_layout_index_from_channel(in_ch_layout, j) < 0) continue; if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) matrix_param[stride*out_i + in_i] = matrix[i][j]; else matrix_param[stride*out_i + in_i] = i == j && - ( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0 - && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0); + ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 + && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0); sum += fabs(matrix_param[stride*out_i + in_i]); in_i++; } @@ -391,6 +335,72 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL matrix_param[stride*i + j] /= maxcoef; } } +} + +av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout, + double center_mix_level, double surround_mix_level, + double lfe_mix_level, double maxval, + double rematrix_volume, double *matrix_param, + ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context) +{ + int i, j, ret; + AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; + char buf[128]; + + ret = clean_layout(&in_ch_layout, in_layout, log_context); + ret |= clean_layout(&out_ch_layout, out_layout, log_context); + if (ret < 0) + goto fail; + + if( !av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) + && !av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) + ) { + av_channel_layout_uninit(&out_ch_layout); + out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; + } + if( !av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) + && !av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) + ) { + av_channel_layout_uninit(&in_ch_layout); + in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; + } + if (!av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2) && + av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2)) { + av_channel_layout_from_mask(&in_ch_layout, (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER)); + av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); + av_log(log_context, AV_LOG_WARNING, + "Full-on remixing from 22.2 has not yet been implemented! " + "Processing the input as '%s'\n", + buf); + } + + if(!av_channel_layout_check(&in_ch_layout)) { + av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n"); + ret = AVERROR(EINVAL); + goto fail; + } + if(!sane_layout(&in_ch_layout)) { + av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); + av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); + ret = AVERROR(EINVAL); + goto fail; + } + + if(!av_channel_layout_check(&out_ch_layout)) { + av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n"); + ret = AVERROR(EINVAL); + goto fail; + } + if(!sane_layout(&out_ch_layout)) { + av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf)); + av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); + ret = AVERROR(EINVAL); + goto fail; + } + + build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level, + surround_mix_level, lfe_mix_level, maxval, rematrix_volume, + matrix_param, stride, matrix_encoding); if(rematrix_volume > 0){ for(i=0; i<SWR_CH_MAX; i++) -- 2.48.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 reply other threads:[~2025-02-02 21:47 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-02-02 21:46 James Almer [this message] 2025-02-02 21:46 ` [FFmpeg-devel] [PATCH 2/2] swresample/rematrix: add support for custom order channel layouts James Almer 2025-02-02 23:03 ` James Almer 2025-02-02 23:44 ` Pavel Koshevoy
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=20250202214642.5316-1-jamrial@gmail.com \ --to=jamrial@gmail.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