diff mbox series

[FFmpeg-devel,v4,4/9] avformat/s337m: New ff_s337m_probe()

Message ID 20201002222346.1196-5-nicolas.gaullier@cji.paris
State Superseded
Headers show
Series avformat: wav-s337m support + new probe_stream option
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Nicolas Gaullier Oct. 2, 2020, 10:23 p.m. UTC
Similar to ff_spdif_probe() with just an additional checking of
the bit resolution of the container as it may be 16 or 24 for s337m.
---
 libavformat/s337m.c | 32 ++++++++++++++++++++++++++++++++
 libavformat/s337m.h | 16 ++++++++++++++++
 2 files changed, 48 insertions(+)

Comments

Carl Eugen Hoyos Oct. 3, 2020, 6:39 p.m. UTC | #1
Am Sa., 3. Okt. 2020 um 00:24 Uhr schrieb Nicolas Gaullier
<nicolas.gaullier@cji.paris>:
>
> Similar to ff_spdif_probe() with just an additional checking of
> the bit resolution of the container as it may be 16 or 24 for s337m.

Sorry if I miss something:
Why is the new function part of s337m.c?

Carl Eugen
Nicolas Gaullier Oct. 5, 2020, 10:48 a.m. UTC | #2
>> Similar to ff_spdif_probe() with just an additional checking of the 
>> bit resolution of the container as it may be 16 or 24 for s337m.
>
>Sorry if I miss something:
>Why is the new function part of s337m.c?

There is a call to static s337m_get_offset_and_codec() which is in s337m.c.
The muxer wavdec.c is the first to support it, but other muxers may come in the future, so the code must be shared.
And at the end, I don't see the point to possibly create a new s337mdec.c or so ?

Nicolas
diff mbox series

Patch

diff --git a/libavformat/s337m.c b/libavformat/s337m.c
index 790f356709..614344cd46 100644
--- a/libavformat/s337m.c
+++ b/libavformat/s337m.c
@@ -130,6 +130,38 @@  static int s337m_probe(const AVProbeData *p)
     return 0;
 }
 
+int ff_s337m_probe(const uint8_t *buf, int size, enum AVCodecID *codec, int container_word_bits)
+{
+    int pos = 0;
+    int consecutive_codes = 0;
+
+    if ( size < S337M_MIN_OFFSET)
+        return 0;
+    size = FFMIN(3 * S337M_MAX_OFFSET, size);
+    if (container_word_bits != 16 && container_word_bits != 24)
+        return AVERROR_INVALIDDATA;
+
+    do {
+        uint64_t state;
+        int data_type, data_size, offset;
+        while (pos < size - 12 && !buf[pos]) {
+            pos++;
+        }
+        if (pos >= size - 12 || pos < S337M_PROBE_GUARDBAND_MIN_BYTES || pos % (container_word_bits == 16 ? 4 : 6))
+            return 0;
+        state = container_word_bits == 16 ? AV_RB32(buf + pos) : AV_RB48(buf + pos);
+        if (!IS_LE_MARKER(state))
+            return 0;
+        data_type = container_word_bits == 16 ? AV_RL16(buf + pos + 4) : AV_RL24(buf + pos + 6);
+        data_size = container_word_bits == 16 ? AV_RL16(buf + pos + 6) : AV_RL24(buf + pos + 9);
+        if (s337m_get_offset_and_codec(NULL, state, data_type, data_size, container_word_bits, &offset, codec))
+            return 0;
+        pos = ++consecutive_codes * (offset + 4*(container_word_bits == 16 ? 4 : 6));
+    } while (consecutive_codes < 3);
+
+    return AVPROBE_SCORE_MAX;
+}
+
 static int s337m_read_header(AVFormatContext *s)
 {
     s->ctx_flags |= AVFMTCTX_NOHEADER;
diff --git a/libavformat/s337m.h b/libavformat/s337m.h
index af2c4c85a3..94e79dce5d 100644
--- a/libavformat/s337m.h
+++ b/libavformat/s337m.h
@@ -21,6 +21,22 @@ 
 #ifndef AVFORMAT_S337M_H
 #define AVFORMAT_S337M_H
 
+#define S337M_MIN_OFFSET 1601*4
+#define S337M_MAX_OFFSET 2002*6
+
+#define S337M_PROBE_GUARDBAND_MIN_BYTES     0
+
+/**
+ * Detect s337m packets in a PCM_S16LE/S24LE stereo stream
+ * Requires 3 samples with enough (S337M_PROBE_GUARDBAND_MIN_BYTES) and clean (set to zero) guard band
+ * @param p_buf Buffer
+ * @param size Buffer size
+ * @param codec Returns AV_CODEC_ID_DOLBY_E upon successful probing
+ * @param container_word_bits 16 or 24
+ * @return = AVPROBE_SCORE
+ */
+int ff_s337m_probe(const uint8_t *p_buf, int size, enum AVCodecID *codec, int container_word_bits);
+
 /**
  * Read s337m packets in a PCM_S16LE/S24LE stereo stream
  * Returns the first inner packet found