Package: ffmpeg2theora Version: 0.16-2+b1 Output from a video-processing script of mine:
[1]+ sf -t FakePipe:debug=0 -t Scratch ffmpeg2theora -c 0 -o t.ogg -f image2 /volatile/ian/tmp/d/composed/frame%06d.ppm --inputfps 30 [2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31][32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47][48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63][64][65][66][67][68][69][70][71][72][73][74][75][76]Input #0, image2, from '/volatile/ian/tmp/d/composed/frame%06d.ppm': Duration: 00:00:16.0, start: 0.000000, bitrate: N/A Stream #0.0: Video: ppm, rgb24, 640x970, 25.00 fps(r) Resize: 640x970 0:00:00.50 audio: 0kbps video: 9420kbps The `[<number>]' are progress indication and can be disregarded. Note that I invoke ffmpeg2theora -c 0 -o t.ogg -f image2 \ /volatile/ian/tmp/d/composed/frame%06d.ppm --inputfps 30 but ffmpeg2theora reports Stream #0.0: Video: ppm, rgb24, 640x970, 25.00 fps(r) `sf' is subterfugue; I'm running ffmpeg2theora under subterfuge to solve the following problem: With the image2 `format' I have to supply all of the files (ppms in this case) for the whole video, as existing disk files, before starting. This requires an enormous amount of disk space, and is very slow (because all of the ppms have to be written out to disk and then read back in). With the image2pipe `format', which ought to be the answer to this problem, I find that ffmpeg2theora, like ffmpeg, cannot cope when it gets a short read(2). It prints messages about buffer underruns. So instead I have written an sf trick. Subterfugue is an strace-based trickery framework which allows supervisory modules called `tricks' to intervene in a program's activities including system calls. The `FakePipe' module allows me to supply the `image2' format with a directory full of named pipes; it tricks ffmpeg into seeing these as normal disk files, while allowing the data provider to open and write to each file one at a time. I have attached the script for your information. If necessary I can supply suitable input data and a copy of the sf trick and other relevant files but you probably don't want to dive that deeply into my situation. Ian.
#!/bin/bash set -e fail () { echo >&2 "bikecams-unify: error: $1"; exit 127; } basis=0 offset=true max='' while [ $# != 0 ]; do val="${1#*=}" case "$1" in --tmpdir=*) tmpdir="$val" ;; --frames=*) max="$val" ;; --start-frame=*) basis="$val" ;; --no-offset) offset=false ;; --) shift; break ;; -*) fail "unknown option \`$1'" ;; *) break ;; esac shift done test $# = 3 || \ fail 'usage: .../bikecams-unify [--tmpdir=T] FRONT.avi REAR.avi OUTPUT.thing' front="$1" rear="$2" output="$3" if [ "x$tmpdir" = x ]; then trap 'set +e; wait; rm -rf -- "$tmpdir"; exit 127' 0 tmpdir="`mktemp -dt`" rm_tmpdir=true else rm -rf -- "$tmpdir" mkdir -- "$tmpdir" rm_tmpdir=false fi frame=frame%06d.jpg oframe=frame%06d.ppm if [ "$max" ]; then t_max="-t $(( ($max + 29) / 30 ))" fi x () { echo >&2 "+ $*"; "$@"; } dmjpeg () { mkdir -p "$tmpdir/$2" x ffmpeg $t_max \ -i "$1" -f image2 "$tmpdir/$2/$frame" \ -f s8 "$tmpdir/$2.sb" } dmjpeg "$front" front dmjpeg "$rear" rear if $offset; then ${0/unify/audio} --not-interactive \ <"$tmpdir"/front.sb \ 3<"$tmpdir"/rear.sb \ >"$tmpdir"/offset read <"$tmpdir"/offset offset_ausamples offset_seconds offset_frames else offset_ausamples=0 offset_seconds=0 offset_frames=0 fi # weird noise thing: # sox -c1 -r8000 d/tmp/rear.sb d/tmp/t.wav noiseprof prof # sox -v0.5 -c1 -r8000 d/tmp/rear.sb d/tmp/t.wav noisered prof 0.1 initoffsets () { if [ $offset_ausamples -lt 0 ]; then atrimfront=$(( -$offset_ausamples )) atrimrear=0 ifront=$(( $basis-$offset_frames )) irear=$basis else atrimfront=0 atrimrear=$(( $offset_ausamples )) ifront=$basis irear=$(( $basis+$offset_frames )) fi icomposed=0 } perframeloop () { ifile front ifile rear icomposed=$(( $icomposed + 1 )) if [ "$max" -a "$icomposed" -gt "$max" ]; then break; fi f=`printf "%s/composed/$oframe" "$tmpdir" "$icomposed"` } ifile () { eval ' i'$1'=$(( $i'$1' + 1)) f=`printf "%s/$frame" "$tmpdir"/'$1' $i'$1'` if ! test -f "$f"; then break; fi f'$1'="$f" ' } pbmmake -black 1 10 >"$tmpdir"/border mkpipe () { rm -f -- "$1" mkfifo -m600 -- "$1" } #mkpipe "$tmpdir"/sentinel #exec 3<>"$tmpdir"/sentinel #exec 4<"$tmpdir"/sentinel rm -rf "$tmpdir"/composed mkdir "$tmpdir"/composed initoffsets trimaudio () { x sox -c1 -r8000 "$tmpdir/$1".sb "$tmpdir/$1".wav trim ${2}s; } trimaudio front $atrimfront trimaudio rear $atrimrear x sox -M "$tmpdir"/rear.wav "$tmpdir"/front.wav -c2 "$tmpdir"/output.wav while true; do perframeloop mkpipe "$f" printf "(%d)\r" $icomposed done echo if false; then PYTHONPATH="`dirname $0`" \ x sf -t FakePipe:debug=0 -t Scratch \ ffmpeg -y -r 30 \ -f image2 -vcodec ppm -i "$tmpdir"/composed/$oframe \ -i "$tmpdir/output.wav" \ -acodec copy \ -vcodec mpeg4 -f avi "$output" \ & ## -f mpeg -acodec copy -vcodec mpeg4 \ ## "$output" \ ## & else PYTHONPATH="`dirname $0`" \ x sf -t FakePipe:debug=0 -t Scratch \ ffmpeg2theora \ -c 0 -o "$output" \ -f image2 "$tmpdir"/composed/$oframe --inputfps 30 \ & ## -f image2pipe --inputfps 30 "pipe:.ppm" & ## ##x strace -vvtt -ot # -f wav output.wav \ # --audiostream 1 \ fi reencode_pid=$! initoffsets while true; do perframeloop printf "[%d]" $icomposed pfront="$ffront.ppm" prear="$frear.ppm" djpeg -pnm "$ffront" >"$pfront" djpeg -pnm "$frear" >"$prear" pnmcat -tb -black "$pfront" "$tmpdir"/border "$prear" >"$f" rm -- "$pfront" "$prear" done exec 4<&- sleep 1 x wait $reencode_pid if $rm_tmpdir; then trap '' 0 rm -rf -- "$tmpdir" fi