From d538dd824ee7abf9f3bb6459485f3e804fcc4777 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 21 Jun 2014 21:43:19 +0200 Subject: [PATCH] avformat: Add image3 demuxers with format autodetection Reviewed-by: wm4 Signed-off-by: Michael Niedermayer --- Changelog | 1 + libavformat/Makefile | 8 +++ libavformat/allformats.c | 11 ++++ libavformat/img2dec.c | 138 ++++++++++++++++++++++++++++++++++++++- libavformat/version.h | 2 +- 5 files changed, 158 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 69f928d011..87448f3e52 100644 --- a/Changelog +++ b/Changelog @@ -31,6 +31,7 @@ version : - signalstats filter - hqx filter (hq2x, hq3x, hq4x) - flanger filter +- Image format auto-detection version 2.2: diff --git a/libavformat/Makefile b/libavformat/Makefile index 17c30a6cb7..b42c823fe9 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 dc5557c091..dbde4325e1 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 dc962dbb33..a8f87efb67 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,33 @@ 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) { + 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 @@ -387,6 +414,8 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) return AVERROR(EIO); if (s->frame_size > 0) { size[0] = s->frame_size; + } else if (!s1->streams[0]->parser) { + size[0] = avio_size(s1->pb); } else { size[0] = 4096; } @@ -522,3 +551,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(b + 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 67393e051e..a5b24bf621 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, \