X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fimg2dec.c;h=d7a7cdaa169747d8e815abe02dbb2a77fe9d8fcb;hb=bc70684e74a185d7b80c8b80bdedda659cb581b8;hp=ecec4988b22fb5a328dd23db1f426cc8cdddcfb0;hpb=44085b9951b06df1cab4105dcda004213988d84f;p=ffmpeg diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index ecec4988b22..d7a7cdaa169 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -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)