[FFmpeg-devel] [PATCH] avformat: Add image3 demuxers with format autodetection

Michael Niedermayer michaelni at gmx.at
Mon Jun 30 03:44:17 CEST 2014


From: Carl Eugen Hoyos <cehoyos at ag.or.at>

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 Changelog                |    1 +
 libavformat/Makefile     |    8 +++
 libavformat/allformats.c |   11 ++++
 libavformat/img2dec.c    |  137 +++++++++++++++++++++++++++++++++++++++++++++-
 libavformat/version.h    |    2 +-
 5 files changed, 157 insertions(+), 2 deletions(-)

diff --git a/Changelog b/Changelog
index 0346877..3013c25 100644
--- a/Changelog
+++ b/Changelog
@@ -30,6 +30,7 @@ version <next>:
 - zoompan filter
 - signalstats filter
 - hqx filter (hq2x, hq3x, hq4x)
+- Image format auto-detection
 
 
 version 2.2:
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 46aac96..857bfbb 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -187,6 +187,14 @@ OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER)        += img2dec.o img2.o
 OBJS-$(CONFIG_IMAGE2PIPE_MUXER)          += img2enc.o img2.o
 OBJS-$(CONFIG_IMAGE2_ALIAS_PIX_DEMUXER)  += img2_alias_pix.o
 OBJS-$(CONFIG_IMAGE2_BRENDER_PIX_DEMUXER) += img2_brender_pix.o
+OBJS-$(CONFIG_IMAGE_BMP_PIPE_DEMUXER)     += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_DPX_PIPE_DEMUXER)     += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_EXR_PIPE_DEMUXER)     += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_PICTOR_PIPE_DEMUXER)  += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_PNG_PIPE_DEMUXER)     += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_SGI_PIPE_DEMUXER)     += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER) += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_TIFF_PIPE_DEMUXER)    += img2dec.o img2.o
 OBJS-$(CONFIG_INGENIENT_DEMUXER)         += ingenientdec.o rawdec.o
 OBJS-$(CONFIG_IPMOVIE_DEMUXER)           += ipmovie.o
 OBJS-$(CONFIG_IRCAM_DEMUXER)             += ircamdec.o ircam.o pcm.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index dc5557c..dbde432 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -318,6 +318,17 @@ void av_register_all(void)
     REGISTER_DEMUXER (YOP,              yop);
     REGISTER_MUXDEMUX(YUV4MPEGPIPE,     yuv4mpegpipe);
 
+    /* image demuxers */
+    REGISTER_DEMUXER (IMAGE_BMP_PIPE,        image_bmp_pipe);
+    REGISTER_DEMUXER (IMAGE_DPX_PIPE,        image_dpx_pipe);
+    REGISTER_DEMUXER (IMAGE_EXR_PIPE,        image_exr_pipe);
+    REGISTER_DEMUXER (IMAGE_PICTOR_PIPE,     image_pictor_pipe);
+    REGISTER_DEMUXER (IMAGE_PNG_PIPE,        image_png_pipe);
+    REGISTER_DEMUXER (IMAGE_SGI_PIPE,        image_sgi_pipe);
+    REGISTER_DEMUXER (IMAGE_SUNRAST_PIPE,    image_sunrast_pipe);
+    REGISTER_DEMUXER (IMAGE_TIFF_PIPE,       image_tiff_pipe);
+
+
     /* protocols */
     REGISTER_PROTOCOL(BLURAY,           bluray);
     REGISTER_PROTOCOL(CACHE,            cache);
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index dc962db..6fa6157 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -27,6 +27,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/parseutils.h"
+#include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
 #include "img2.h"
@@ -302,7 +303,34 @@ int ff_img_read_header(AVFormatContext *s1)
         const char *str = strrchr(s->path, '.');
         s->split_planes       = str && !av_strcasecmp(str + 1, "y");
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-        st->codec->codec_id   = ff_guess_image2_codec(s->path);
+        if (s1->pb) {
+            struct image_probe *probe;
+            uint8_t probe_buffer[AVPROBE_PADDING_SIZE] = {0};
+            AVInputFormat *fmt = NULL;
+            AVProbeData pd;
+            int ret = avio_read(s1->pb, probe_buffer, 8);
+            if (ret < 8)
+                return AVERROR(EINVAL);
+            avio_seek(s1->pb, -8, SEEK_CUR);
+
+            pd.buf = probe_buffer;
+            pd.buf_size = 8;
+            pd.filename = s1->filename;
+
+            while ((fmt = av_iformat_next(fmt))) {
+                if (fmt->read_header != ff_img_read_header ||
+                    !fmt->read_probe ||
+                    (fmt->flags & AVFMT_NOFILE) ||
+                    !fmt->raw_codec_id)
+                    continue;
+                if (fmt->read_probe(&pd) > 0) {
+                    st->codec->codec_id = fmt->raw_codec_id;
+                    break;
+                }
+            }
+        }
+        if (st->codec->codec_id == AV_CODEC_ID_NONE)
+            st->codec->codec_id = ff_guess_image2_codec(s->path);
         if (st->codec->codec_id == AV_CODEC_ID_LJPEG)
             st->codec->codec_id = AV_CODEC_ID_MJPEG;
         if (st->codec->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distingiush this from BRENDER_PIX
@@ -522,3 +550,110 @@ AVInputFormat ff_image2pipe_demuxer = {
     .priv_class     = &img2pipe_class,
 };
 #endif
+
+static int bmp_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RB16(b) == 0x424d)
+        if (!AV_RN32(p + 6)) {
+            return AVPROBE_SCORE_EXTENSION + 1;
+        } else {
+            return AVPROBE_SCORE_EXTENSION / 4;
+        }
+    return 0;
+}
+
+static int dpx_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RN32(b) == AV_RN32("SDPX") || AV_RN32(b) == AV_RN32("XPDS"))
+        return AVPROBE_SCORE_EXTENSION + 1;
+    return 0;
+}
+
+static int exr_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RL32(b) == 20000630)
+        return AVPROBE_SCORE_EXTENSION + 1;
+    return 0;
+}
+
+static int pictor_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RL16(b) == 0x1234)
+        return AVPROBE_SCORE_EXTENSION / 4;
+    return 0;
+}
+
+static int png_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RB64(b) == 0x89504e470d0a1a0a)
+        return AVPROBE_SCORE_MAX - 1;
+    return 0;
+}
+
+static int sgi_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RB16(b) == 474 &&
+        (b[2] & ~1) == 0 &&
+        (b[3] & ~3) == 0 && b[3] &&
+        (AV_RB16(b + 4) & ~7) == 0 && AV_RB16(b + 4))
+        return AVPROBE_SCORE_EXTENSION + 1;
+    return 0;
+}
+
+static int sunrast_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RB32(b) == 0x59a66a95)
+        return AVPROBE_SCORE_EXTENSION + 1;
+    return 0;
+}
+
+static int tiff_probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (AV_RB32(b) == 0x49492a00)
+        return AVPROBE_SCORE_EXTENSION + 1;
+    return 0;
+}
+
+#define IMAGEAUTO_DEMUXER(imgname, codecid)\
+static const AVClass imgname ## _class = {\
+    .class_name = AV_STRINGIFY(imgname) " demuxer",\
+    .item_name  = av_default_item_name,\
+    .option     = options,\
+    .version    = LIBAVUTIL_VERSION_INT,\
+};\
+AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
+    .name           = AV_STRINGIFY(imgname) "_pipe",\
+    .priv_data_size = sizeof(VideoDemuxData),\
+    .read_probe     = imgname ## _probe,\
+    .read_header    = ff_img_read_header,\
+    .read_packet    = ff_img_read_packet,\
+    .read_close     = img_read_close,\
+    .read_seek      = img_read_seek,\
+    .priv_class     = & imgname ## _class,\
+    .raw_codec_id   = codecid,\
+};
+
+IMAGEAUTO_DEMUXER(bmp,     AV_CODEC_ID_BMP)
+IMAGEAUTO_DEMUXER(dpx,     AV_CODEC_ID_DPX)
+IMAGEAUTO_DEMUXER(exr,     AV_CODEC_ID_EXR)
+IMAGEAUTO_DEMUXER(pictor,  AV_CODEC_ID_PICTOR)
+IMAGEAUTO_DEMUXER(png,     AV_CODEC_ID_PNG)
+IMAGEAUTO_DEMUXER(sgi,     AV_CODEC_ID_SGI)
+IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST)
+IMAGEAUTO_DEMUXER(tiff,    AV_CODEC_ID_TIFF)
diff --git a/libavformat/version.h b/libavformat/version.h
index 67393e0..a5b24bf 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,7 +30,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR 44
+#define LIBAVFORMAT_VERSION_MINOR 45
 #define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list