diff mbox series

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

Message ID 20240305225147.6849-7-cus@passwd.hu
State New
Headers show
Series [FFmpeg-devel,1/9] avcodec/bsf/pcm_rechunk: reorder supported codec list | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Marton Balint March 5, 2024, 10:51 p.m. UTC
Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavformat/pcm.c    | 38 ++++++++++++++++++++++++++------------
 libavformat/pcm.h    |  1 +
 libavformat/wavdec.c | 11 ++---------
 3 files changed, 29 insertions(+), 21 deletions(-)

Comments

Michael Niedermayer March 6, 2024, 8:37 p.m. UTC | #1
On Tue, Mar 05, 2024 at 11:51:45PM +0100, Marton Balint wrote:
> Signed-off-by: Marton Balint <cus@passwd.hu>
> ---
>  libavformat/pcm.c    | 38 ++++++++++++++++++++++++++------------
>  libavformat/pcm.h    |  1 +
>  libavformat/wavdec.c | 11 ++---------
>  3 files changed, 29 insertions(+), 21 deletions(-)

breaks:

./ffmpeg -i H8Le.xmd -bitexact -f framecrc -

[in#0/xmd @ 0x55737c355980] Error during demuxing: Invalid argument
[aost#0:0/pcm_s16le @ 0x55737c35a0c0] No filtered frames for output stream, trying to initialize anyway.
#tb 0: 1/44100
#media_type 0: audio
#codec_id 0: pcm_s16le
#sample_rate 0: 44100
#channel_layout_name 0: stereo
Output #0, framecrc, to 'pipe:':
  Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
      Metadata:
        encoder         : Lavc pcm_s16le
[out#0/framecrc @ 0x55737c357e80] video:0KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
[out#0/framecrc @ 0x55737c357e80] Output file is empty, nothing was encoded(check -ss / -t / -frames parameters if used)
size=       0KiB time=N/A bitrate=N/A speed=N/A

file is here: https://0x0.st/H8Le.xmd

thx

[...]
diff mbox series

Patch

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;
     }
 }