X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fimg2dec.c;h=40f3e3d499eed341d4714b1ff2c81f61e36e3058;hb=a07b19d9af6377beac5630cb49065ede426c4fee;hp=ff4757e5322ee25a456f82537b8efeb1a16ba2c1;hpb=94d98330ed6c5562341315c26c1af92771a2e6de;p=ffmpeg diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index ff4757e5322..40f3e3d499e 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -29,6 +29,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/parseutils.h" #include "libavutil/intreadwrite.h" +#include "libavcodec/gif.h" #include "avformat.h" #include "avio_internal.h" #include "internal.h" @@ -159,7 +160,7 @@ fail: return -1; } -static int img_read_probe(AVProbeData *p) +static int img_read_probe(const AVProbeData *p) { if (p->filename && ff_guess_image2_codec(p->filename)) { if (av_filename_number_test(p->filename)) @@ -355,6 +356,7 @@ int ff_img_read_header(AVFormatContext *s1) } if (s1->flags & AVFMT_FLAG_CUSTOM_IO) { avio_seek(s1->pb, 0, SEEK_SET); + av_freep(&probe_buffer); } else ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); } @@ -372,6 +374,33 @@ int ff_img_read_header(AVFormatContext *s1) return 0; } +/** + * Add this frame's source path and basename to packet's sidedata + * as a dictionary, so it can be used by filters like 'drawtext'. + */ +static int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) { + uint8_t* metadata; + int metadata_len; + AVDictionary *d = NULL; + char *packed_metadata = NULL; + + av_dict_set(&d, "lavf.image2dec.source_path", filename, 0); + av_dict_set(&d, "lavf.image2dec.source_basename", av_basename(filename), 0); + + packed_metadata = av_packet_pack_dictionary(d, &metadata_len); + av_dict_free(&d); + if (!packed_metadata) + return AVERROR(ENOMEM); + if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) { + av_freep(&packed_metadata); + return AVERROR(ENOMEM); + } + memcpy(metadata, packed_metadata, metadata_len); + av_freep(&packed_metadata); + + return 0; +} + int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; @@ -423,7 +452,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) if (par->codec_id == AV_CODEC_ID_NONE) { AVProbeData pd = { 0 }; - AVInputFormat *ifmt; + const AVInputFormat *ifmt; uint8_t header[PROBE_BUF_MIN + AVPROBE_PADDING_SIZE]; int ret; int score = 0; @@ -484,6 +513,17 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) if (s->is_pipe) pkt->pos = avio_tell(f[0]); + /* + * export_path_metadata must be explicitly enabled via + * command line options for path metadata to be exported + * as packet side_data. + */ + if (!s->is_pipe && s->export_path_metadata == 1) { + res = add_filename_as_pkt_side_data(filename, pkt); + if (res < 0) + goto fail; + } + pkt->size = 0; for (i = 0; i < 3; i++) { if (f[i]) { @@ -502,7 +542,6 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { - av_packet_unref(pkt); if (ret[0] < 0) { res = ret[0]; } else if (ret[1] < 0) { @@ -563,29 +602,30 @@ static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp #define OFFSET(x) offsetof(VideoDemuxData, x) #define DEC AV_OPT_FLAG_DECODING_PARAM -const AVOption ff_img_options[] = { - { "framerate", "set the video framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC }, - { "loop", "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, +#define COMMON_OPTIONS \ + { "framerate", "set the video framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC }, \ + { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \ + { "video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC }, \ + { "loop", "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, \ + { NULL }, +#if CONFIG_IMAGE2_DEMUXER +const AVOption ff_img_options[] = { { "pattern_type", "set pattern type", OFFSET(pattern_type), AV_OPT_TYPE_INT, {.i64=PT_DEFAULT}, 0, INT_MAX, DEC, "pattern_type"}, { "glob_sequence","select glob/sequence pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX, DEC, "pattern_type" }, { "glob", "select glob pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_GLOB }, INT_MIN, INT_MAX, DEC, "pattern_type" }, { "sequence", "select sequence pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_SEQUENCE }, INT_MIN, INT_MAX, DEC, "pattern_type" }, { "none", "disable pattern matching", 0, AV_OPT_TYPE_CONST, {.i64=PT_NONE }, INT_MIN, INT_MAX, DEC, "pattern_type" }, - - { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, { "start_number", "set first number in the sequence", OFFSET(start_number), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, DEC }, { "start_number_range", "set range for looking at the first sequence number", OFFSET(start_number_range), AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX, DEC }, - { "video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC }, - { "frame_size", "force frame size in bytes", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC }, { "ts_from_file", "set frame timestamp from file's one", OFFSET(ts_from_file), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, DEC, "ts_type" }, { "none", "none", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 2, DEC, "ts_type" }, { "sec", "second precision", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 2, DEC, "ts_type" }, { "ns", "nano second precision", 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 2, DEC, "ts_type" }, - { NULL }, + { "export_path_metadata", "enable metadata containing input path information", OFFSET(export_path_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, \ + COMMON_OPTIONS }; -#if CONFIG_IMAGE2_DEMUXER static const AVClass img2_class = { .class_name = "image2 demuxer", .item_name = av_default_item_name, @@ -605,11 +645,17 @@ AVInputFormat ff_image2_demuxer = { .priv_class = &img2_class, }; #endif + +const AVOption ff_img2pipe_options[] = { + { "frame_size", "force frame size in bytes", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC }, + COMMON_OPTIONS +}; + #if CONFIG_IMAGE2PIPE_DEMUXER static const AVClass img2pipe_class = { .class_name = "image2pipe demuxer", .item_name = av_default_item_name, - .option = ff_img_options, + .option = ff_img2pipe_options, .version = LIBAVUTIL_VERSION_INT, }; AVInputFormat ff_image2pipe_demuxer = { @@ -622,7 +668,7 @@ AVInputFormat ff_image2pipe_demuxer = { }; #endif -static int bmp_probe(AVProbeData *p) +static int bmp_probe(const AVProbeData *p) { const uint8_t *b = p->buf; int ihsize; @@ -640,7 +686,7 @@ static int bmp_probe(AVProbeData *p) return AVPROBE_SCORE_EXTENSION / 4; } -static int dds_probe(AVProbeData *p) +static int dds_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -651,7 +697,7 @@ static int dds_probe(AVProbeData *p) return 0; } -static int dpx_probe(AVProbeData *p) +static int dpx_probe(const AVProbeData *p) { const uint8_t *b = p->buf; int w, h; @@ -669,7 +715,7 @@ static int dpx_probe(AVProbeData *p) return 0; } -static int exr_probe(AVProbeData *p) +static int exr_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -678,7 +724,7 @@ static int exr_probe(AVProbeData *p) return 0; } -static int j2k_probe(AVProbeData *p) +static int j2k_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -688,7 +734,7 @@ static int j2k_probe(AVProbeData *p) return 0; } -static int jpeg_probe(AVProbeData *p) +static int jpeg_probe(const AVProbeData *p) { const uint8_t *b = p->buf; int i, state = SOI; @@ -763,7 +809,7 @@ static int jpeg_probe(AVProbeData *p) return AVPROBE_SCORE_EXTENSION / 8; } -static int jpegls_probe(AVProbeData *p) +static int jpegls_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -772,7 +818,7 @@ static int jpegls_probe(AVProbeData *p) return 0; } -static int pcx_probe(AVProbeData *p) +static int pcx_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -793,7 +839,7 @@ static int pcx_probe(AVProbeData *p) return AVPROBE_SCORE_EXTENSION + 1; } -static int qdraw_probe(AVProbeData *p) +static int qdraw_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -809,7 +855,7 @@ static int qdraw_probe(AVProbeData *p) return 0; } -static int pictor_probe(AVProbeData *p) +static int pictor_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -818,7 +864,7 @@ static int pictor_probe(AVProbeData *p) return 0; } -static int png_probe(AVProbeData *p) +static int png_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -827,7 +873,7 @@ static int png_probe(AVProbeData *p) return 0; } -static int psd_probe(AVProbeData *p) +static int psd_probe(const AVProbeData *p) { const uint8_t *b = p->buf; int ret = 0; @@ -855,7 +901,7 @@ static int psd_probe(AVProbeData *p) return AVPROBE_SCORE_EXTENSION + ret; } -static int sgi_probe(AVProbeData *p) +static int sgi_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -867,7 +913,7 @@ static int sgi_probe(AVProbeData *p) return 0; } -static int sunrast_probe(AVProbeData *p) +static int sunrast_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -876,7 +922,7 @@ static int sunrast_probe(AVProbeData *p) return 0; } -static int svg_probe(AVProbeData *p) +static int svg_probe(const AVProbeData *p) { const uint8_t *b = p->buf; const uint8_t *end = p->buf + p->buf_size; @@ -896,7 +942,7 @@ static int svg_probe(AVProbeData *p) return 0; } -static int tiff_probe(AVProbeData *p) +static int tiff_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -906,7 +952,7 @@ static int tiff_probe(AVProbeData *p) return 0; } -static int webp_probe(AVProbeData *p) +static int webp_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -934,39 +980,39 @@ static inline int pnm_probe(const AVProbeData *p) return 0; } -static int pbm_probe(AVProbeData *p) +static int pbm_probe(const AVProbeData *p) { return pnm_magic_check(p, 1) || pnm_magic_check(p, 4) ? pnm_probe(p) : 0; } -static inline int pgmx_probe(AVProbeData *p) +static inline int pgmx_probe(const AVProbeData *p) { return pnm_magic_check(p, 2) || pnm_magic_check(p, 5) ? pnm_probe(p) : 0; } -static int pgm_probe(AVProbeData *p) +static int pgm_probe(const AVProbeData *p) { int ret = pgmx_probe(p); return ret && !av_match_ext(p->filename, "pgmyuv") ? ret : 0; } -static int pgmyuv_probe(AVProbeData *p) // custom FFmpeg format recognized by file extension +static int pgmyuv_probe(const AVProbeData *p) // custom FFmpeg format recognized by file extension { int ret = pgmx_probe(p); return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0; } -static int ppm_probe(AVProbeData *p) +static int ppm_probe(const AVProbeData *p) { return pnm_magic_check(p, 3) || pnm_magic_check(p, 6) ? pnm_probe(p) : 0; } -static int pam_probe(AVProbeData *p) +static int pam_probe(const AVProbeData *p) { return pnm_magic_check(p, 7) ? pnm_probe(p) : 0; } -static int xpm_probe(AVProbeData *p) +static int xpm_probe(const AVProbeData *p) { const uint8_t *b = p->buf; @@ -975,7 +1021,7 @@ static int xpm_probe(AVProbeData *p) return 0; } -static int xwd_probe(AVProbeData *p) +static int xwd_probe(const AVProbeData *p) { const uint8_t *b = p->buf; unsigned width, bpp, bpad, lsize; @@ -1005,11 +1051,24 @@ static int xwd_probe(AVProbeData *p) return AVPROBE_SCORE_MAX / 2 + 1; } +static int gif_probe(const AVProbeData *p) +{ + /* check magick */ + if (memcmp(p->buf, gif87a_sig, 6) && memcmp(p->buf, gif89a_sig, 6)) + return 0; + + /* width or height contains zero? */ + if (!AV_RL16(&p->buf[6]) || !AV_RL16(&p->buf[8])) + return 0; + + return AVPROBE_SCORE_MAX - 1; +} + #define IMAGEAUTO_DEMUXER(imgname, codecid)\ static const AVClass imgname ## _class = {\ .class_name = AV_STRINGIFY(imgname) " demuxer",\ .item_name = av_default_item_name,\ - .option = ff_img_options,\ + .option = ff_img2pipe_options,\ .version = LIBAVUTIL_VERSION_INT,\ };\ AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\ @@ -1028,6 +1087,7 @@ IMAGEAUTO_DEMUXER(bmp, AV_CODEC_ID_BMP) IMAGEAUTO_DEMUXER(dds, AV_CODEC_ID_DDS) IMAGEAUTO_DEMUXER(dpx, AV_CODEC_ID_DPX) IMAGEAUTO_DEMUXER(exr, AV_CODEC_ID_EXR) +IMAGEAUTO_DEMUXER(gif, AV_CODEC_ID_GIF) IMAGEAUTO_DEMUXER(j2k, AV_CODEC_ID_JPEG2000) IMAGEAUTO_DEMUXER(jpeg, AV_CODEC_ID_MJPEG) IMAGEAUTO_DEMUXER(jpegls, AV_CODEC_ID_JPEGLS)