[FFmpeg-devel] [PATCH 2/3] avformat: Support s337m in mxf/wav/w64

Nicolas Gaullier nicolas.gaullier at arkena.com
Fri Jul 26 19:45:16 EEST 2019


---
 libavformat/avformat.h      |  7 +++++++
 libavformat/mxfdec.c        | 20 +++++++++++++++++++-
 libavformat/options_table.h |  1 +
 libavformat/wavdec.c        |  7 ++++++-
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 6eb329f13f..42bb094d81 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1951,6 +1951,13 @@ typedef struct AVFormatContext {
      * - decoding: set by user
      */
     int skip_estimate_duration_from_pts;
+
+    /**
+     * Probe dolby_e in PCM streams
+     * - encoding: unused
+     * - decoding: set by user
+     */
+    int dolby_e_probe;
 } AVFormatContext;
 
 #if FF_API_FORMAT_GET_SET
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index bb72fb9841..5b6eb9d756 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -56,6 +56,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "mxf.h"
+#include "s337m.h"
 
 #define MXF_MAX_CHUNK_SIZE (32 << 20)
 
@@ -302,6 +303,8 @@ typedef struct MXFMetadataReadTableEntry {
     enum MXFMetadataSetType type;
 } MXFMetadataReadTableEntry;
 
+static int mxf_read_packet_init = 0;
+static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt);
 static int mxf_read_close(AVFormatContext *s);
 
 /* partial keys to match */
@@ -3247,6 +3250,19 @@ static int mxf_read_header(AVFormatContext *s)
     if ((ret = mxf_parse_structural_metadata(mxf)) < 0)
         goto fail;
 
+    if (mxf->fc->dolby_e_probe)
+    {
+        int i;
+        AVPacket *pkt = av_packet_alloc();
+        av_init_packet(pkt);
+        mxf_read_packet_init = 1;
+        for (i = 0; i < mxf->fc->nb_streams; i++)
+            mxf_read_packet(mxf->fc, pkt);
+        mxf_read_packet_init = 0;
+        av_freep(pkt);
+        avio_seek(s->pb, essence_offset, SEEK_SET);
+    }
+
     for (int i = 0; i < s->nb_streams; i++)
         mxf_handle_missing_index_segment(mxf, s->streams[i]);
 
@@ -3539,7 +3555,9 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
                     return ret;
                 }
             } else {
-                ret = av_get_packet(s->pb, pkt, klv.length);
+                if (mxf_read_packet_init)
+                    s337m_probe_stream(mxf->fc, &st);
+                ret = st->codecpar->codec_id == AV_CODEC_ID_DOLBY_E ? s337m_read_packet(s, pkt) : av_get_packet(s->pb, pkt, klv.length);
                 if (ret < 0) {
                     mxf->current_klv_data = (KLVPacket){{0}};
                     return ret;
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index f2f077b34f..7f3c22d6bb 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -111,6 +111,7 @@ static const AVOption avformat_options[] = {
 {"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL },  CHAR_MIN, CHAR_MAX, D },
 {"max_streams", "maximum number of streams", OFFSET(max_streams), AV_OPT_TYPE_INT, { .i64 = 1000 }, 0, INT_MAX, D },
 {"skip_estimate_duration_from_pts", "skip duration calculation in estimate_timings_from_pts", OFFSET(skip_estimate_duration_from_pts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, D},
+{"dolbyeprobe", "probe dolby_e in PCM streams", OFFSET(dolby_e_probe), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, D},
 {NULL},
 };
 
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 52194f54ef..501c21f220 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -41,6 +41,7 @@
 #include "riff.h"
 #include "w64.h"
 #include "spdif.h"
+#include "s337m.h"
 
 typedef struct WAVDemuxContext {
     const AVClass *class;
@@ -593,6 +594,8 @@ break_loop:
     } else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS && st->codecpar->channels > 2) {
         st->codecpar->block_align *= st->codecpar->channels;
     }
+    if (s->dolby_e_probe)
+        s337m_probe_stream(s, &st);
 
     ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
     ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
@@ -708,7 +711,7 @@ smv_out:
         size = (size / st->codecpar->block_align) * st->codecpar->block_align;
     }
     size = FFMIN(size, left);
-    ret  = av_get_packet(s->pb, pkt, size);
+    ret  = st->codecpar->codec_id == AV_CODEC_ID_DOLBY_E ? s337m_read_packet(s, pkt) : av_get_packet(s->pb, pkt, size);
     if (ret < 0)
         return ret;
     pkt->stream_index = 0;
@@ -895,6 +898,8 @@ static int w64_read_header(AVFormatContext *s)
     st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     avio_seek(pb, data_ofs, SEEK_SET);
+    if (s->dolby_e_probe)
+        s337m_probe_stream(s, &st);
 
     set_spdif(s, wav);
 
-- 
2.14.1.windows.1



More information about the ffmpeg-devel mailing list