[FFmpeg-devel] [PATCH 1/4] avformat/audiointerleave: disallow using a samples_per_frame array
Tomas Härdin
tjoppen at acc.umu.se
Mon Mar 2 19:00:30 EET 2020
Sorry for replying a bit late, I've been sick
fre 2020-02-28 klockan 01:37 +0100 skrev Marton Balint:
> Only MXF used an actual sample array, and that is unneeded there
> because simple
> rounding rules can be used instead.
Does this produce the exact same rounding? Like 1602, 1601,
1602, 1601, 1602, 1062 ... for 30/1.001 fps? If so then this is a nice
solution
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
> libavformat/audiointerleave.c | 24 ++++++++++--------------
> libavformat/audiointerleave.h | 7 ++++---
> libavformat/gxfenc.c | 2 +-
> libavformat/mxfenc.c | 7 ++-----
> 4 files changed, 17 insertions(+), 23 deletions(-)
>
> diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
> index 6797546a44..f9887c1f4a 100644
> --- a/libavformat/audiointerleave.c
> +++ b/libavformat/audiointerleave.c
> @@ -39,14 +39,11 @@ void ff_audio_interleave_close(AVFormatContext *s)
> }
>
> int ff_audio_interleave_init(AVFormatContext *s,
> - const int *samples_per_frame,
> + const int samples_per_frame,
> AVRational time_base)
> {
> int i;
>
> - if (!samples_per_frame)
> - return AVERROR(EINVAL);
> -
> if (!time_base.num) {
> av_log(s, AV_LOG_ERROR, "timebase not set for audio interleave\n");
> return AVERROR(EINVAL);
> @@ -56,18 +53,18 @@ int ff_audio_interleave_init(AVFormatContext *s,
> AudioInterleaveContext *aic = st->priv_data;
>
> if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
> + int max_samples = samples_per_frame ? samples_per_frame : av_rescale_rnd(st->codecpar->sample_rate, time_base.num, time_base.den, AV_ROUND_UP);
Looks correct
> aic->sample_size = (st->codecpar->channels *
> av_get_bits_per_sample(st->codecpar->codec_id)) / 8;
> if (!aic->sample_size) {
> av_log(s, AV_LOG_ERROR, "could not compute sample size\n");
> return AVERROR(EINVAL);
> }
> - aic->samples_per_frame = samples_per_frame;
> - aic->samples = aic->samples_per_frame;
> aic->time_base = time_base;
> + aic->samples_per_frame = samples_per_frame;
>
> - aic->fifo_size = 100* *aic->samples;
> - if (!(aic->fifo= av_fifo_alloc_array(100, *aic->samples)))
> + aic->fifo_size = 100 * max_samples;
> + if (!(aic->fifo = av_fifo_alloc_array(100, max_samples)))
> return AVERROR(ENOMEM);
> }
> }
> @@ -81,7 +78,8 @@ static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
> AVStream *st = s->streams[stream_index];
> AudioInterleaveContext *aic = st->priv_data;
> int ret;
> - int frame_size = *aic->samples * aic->sample_size;
> + int nb_samples = aic->samples_per_frame ? aic->samples_per_frame : (av_rescale_q(aic->n + 1, av_make_q(st->codecpar->sample_rate, 1), av_inv_q(aic->time_base)) - aic->nb_samples);
Here's where the meat is. av_rescale_q() means AV_ROUND_NEAR_INF. So
basically round(). Fiddling around a bit in Octave to replicate the
logic:
octave:13> round(48000*1001/30000)
ans = 1602
octave:14> round(48000*1001/30000*2)-1602
ans = 1601
octave:15> round(48000*1001/30000*3)-(1602+1601)
ans = 1602
octave:16> round(48000*1001/30000*4)-(1602+1601+1602)
ans = 1601
octave:17> 48000*1001/30000*5-(1602+1601+1602+1601)
ans = 1602
Seems kosher. The rest of the patch looks OK.
mxfdec.c could also make use of this. Then we could remove
ff_mxf_get_samples_per_frame() and related code. Replacing
mxf_content_package_rates with a simple formula would also be nice.
/Tomas
More information about the ffmpeg-devel
mailing list