]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/img2dec.c
configure: add -lvulkan to libglslang's lib flags
[ffmpeg] / libavformat / img2dec.c
index ecec4988b22fb5a328dd23db1f426cc8cdddcfb0..d7a7cdaa169747d8e815abe02dbb2a77fe9d8fcb 100644 (file)
@@ -160,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))
@@ -220,8 +220,10 @@ int ff_img_read_header(AVFormatContext *s1)
         avpriv_set_pts_info(st, 64, 1, 1000000000);
     } else if (s->ts_from_file)
         avpriv_set_pts_info(st, 64, 1, 1);
-    else
+    else {
         avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num);
+        st->avg_frame_rate = st->r_frame_rate = s->framerate;
+    }
 
     if (s->width && s->height) {
         st->codecpar->width  = s->width;
@@ -356,6 +358,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);
         }
@@ -373,6 +376,32 @@ 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) {
+    AVDictionary *d = NULL;
+    char *packed_metadata = NULL;
+    size_t metadata_len;
+    int ret;
+
+    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);
+    ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
+                                  packed_metadata, metadata_len);
+    if (ret < 0) {
+        av_freep(&packed_metadata);
+        return ret;
+    }
+    return 0;
+}
+
 int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
 {
     VideoDemuxData *s = s1->priv_data;
@@ -424,7 +453,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;
@@ -485,6 +514,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]) {
@@ -503,7 +543,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) {
@@ -551,7 +590,7 @@ static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
         int index = av_index_search_timestamp(st, timestamp, flags);
         if(index < 0)
             return -1;
-        s1->img_number = st->index_entries[index].pos;
+        s1->img_number = st->internal->index_entries[index].pos;
         return 0;
     }
 
@@ -584,6 +623,7 @@ const AVOption ff_img_options[] = {
     { "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" },
+    { "export_path_metadata", "enable metadata containing input path information", OFFSET(export_path_metadata), AV_OPT_TYPE_BOOL,   {.i64 = 0   }, 0, 1,       DEC }, \
     COMMON_OPTIONS
 };
 
@@ -593,7 +633,7 @@ static const AVClass img2_class = {
     .option     = ff_img_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
-AVInputFormat ff_image2_demuxer = {
+const AVInputFormat ff_image2_demuxer = {
     .name           = "image2",
     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
     .priv_data_size = sizeof(VideoDemuxData),
@@ -619,7 +659,7 @@ static const AVClass img2pipe_class = {
     .option     = ff_img2pipe_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
-AVInputFormat ff_image2pipe_demuxer = {
+const AVInputFormat ff_image2pipe_demuxer = {
     .name           = "image2pipe",
     .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
     .priv_data_size = sizeof(VideoDemuxData),
@@ -629,7 +669,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;
@@ -647,7 +687,18 @@ static int bmp_probe(AVProbeData *p)
     return AVPROBE_SCORE_EXTENSION / 4;
 }
 
-static int dds_probe(AVProbeData *p)
+static int cri_probe(const AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (   AV_RL32(b) == 1
+        && AV_RL32(b + 4) == 4
+        && AV_RN32(b + 8) == AV_RN32("DVCC"))
+        return AVPROBE_SCORE_MAX - 1;
+    return 0;
+}
+
+static int dds_probe(const AVProbeData *p)
 {
     const uint8_t *b = p->buf;
 
@@ -658,7 +709,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;
@@ -676,7 +727,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;
 
@@ -685,7 +736,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;
 
@@ -695,7 +746,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;
@@ -767,10 +818,10 @@ static int jpeg_probe(AVProbeData *p)
         return AVPROBE_SCORE_EXTENSION + 1;
     if (state == SOS)
         return AVPROBE_SCORE_EXTENSION / 2;
-    return AVPROBE_SCORE_EXTENSION / 8;
+    return AVPROBE_SCORE_EXTENSION / 8 + 1;
 }
 
-static int jpegls_probe(AVProbeData *p)
+static int jpegls_probe(const AVProbeData *p)
 {
     const uint8_t *b = p->buf;
 
@@ -779,7 +830,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;
 
@@ -800,7 +851,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;
 
@@ -816,7 +867,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;
 
@@ -825,7 +876,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;
 
@@ -834,7 +885,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;
@@ -862,7 +913,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;
 
@@ -874,7 +925,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;
 
@@ -883,7 +934,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;
@@ -903,7 +954,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;
 
@@ -913,7 +964,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;
 
@@ -941,39 +992,57 @@ 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;
+    return pnm_magic_check(p, 1) || pnm_magic_check(p, 4) || pnm_magic_check(p, 22) || pnm_magic_check(p, 54) ? 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 pgx_probe(const AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+    if (!memcmp(b, "PG ML ", 6))
+        return AVPROBE_SCORE_EXTENSION + 1;
+    return 0;
+}
+
+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 xbm_probe(const AVProbeData *p)
+{
+    if (!memcmp(p->buf, "/* XBM X10 format */", 20))
+        return AVPROBE_SCORE_MAX;
+
+    if (!memcmp(p->buf, "#define", 7))
+        return AVPROBE_SCORE_MAX - 1;
+    return 0;
+}
+
+static int xpm_probe(const AVProbeData *p)
 {
     const uint8_t *b = p->buf;
 
@@ -982,7 +1051,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;
@@ -1012,7 +1081,7 @@ static int xwd_probe(AVProbeData *p)
     return AVPROBE_SCORE_MAX / 2 + 1;
 }
 
-static int gif_probe(AVProbeData *p)
+static int gif_probe(const AVProbeData *p)
 {
     /* check magick */
     if (memcmp(p->buf, gif87a_sig, 6) && memcmp(p->buf, gif89a_sig, 6))
@@ -1025,6 +1094,17 @@ static int gif_probe(AVProbeData *p)
     return AVPROBE_SCORE_MAX - 1;
 }
 
+static int photocd_probe(const AVProbeData *p)
+{
+    if (!memcmp(p->buf, "PCD_OPA", 7))
+        return AVPROBE_SCORE_MAX - 1;
+
+    if (p->buf_size < 0x807 || memcmp(p->buf + 0x800, "PCD_IPI", 7))
+        return 0;
+
+    return AVPROBE_SCORE_MAX - 1;
+}
+
 #define IMAGEAUTO_DEMUXER(imgname, codecid)\
 static const AVClass imgname ## _class = {\
     .class_name = AV_STRINGIFY(imgname) " demuxer",\
@@ -1032,7 +1112,7 @@ static const AVClass imgname ## _class = {\
     .option     = ff_img2pipe_options,\
     .version    = LIBAVUTIL_VERSION_INT,\
 };\
-AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
+const AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
     .name           = AV_STRINGIFY(imgname) "_pipe",\
     .long_name      = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
     .priv_data_size = sizeof(VideoDemuxData),\
@@ -1045,6 +1125,7 @@ AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
 };
 
 IMAGEAUTO_DEMUXER(bmp,     AV_CODEC_ID_BMP)
+IMAGEAUTO_DEMUXER(cri,     AV_CODEC_ID_CRI)
 IMAGEAUTO_DEMUXER(dds,     AV_CODEC_ID_DDS)
 IMAGEAUTO_DEMUXER(dpx,     AV_CODEC_ID_DPX)
 IMAGEAUTO_DEMUXER(exr,     AV_CODEC_ID_EXR)
@@ -1057,6 +1138,8 @@ IMAGEAUTO_DEMUXER(pbm,     AV_CODEC_ID_PBM)
 IMAGEAUTO_DEMUXER(pcx,     AV_CODEC_ID_PCX)
 IMAGEAUTO_DEMUXER(pgm,     AV_CODEC_ID_PGM)
 IMAGEAUTO_DEMUXER(pgmyuv,  AV_CODEC_ID_PGMYUV)
+IMAGEAUTO_DEMUXER(pgx,     AV_CODEC_ID_PGX)
+IMAGEAUTO_DEMUXER(photocd, AV_CODEC_ID_PHOTOCD)
 IMAGEAUTO_DEMUXER(pictor,  AV_CODEC_ID_PICTOR)
 IMAGEAUTO_DEMUXER(png,     AV_CODEC_ID_PNG)
 IMAGEAUTO_DEMUXER(ppm,     AV_CODEC_ID_PPM)
@@ -1067,5 +1150,6 @@ IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST)
 IMAGEAUTO_DEMUXER(svg,     AV_CODEC_ID_SVG)
 IMAGEAUTO_DEMUXER(tiff,    AV_CODEC_ID_TIFF)
 IMAGEAUTO_DEMUXER(webp,    AV_CODEC_ID_WEBP)
+IMAGEAUTO_DEMUXER(xbm,     AV_CODEC_ID_XBM)
 IMAGEAUTO_DEMUXER(xpm,     AV_CODEC_ID_XPM)
 IMAGEAUTO_DEMUXER(xwd,     AV_CODEC_ID_XWD)