Opened 5 years ago
Last modified 5 years ago
#8644 new enhancement
Demux multi-image TIFF beyond first image
Reported by: | adaerr | Owned by: | |
---|---|---|---|
Priority: | wish | Component: | undetermined |
Version: | git-master | Keywords: | tif |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
I would like to create a video from a TIFF file containing a sequence
of images of the same size. However currently ffmpeg decodes only the first image from the TIFF input.
TIFF files containing multiple images are indeed possible, and used as
native format by software ranging from scan software to scientific
image processing software like ImageJ. It would be convenient if
ffmpeg could decode/demux/process the sequence of images as a video input
just as it can for a collection of image files. In other words, I
would expect
ffmpeg -i all-frames.tif video-from-tif.webm
to produce the same video as that obtained by splitting the TIFF into
separate files and running
ffmpeg -i single-frame-%03d.png video-from-png.webm
The observed behaviour (see full output below) is that ffmpeg only
reads a single image from TIFF input, so that video-from-tif.webm
contains only one frame, where video-from-png.webm
contains the same
number of frames as there are PNG files in the input.
To reproduce, I attach[*] a sample TIFF with 20 frames:
20-frame-stack_416x160_grayscale-8bpp.tif
[*] Sorry, I failed to connect and upload the sample to the ftp server as specified in the instructions at http://www.ffmpeg.org/bugreports.html
A test stack can also easily be generated by the convert tool from the
ImageMagick software. The following command line for example produces
a TIFF containing 30 256x256 grayscale (8bpp) images showing a
gradient in varying orientation.
convert -size 256x256 gradient: -duplicate 29 -distort SRT '%[fx:360*t/n]' -depth 8 30-frame-stack_256x256_grayscale-8pp.tif
Here is the full log produced by a recent build from git sources:
Log level: 48 Command line: /home/adrian/.local/bin/ffmpeg -report -i 20-frame-stack_416x160_grayscale-8bpp.tif -y out.webm ffmpeg version N-97504-g1128aa8753 Copyright (c) 2000-2020 the FFmpeg developers built with gcc 9 (Debian 9.3.0-10) configuration: --prefix=/home/adrian/.local --enable-gpl --enable-version3 --enable-nonfree --enable-shared --enable-pthreads --enable-libfreetype --enable-fontconfig --enable-libass --enable-gnutls --enable-librtmp --enable-libxcb --enable-libmp3lame --enable-libvorbis --enable-libspeex --enable-libopus --enable-libgsm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-libx264 --enable-libxvid --enable-libtheora --enable-libvpx --enable-libopenjpeg --enable-frei0r --enable-libmodplug --enable-libzmq --enable-ladspa --enable-libssh --enable-libzvbi --enable-libgme --enable-libwavpack --enable-libwebp --enable-libx265 --enable-opengl --enable-librubberband --enable-libxml2 libavutil 56. 43.100 / 56. 43.100 libavcodec 58. 82.100 / 58. 82.100 libavformat 58. 42.101 / 58. 42.101 libavdevice 58. 9.103 / 58. 9.103 libavfilter 7. 79.100 / 7. 79.100 libswscale 5. 6.101 / 5. 6.101 libswresample 3. 6.100 / 3. 6.100 libpostproc 55. 6.100 / 55. 6.100 Splitting the commandline. Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'. Reading option '-i' ... matched as input url with argument '20-frame-stack_416x160_grayscale-8bpp.tif'. Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'. Reading option 'out.webm' ... matched as output url. Finished splitting the commandline. Parsing a group of options: global . Applying option report (generate a report) with argument 1. Applying option y (overwrite output files) with argument 1. Successfully parsed a group of options. Parsing a group of options: input url 20-frame-stack_416x160_grayscale-8bpp.tif. Successfully parsed a group of options. Opening an input file: 20-frame-stack_416x160_grayscale-8bpp.tif. [NULL @ 0x562105205440] Opening '20-frame-stack_416x160_grayscale-8bpp.tif' for reading [file @ 0x562105205f00] Setting default whitelist 'file,crypto,data' [tiff_pipe @ 0x562105205440] Format tiff_pipe probed with size=2048 and score=51 [tiff_pipe @ 0x562105205440] Before avformat_find_stream_info() pos: 0 bytes read:32768 seeks:0 nb_streams:1 [tiff_pipe @ 0x562105205440] parser not found for codec tiff, packets or times may be invalid. [tiff_pipe @ 0x562105205440] parser not found for codec tiff, packets or times may be invalid. [tiff_pipe @ 0x562105205440] After avformat_find_stream_info() pos: 1334978 bytes read:1334978 seeks:0 frames:1 Input #0, tiff_pipe, from '20-frame-stack_416x160_grayscale-8bpp.tif': Duration: N/A, bitrate: N/A Stream #0:0, 1, 1/25: Video: tiff, gray, 416x160 [SAR 1:1 DAR 13:5], 25 tbr, 25 tbn, 25 tbc Successfully opened the file. Parsing a group of options: output url out.webm. Successfully parsed a group of options. Opening an output file: out.webm. [file @ 0x562105218540] Setting default whitelist 'file,crypto,data' Successfully opened the file. detected 4 logical cores Stream mapping: Stream #0:0 -> #0:0 (tiff (native) -> vp9 (libvpx-vp9)) Press [q] to stop, [?] for help cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream) cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream) [graph 0 input from stream 0:0 @ 0x562105355900] Setting 'video_size' to value '416x160' [graph 0 input from stream 0:0 @ 0x562105355900] Setting 'pix_fmt' to value '8' [graph 0 input from stream 0:0 @ 0x562105355900] Setting 'time_base' to value '1/25' [graph 0 input from stream 0:0 @ 0x562105355900] Setting 'pixel_aspect' to value '1/1' [graph 0 input from stream 0:0 @ 0x562105355900] Setting 'frame_rate' to value '25/1' [graph 0 input from stream 0:0 @ 0x562105355900] w:416 h:160 pixfmt:gray tb:1/25 fr:25/1 sar:1/1 [format @ 0x562105355d00] Setting 'pix_fmts' to value 'yuv420p|yuva420p|yuv422p|yuv440p|yuv444p|gbrp' [auto_scaler_0 @ 0x56210535de00] Setting 'flags' to value 'bicubic' [auto_scaler_0 @ 0x56210535de00] w:iw h:ih flags:'bicubic' interl:0 [format @ 0x562105355d00] auto-inserting filter 'auto_scaler_0' between the filter 'Parsed_null_0' and the filter 'format' [AVFilterGraph @ 0x56210532d440] query_formats: 4 queried, 2 merged, 1 already done, 0 delayed [auto_scaler_0 @ 0x56210535de00] picking gbrp out of 6 ref:gray alpha:0 [swscaler @ 0x56210535f300] Forcing full internal H chroma due to input having non subsampled chroma [auto_scaler_0 @ 0x56210535de00] w:416 h:160 fmt:gray sar:1/1 -> w:416 h:160 fmt:gbrp sar:1/1 flags:0x4 [libvpx-vp9 @ 0x56210521ac40] v1.8.2 [libvpx-vp9 @ 0x56210521ac40] --prefix=/usr --enable-pic --enable-shared --disable-install-bins --disable-install-srcs --size-limit=16384x16384 --enable-postproc --enable-multi-res-encoding --enable-temporal-denoising --enable-vp9-temporal-denoising --enable-vp9-postproc --target=x86_64-linux-gcc [libvpx-vp9 @ 0x56210521ac40] vpx_codec_enc_cfg [libvpx-vp9 @ 0x56210521ac40] generic settings g_usage: 0 g_threads: 8 g_profile: 1 g_w: 320 g_h: 240 g_bit_depth: 8 g_input_bit_depth: 8 g_timebase: {1/30} g_error_resilient: 0 g_pass: 0 g_lag_in_frames: 25 [libvpx-vp9 @ 0x56210521ac40] rate control settings rc_dropframe_thresh: 0 rc_resize_allowed: 0 rc_resize_up_thresh: 60 rc_resize_down_thresh: 30 rc_end_usage: 0 rc_twopass_stats_in: (nil)(0) rc_target_bitrate: 256 [libvpx-vp9 @ 0x56210521ac40] quantizer settings rc_min_quantizer: 0 rc_max_quantizer: 63 [libvpx-vp9 @ 0x56210521ac40] bitrate tolerance rc_undershoot_pct: 25 rc_overshoot_pct: 25 [libvpx-vp9 @ 0x56210521ac40] temporal layering settings ts_number_layers: 1 [libvpx-vp9 @ 0x56210521ac40] layer_target_bitrate: 0 0 0 0 0 [libvpx-vp9 @ 0x56210521ac40] ts_rate_decimator: 0 0 0 0 0 [libvpx-vp9 @ 0x56210521ac40] ts_periodicity: 0 [libvpx-vp9 @ 0x56210521ac40] ts_layer_id: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [libvpx-vp9 @ 0x56210521ac40] decoder buffer model rc_buf_sz: 6000 rc_buf_initial_sz: 4000 rc_buf_optimal_sz: 5000 [libvpx-vp9 @ 0x56210521ac40] 2 pass rate control settings rc_2pass_vbr_bias_pct: 50 rc_2pass_vbr_minsection_pct: 0 rc_2pass_vbr_maxsection_pct: 2000 [libvpx-vp9 @ 0x56210521ac40] rc_2pass_vbr_corpus_complexity:0 [libvpx-vp9 @ 0x56210521ac40] keyframing settings kf_mode: 1 kf_min_dist: 0 kf_max_dist: 128 [libvpx-vp9 @ 0x56210521ac40] [libvpx-vp9 @ 0x56210521ac40] Neither bitrate nor constrained quality specified, using default CRF of 32 [libvpx-vp9 @ 0x56210521ac40] vpx_codec_enc_cfg [libvpx-vp9 @ 0x56210521ac40] generic settings g_usage: 0 g_threads: 4 g_profile: 1 g_w: 416 g_h: 160 g_bit_depth: 8 g_input_bit_depth: 8 g_timebase: {1/25} g_error_resilient: 0 g_pass: 0 g_lag_in_frames: 25 [libvpx-vp9 @ 0x56210521ac40] rate control settings rc_dropframe_thresh: 0 rc_resize_allowed: 0 rc_resize_up_thresh: 60 rc_resize_down_thresh: 30 rc_end_usage: 3 rc_twopass_stats_in: (nil)(0) rc_target_bitrate: 256 [libvpx-vp9 @ 0x56210521ac40] quantizer settings rc_min_quantizer: 0 rc_max_quantizer: 63 [libvpx-vp9 @ 0x56210521ac40] bitrate tolerance rc_undershoot_pct: 25 rc_overshoot_pct: 25 [libvpx-vp9 @ 0x56210521ac40] temporal layering settings ts_number_layers: 1 [libvpx-vp9 @ 0x56210521ac40] layer_target_bitrate: 0 0 0 0 0 [libvpx-vp9 @ 0x56210521ac40] ts_rate_decimator: 0 0 0 0 0 [libvpx-vp9 @ 0x56210521ac40] ts_periodicity: 0 [libvpx-vp9 @ 0x56210521ac40] ts_layer_id: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [libvpx-vp9 @ 0x56210521ac40] decoder buffer model rc_buf_sz: 6000 rc_buf_initial_sz: 4000 rc_buf_optimal_sz: 5000 [libvpx-vp9 @ 0x56210521ac40] 2 pass rate control settings rc_2pass_vbr_bias_pct: 50 rc_2pass_vbr_minsection_pct: 0 rc_2pass_vbr_maxsection_pct: 2000 [libvpx-vp9 @ 0x56210521ac40] rc_2pass_vbr_corpus_complexity:0 [libvpx-vp9 @ 0x56210521ac40] keyframing settings kf_mode: 1 kf_min_dist: 0 kf_max_dist: 128 [libvpx-vp9 @ 0x56210521ac40] [libvpx-vp9 @ 0x56210521ac40] vpx_codec_control [libvpx-vp9 @ 0x56210521ac40] VP8E_SET_CPUUSED: 1 [libvpx-vp9 @ 0x56210521ac40] VP8E_SET_ARNR_MAXFRAMES: 0 [libvpx-vp9 @ 0x56210521ac40] VP8E_SET_ARNR_STRENGTH: 3 [libvpx-vp9 @ 0x56210521ac40] VP8E_SET_ARNR_TYPE: 3 [libvpx-vp9 @ 0x56210521ac40] VP8E_SET_STATIC_THRESHOLD: 0 [libvpx-vp9 @ 0x56210521ac40] VP8E_SET_CQ_LEVEL: 32 [libvpx-vp9 @ 0x56210521ac40] VP9E_SET_COLOR_SPACE: 7 [libvpx-vp9 @ 0x56210521ac40] VP9E_SET_COLOR_RANGE: 0 [libvpx-vp9 @ 0x56210521ac40] VP9E_SET_TARGET_LEVEL: 255 [libvpx-vp9 @ 0x56210521ac40] Using deadline: 1000000 [webm @ 0x562105216480] get_metadata_duration returned: 0 Output #0, webm, to 'out.webm': Metadata: encoder : Lavf58.42.101 Stream #0:0, 0, 1/1000: Video: vp9 (libvpx-vp9), gbrp, 416x160 [SAR 1:1 DAR 13:5], q=-1--1, 25 fps, 1k tbn, 25 tbc Metadata: encoder : Lavc58.82.100 libvpx-vp9 Side data: cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A Clipping frame in rate conversion by 0.000008 cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream) cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream) [out_0_0 @ 0x56210535bb00] EOF on sink link out_0_0:default. No more output streams to write to, finishing. Automatically inserted bitstream filter 'vp9_superframe'; args='' [webm @ 0x562105216480] Starting new cluster with timestamp 0 at offset 478 bytes [webm @ 0x562105216480] Writing block of size 8070 with pts 0, dts 0, duration 40 at relative offset 3 in cluster at offset 478. TrackNumber 1, keyframe 1 [webm @ 0x562105216480] end duration = 40 [webm @ 0x562105216480] stream 0 end duration = 40 frame= 1 fps=0.0 q=0.0 Lsize= 8kB time=00:00:00.00 bitrate=68688.0kbits/s speed=0.0109x video:8kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 6.394052% Input file #0 (20-frame-stack_416x160_grayscale-8bpp.tif): Input stream #0:0 (video): 1 packets read (1334978 bytes); 1 frames decoded; Total: 1 packets (1334978 bytes) demuxed Output file #0 (out.webm): Output stream #0:0 (video): 1 frames encoded; 1 packets muxed (8070 bytes); Total: 1 packets (8070 bytes) muxed 1 frames successfully decoded, 0 decoding errors [AVIOContext @ 0x56210521b380] Statistics: 0 seeks, 1 writeouts [AVIOContext @ 0x56210520e2c0] Statistics: 1334978 bytes read, 0 seeks
Attachments (2)
Change History (6)
by , 5 years ago
Attachment: | 20-frame-stack_416x160_grayscale-8bpp.tif added |
---|
by , 5 years ago
Attachment: | 20-frame-stack_416x160_grayscale-8bpp_README.md added |
---|
Description for the attached TIFF file
comment:1 by , 5 years ago
Keywords: | tif added; tiff removed |
---|---|
Priority: | normal → wish |
comment:2 by , 5 years ago
A workaround is to pipe ImageMagick to FFmpeg
eg. 10fps FFV1, MKV container
"convert" "20-frame-stack_416x160_grayscale-8bpp.tif" gray:- | ffmpeg -f rawvideo -s 416x160 -pix_fmt gray -r 10 -i - -c:v ffv1 -an im_pipe_to_ffmpeg_ffv1.mkv
comment:3 by , 5 years ago
Thanks for the comment. Although using ImageMagick to pipe the images into ffmpeg is indeed a workaround I should have mentioned, it works only for not too large files. The variant I use is
convert foo.tif ppm:- | ffmpeg -f image2pipe -framerate 15 -i - [...]
ImageMagick was not designed for processing long image sequences - though it has some animation support for gif etc - so this is slow and fails for large files: convert
loads images into memory (can be extended by use of tmp dir and tuning magick's configuration to some extent) before outputting data, so memory usage increases with file size. Note that the limit file size is a fraction of the available cache size: the internal representation of images may have 16bit depth per channel, so 8bit gray is stored as 64bpp RGBA in memory/cache.
comment:4 by , 5 years ago
And while we're mentionning workarounds: for large files that I cannot process via ImageMagick, my workaround consists in opening the TIFF in ImageJ and saving it as uncompressed AVI, that works like a charm with ffmpeg.
Still it would be more convenient if ffmpeg, which already has a TIFF decoder, could properly demux multiple images from a TIFF file. Whence this ticket.
TIFF file containing a sequence of (416x160 8bpp grayscale) images.