[FFmpeg-devel] [PATCH 7/9] avformat/pcm: use a common default packet size function for both wav and pcm

Marton Balint cus at passwd.hu
Wed Mar 6 00:51:45 EET 2024


Signed-off-by: Marton Balint <cus at passwd.hu>
---
 libavformat/pcm.c    | 38 ++++++++++++++++++++++++++------------
 libavformat/pcm.h    |  1 +
 libavformat/wavdec.c | 11 ++---------
 3 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/libavformat/pcm.c b/libavformat/pcm.c
index 9741f73667..b3d23110ab 100644
--- a/libavformat/pcm.c
+++ b/libavformat/pcm.c
@@ -24,26 +24,40 @@
 #include "internal.h"
 #include "pcm.h"
 
-#define RAW_SAMPLES     1024
+#define PCM_DEMUX_TARGET_FPS  25
+#define PCM_DEMUX_MAX_SAMPLES 1024
 
-int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt)
+int ff_pcm_default_packet_size(AVCodecParameters *par)
 {
-    AVCodecParameters *par = s->streams[0]->codecpar;
-    int ret, size;
+    int nb_samples, max_samples;
 
     if (par->block_align <= 0)
         return AVERROR(EINVAL);
 
+    if (par->ch_layout.nb_channels <= 0)
+        return AVERROR(EINVAL);
+
+    /* Unusually large block_align means a non-pcm codec */
+    if (par->block_align > 8LL * par->ch_layout.nb_channels)
+        return AVERROR(EINVAL);
+
     /*
-     * Compute read size to complete a read every 62ms.
-     * Clamp to RAW_SAMPLES if larger.
+     * Compute read size based on PCM_DEMUX_TARGET_FPS
+     * Clamp to PCM_DEMUX_MAX_SAMPLES if larger.
      */
-    size = FFMAX(par->sample_rate/25, 1);
-    if (par->block_align <= INT_MAX / RAW_SAMPLES) {
-        size = FFMIN(size, RAW_SAMPLES) * par->block_align;
-    } else {
-        size = par->block_align;
-    }
+    max_samples = FFMIN(PCM_DEMUX_MAX_SAMPLES, INT_MAX / par->block_align);
+    nb_samples = av_clip(par->sample_rate / PCM_DEMUX_TARGET_FPS, 1, max_samples);
+
+    return par->block_align * nb_samples;
+}
+
+int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret, size;
+
+    size = ff_pcm_default_packet_size(s->streams[0]->codecpar);
+    if (size < 0)
+        return size;
 
     ret = av_get_packet(s->pb, pkt, size);
 
diff --git a/libavformat/pcm.h b/libavformat/pcm.h
index 9af36d5a2e..1928497eed 100644
--- a/libavformat/pcm.h
+++ b/libavformat/pcm.h
@@ -24,6 +24,7 @@
 
 #include "avformat.h"
 
+int ff_pcm_default_packet_size(AVCodecParameters *par);
 int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt);
 int ff_pcm_read_seek(AVFormatContext *s,
                      int stream_index, int64_t timestamp, int flags);
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 5ceb8bef23..61b4b12dc5 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -80,15 +80,8 @@ static const AVOption demux_options[] = {
 static void set_max_size(AVStream *st, WAVDemuxContext *wav)
 {
     if (wav->max_size <= 0) {
-        int64_t nb_samples = av_clip(st->codecpar->sample_rate / 25, 1, 1024);
-        if (st->codecpar->block_align > 0 &&
-            st->codecpar->block_align * nb_samples < INT_MAX &&
-            st->codecpar->ch_layout.nb_channels > 0 &&
-            st->codecpar->block_align <= 8LL * st->codecpar->ch_layout.nb_channels) {
-            wav->max_size = st->codecpar->block_align * nb_samples;
-        } else {
-            wav->max_size = 4096;
-        }
+        int max_size = ff_pcm_default_packet_size(st->codecpar);
+        wav->max_size = max_size < 0 ? 4096 : max_size;
     }
 }
 
-- 
2.35.3



More information about the ffmpeg-devel mailing list