From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Subject: [FFmpeg-devel] [PATCH 20/41] avcodec/mpegvideoenc: Move ratecontrol to MPVMainEncContext Date: Sun, 30 Jan 2022 07:27:28 +0100 Message-ID: <AM7PR03MB66603B606FBA794C2C0C90498F249@AM7PR03MB6660.eurprd03.prod.outlook.com> (raw) In-Reply-To: <AM7PR03MB666068B09E9D0014E1CC65DD8F249@AM7PR03MB6660.eurprd03.prod.outlook.com> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/mpegvideo.h | 8 -------- libavcodec/mpegvideo_enc.c | 38 +++++++++++++++++++------------------- libavcodec/mpegvideoenc.h | 8 ++++++++ libavcodec/ratecontrol.c | 31 +++++++++++++++---------------- libavcodec/snowenc.c | 8 ++++---- 5 files changed, 46 insertions(+), 47 deletions(-) diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index e83061fa92..c9467f0752 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -47,7 +47,6 @@ #include "mpegvideodata.h" #include "pixblockdsp.h" #include "put_bits.h" -#include "ratecontrol.h" #if FF_API_FLAG_TRUNCATED #include "parser.h" #endif @@ -316,13 +315,6 @@ typedef struct MPVContext { int dct_count[2]; uint16_t (*dct_offset)[64]; - /* bit rate control */ - int64_t total_bits; - int frame_bits; ///< bits used for the current frame - int stuffing_bits; ///< bits used for stuffing - int next_lambda; ///< next lambda used for retrying to encode a frame - RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c - /* statistics, used for 2-pass encoding */ int mv_bits; int header_bits; diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index bbff65ef41..3eb8260b06 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1405,15 +1405,15 @@ static int select_input_picture(MPVMainEncContext *m) for (i = 0; i < s->max_b_frames + 1; i++) { int pict_num = s->input_picture[0]->f->display_picture_number + i; - if (pict_num >= s->rc_context.num_entries) + if (pict_num >= m->rc_context.num_entries) break; if (!s->input_picture[i]) { - s->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P; + m->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P; break; } s->input_picture[i]->f->pict_type = - s->rc_context.entry[pict_num].new_pict_type; + m->rc_context.entry[pict_num].new_pict_type; } } @@ -1743,14 +1743,14 @@ vbv_retry: ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits); if (avctx->rc_buffer_size) { - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; int max_size = FFMAX(rcc->buffer_index * avctx->rc_max_available_vbv_use, rcc->buffer_index - 500); int hq = (avctx->mb_decision == FF_MB_DECISION_RD || avctx->trellis); int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139; if (put_bits_count(&s->pb) > max_size && s->lambda < s->lmax) { - s->next_lambda = FFMAX(s->lambda + min_step, s->lambda * + m->next_lambda = FFMAX(s->lambda + min_step, s->lambda * (s->qscale + 1) / s->qscale); if (s->adaptive_quant) { int i; @@ -1801,10 +1801,10 @@ vbv_retry: s->misc_bits + s->i_tex_bits + s->p_tex_bits); flush_put_bits(&s->pb); - s->frame_bits = put_bits_count(&s->pb); + m->frame_bits = put_bits_count(&s->pb); - stuffing_count = ff_vbv_update(m, s->frame_bits); - s->stuffing_bits = 8*stuffing_count; + stuffing_count = ff_vbv_update(m, m->frame_bits); + m->stuffing_bits = 8 * stuffing_count; if (stuffing_count) { if (put_bytes_left(&s->pb, 0) < stuffing_count + 50) { av_log(avctx, AV_LOG_ERROR, "stuffing too large\n"); @@ -1828,10 +1828,10 @@ vbv_retry: break; default: av_log(avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); - s->stuffing_bits = 0; + m->stuffing_bits = 0; } flush_put_bits(&s->pb); - s->frame_bits = put_bits_count(&s->pb); + m->frame_bits = put_bits_count(&s->pb); } /* update MPEG-1/2 vbv_delay for CBR */ @@ -1846,9 +1846,9 @@ vbv_retry: int vbv_delay, min_delay; double inbits = avctx->rc_max_rate * av_q2d(avctx->time_base); - int minbits = s->frame_bits - 8 * + int minbits = m->frame_bits - 8 * (s->vbv_delay_pos - 1); - double bits = s->rc_context.buffer_index + minbits - inbits; + double bits = m->rc_context.buffer_index + minbits - inbits; uint8_t *const vbv_delay_ptr = s->pb.buf + s->vbv_delay_pos; if (bits < 0) @@ -1883,7 +1883,7 @@ vbv_retry: return ret; } } - s->total_bits += s->frame_bits; + m->total_bits += m->frame_bits; pkt->pts = s->current_picture.f->pts; if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) { @@ -1899,7 +1899,7 @@ vbv_retry: if (s->mb_info) av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size); } else { - s->frame_bits = 0; + m->frame_bits = 0; } /* release non-reference frames */ @@ -1908,9 +1908,9 @@ vbv_retry: ff_mpeg_unref_picture(avctx, &s->picture[i]); } - av_assert1((s->frame_bits & 7) == 0); + av_assert1((m->frame_bits & 7) == 0); - pkt->size = s->frame_bits / 8; + pkt->size = m->frame_bits / 8; *got_packet = !!pkt->size; return 0; } @@ -3445,10 +3445,10 @@ static void merge_context_after_encode(MPVEncContext *dst, MPVEncContext *src) static int estimate_qp(MPVMainEncContext *m, int dry_run) { MPVEncContext *const s = &m->common; - if (s->next_lambda){ + if (m->next_lambda) { s->current_picture_ptr->f->quality = - s->current_picture.f->quality = s->next_lambda; - if(!dry_run) s->next_lambda= 0; + s->current_picture.f->quality = m->next_lambda; + if (!dry_run) m->next_lambda= 0; } else if (!s->fixed_qscale) { int quality = ff_rate_estimate_qscale(m, dry_run); s->current_picture_ptr->f->quality = diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h index c1013316aa..6a96909e17 100644 --- a/libavcodec/mpegvideoenc.h +++ b/libavcodec/mpegvideoenc.h @@ -31,11 +31,19 @@ #include "libavutil/opt.h" #include "internal.h" #include "mpegvideo.h" +#include "ratecontrol.h" typedef MPVContext MPVEncContext; typedef struct MPVMainEncContext { MPVMainContext common; + /* bit rate control */ + int64_t total_bits; + int frame_bits; ///< bits used for the current frame + int stuffing_bits; ///< bits used for stuffing + int next_lambda; ///< next lambda used for retrying to encode a frame + RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c + /* temporary frames used by b_frame_strategy == 2 */ AVFrame *tmp_frames[MAX_B_FRAMES + 2]; int b_frame_strategy; diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 4c326741df..b0f319680b 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -81,7 +81,7 @@ static inline double bits2qp(RateControlEntry *rce, double bits) static double get_diff_limited_q(MPVMainEncContext *m, RateControlEntry *rce, double q) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; AVCodecContext *a = s->avctx; const int pict_type = rce->new_pict_type; const double last_p_q = rcc->last_qscale_for[AV_PICTURE_TYPE_P]; @@ -150,7 +150,7 @@ static double modify_qscale(MPVMainEncContext *m, RateControlEntry *rce, double q, int frame_num) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; const double buffer_size = s->avctx->rc_buffer_size; const double fps = get_fps(s->avctx); const double min_rate = s->avctx->rc_min_rate / fps; @@ -242,7 +242,7 @@ static double get_qscale(MPVMainEncContext *m, RateControlEntry *rce, double rate_factor, int frame_num) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; AVCodecContext *a = s->avctx; const int pict_type = rce->new_pict_type; const double mb_num = s->mb_num; @@ -315,7 +315,7 @@ static double get_qscale(MPVMainEncContext *m, RateControlEntry *rce, static int init_pass2(MPVMainEncContext *m) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; AVCodecContext *a = s->avctx; int i, toobig; double fps = get_fps(s->avctx); @@ -477,7 +477,7 @@ static int init_pass2(MPVMainEncContext *m) av_cold int ff_rate_control_init(MPVMainEncContext *m) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; int i, res; static const char * const const_names[] = { "PI", @@ -677,8 +677,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *m) av_cold void ff_rate_control_uninit(MPVMainEncContext *m) { - MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; emms_c(); av_expr_free(rcc->rc_eq_eval); @@ -688,7 +687,7 @@ av_cold void ff_rate_control_uninit(MPVMainEncContext *m) int ff_vbv_update(MPVMainEncContext *m, int frame_size) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; const double fps = get_fps(s->avctx); const int buffer_size = s->avctx->rc_buffer_size; const double min_rate = s->avctx->rc_min_rate / fps; @@ -866,7 +865,7 @@ static void adaptive_quantization(MPVMainEncContext *m, double q) void ff_get_2pass_fcode(MPVMainEncContext *m) { MPVEncContext *const s = &m->common; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; RateControlEntry *rce = &rcc->entry[s->picture_number]; s->f_code = rce->f_code; @@ -886,7 +885,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run) double fps; int picture_number = s->picture_number; int64_t wanted_bits; - RateControlContext *rcc = &s->rc_context; + RateControlContext *rcc = &m->rc_context; AVCodecContext *a = s->avctx; RateControlEntry local_rce, *rce; double bits; @@ -904,11 +903,11 @@ float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run) const int64_t last_var = s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum; - av_assert1(s->frame_bits >= s->stuffing_bits); + av_assert1(m->frame_bits >= m->stuffing_bits); update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), - s->frame_bits - s->stuffing_bits); + m->frame_bits - m->stuffing_bits); } if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { @@ -937,7 +936,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run) wanted_bits = (uint64_t)(s->bit_rate * (double)dts_pic->f->pts / fps); } - diff = s->total_bits - wanted_bits; + diff = m->total_bits - wanted_bits; br_compensation = (a->bit_rate_tolerance - diff) / a->bit_rate_tolerance; if (br_compensation <= 0.0) br_compensation = 0.001; @@ -951,7 +950,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run) q = rce->new_qscale / br_compensation; ff_dlog(s, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale, - br_compensation, s->frame_bits, var, pict_type); + br_compensation, m->frame_bits, var, pict_type); } else { rce->pict_type = rce->new_pict_type = pict_type; @@ -1014,8 +1013,8 @@ float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run) "size:%d var:%"PRId64"/%"PRId64" br:%"PRId64" fps:%d\n", av_get_picture_type_char(pict_type), qmin, q, qmax, picture_number, - wanted_bits / 1000, s->total_bits / 1000, - br_compensation, short_term_q, s->frame_bits, + wanted_bits / 1000, m->total_bits / 1000, + br_compensation, short_term_q, m->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate / 1000, (int)fps); } diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 028b6b91aa..ebed90c729 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -1597,7 +1597,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, mpv->picture_number= avctx->frame_number; if(avctx->flags&AV_CODEC_FLAG_PASS2){ - mpv->pict_type = pic->pict_type = mpv->rc_context.entry[avctx->frame_number].new_pict_type; + mpv->pict_type = pic->pict_type = s->m.rc_context.entry[avctx->frame_number].new_pict_type; s->keyframe = pic->pict_type == AV_PICTURE_TYPE_I; if(!(avctx->flags&AV_CODEC_FLAG_QSCALE)) { pic->quality = ff_rate_estimate_qscale(&s->m, 0); @@ -1847,12 +1847,12 @@ redo_frame: s->current_picture->coded_picture_number = avctx->frame_number; s->current_picture->pict_type = pic->pict_type; s->current_picture->quality = pic->quality; - mpv->frame_bits = 8*(s->c.bytestream - s->c.bytestream_start); - mpv->p_tex_bits = mpv->frame_bits - mpv->misc_bits - mpv->mv_bits; + s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start); + mpv->p_tex_bits = s->m.frame_bits - mpv->misc_bits - mpv->mv_bits; mpv->current_picture.f->display_picture_number = mpv->current_picture.f->coded_picture_number = avctx->frame_number; mpv->current_picture.f->quality = pic->quality; - mpv->total_bits += 8*(s->c.bytestream - s->c.bytestream_start); + s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start); if(s->pass1_rc) if (ff_rate_estimate_qscale(&s->m, 0) < 0) return -1; -- 2.32.0 _______________________________________________ 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-01-30 6:31 UTC|newest] Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-01-30 6:08 [FFmpeg-devel] [PATCH 01/41] avcodec/mpegvideo_enc: Allow slices only for slice-thread-able codecs Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 02/41] avcodec/mjpegenc: Remove nonsense assert Andreas Rheinhardt 2022-01-30 13:15 ` Michael Niedermayer 2022-01-30 17:07 ` Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 03/41] avcodec/mjpegenc: Fix files with slices > 1, but threads == 1 Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 04/41] avcodec/mpegvideo: Enable private contexts Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 05/41] avcodec/h261: Separate decode and encode contexts Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 06/41] avcodec/h261enc: Pass PutBitContext directly in h261_encode_motion() Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 07/41] avcodec/idctdsp: Constify the permutation parameter of ff_init_scantable Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 08/41] avcodec/wmv2: Move initializing abt_scantables to the decoder Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 09/41] avcodec/wmv2: Split Wmv2Context into decoder and encoder context Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 10/41] avcodec/msmpeg4.h: Move encoder-only stuff to a new header Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 11/41] avcodec/msmpegenc: Add MSMPEG4EncContext and move ac_stats to it Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 12/41] avcodec/h263.h: Move encoder-only stuff to a new header h263enc.h Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 13/41] avcodec/mpegvideo: Move encoder-only stuff to a new header Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 14/41] avcodec/avcodec: Avoid MpegEncContext in AVHWAccel.decode_mb Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 15/41] avcodec/speedhqenc: Add SpeedHQEncContext and move slice_start to it Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 16/41] avcodec/mpegvideo: Use typedefs for MPV(Main)?(Dec|Enc)?Context Andreas Rheinhardt 2022-01-30 11:40 ` Michael Niedermayer 2022-01-30 23:05 ` Andreas Rheinhardt 2022-01-31 15:37 ` Michael Niedermayer 2022-01-30 11:43 ` Michael Niedermayer 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 17/41] avcodec/mpegvideo_enc: Don't find encoder by ID Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 18/41] avcodec/mpegvideoenc: Add proper MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 19/41] avcodec/mpegvideoenc: Move tmp bframes to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` Andreas Rheinhardt [this message] 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 21/41] avcodec/mpegvideo: Move me_pre and me_penalty_compensation to enc-ctx Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 22/41] avcodec/mpegvideo: Move gop_size to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 23/41] avcodec/mpegvideo_enc: Don't set picture_in_gop_number for slice threads Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 24/41] avcodec/mpegvideo: Move picture_in_gop_number to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 25/41] avcodec/mpegvideo: Move pts and dts fields " Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 26/41] avcodec/mpegvideo: Move input_picture list " Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 27/41] avcodec/mpegvideo: Remove write-only [fb]_code Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 28/41] avcodec/mpegvideo: Move last-pic information to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 29/41] avcodec/mpegvideo: Move header_bits " Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 30/41] avcodec/mpegvideo_enc: Remove unused function parameters Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 31/41] avcodec/mpegvideo_enc: Remove unused parameter from encode_mb_hq() Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 32/41] avcodec/mpegvideo: Move vbv_delay to Mpeg1Context Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 33/41] avcodec/mpegvideo: Move brd_scale to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 34/41] avcodec/mpegvideo: Move ratecontrol parameters " Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 35/41] avcodec/mpegvideo: Allocate encoder-only tables in mpegvideo_enc.c Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 36/41] avcodec/mpegvideo: Move encoder-only base-arrays to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 37/41] avcodec/mpegvideo_enc: Initialize non-JPEG q-matrices only once Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 38/41] avcodec/mpegvideo_enc: Avoid allocations for q_int(er|ra)_matrix tables Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 39/41] avcodec/mpegvideo: Move scenechange_threshold to MPVMainEncContext Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 40/41] avcodec/mpegvideo: Move dummy dst for depr. opts " Andreas Rheinhardt 2022-01-30 6:27 ` [FFmpeg-devel] [PATCH 41/41] avcodec/mpegvideo: Move frame_skip_(exp|cmp) " 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=AM7PR03MB66603B606FBA794C2C0C90498F249@AM7PR03MB6660.eurprd03.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