[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