merged hv7 mod
authorGood Guy <good1.2guy@gmail.com>
Wed, 18 Oct 2017 23:04:27 +0000 (17:04 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 18 Oct 2017 23:04:27 +0000 (17:04 -0600)
223 files changed:
cinelerra-5.1/Cinelerra_factory [new file with mode: 0644]
cinelerra-5.1/Makefile.am
cinelerra-5.1/Makefile.devel
cinelerra-5.1/cinelerra/Makefile
cinelerra-5.1/cinelerra/aautomation.C
cinelerra-5.1/cinelerra/adeviceprefs.C
cinelerra-5.1/cinelerra/adeviceprefs.h
cinelerra-5.1/cinelerra/asset.C
cinelerra-5.1/cinelerra/asset.h
cinelerra-5.1/cinelerra/assetpopup.C
cinelerra-5.1/cinelerra/atrack.C
cinelerra-5.1/cinelerra/atrack.h
cinelerra-5.1/cinelerra/audioconfig.C
cinelerra-5.1/cinelerra/automation.C
cinelerra-5.1/cinelerra/awindow.C
cinelerra-5.1/cinelerra/awindow.h
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/cachebase.C
cinelerra-5.1/cinelerra/cachebase.h
cinelerra-5.1/cinelerra/canvas.C
cinelerra-5.1/cinelerra/channelinfo.C
cinelerra-5.1/cinelerra/clippopup.C
cinelerra-5.1/cinelerra/colorpicker.C
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/cwindowtool.C
cinelerra-5.1/cinelerra/cwindowtool.h
cinelerra-5.1/cinelerra/edit.C
cinelerra-5.1/cinelerra/edits.C
cinelerra-5.1/cinelerra/edits.h
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/edl.h
cinelerra-5.1/cinelerra/edl.inc
cinelerra-5.1/cinelerra/edlsession.C
cinelerra-5.1/cinelerra/edlsession.h
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/file.C
cinelerra-5.1/cinelerra/file.h
cinelerra-5.1/cinelerra/filebase.h
cinelerra-5.1/cinelerra/fileffmpeg.C
cinelerra-5.1/cinelerra/fileffmpeg.h
cinelerra-5.1/cinelerra/filejpeg.C
cinelerra-5.1/cinelerra/filelist.C
cinelerra-5.1/cinelerra/filempeg.C
cinelerra-5.1/cinelerra/filempeg.h
cinelerra-5.1/cinelerra/formattools.C
cinelerra-5.1/cinelerra/keyframe.C
cinelerra-5.1/cinelerra/keyframe.h
cinelerra-5.1/cinelerra/keyframegui.C
cinelerra-5.1/cinelerra/keyframegui.h
cinelerra-5.1/cinelerra/localsession.C
cinelerra-5.1/cinelerra/localsession.h
cinelerra-5.1/cinelerra/mainclock.C
cinelerra-5.1/cinelerra/menueffects.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindow.inc
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/new.C
cinelerra-5.1/cinelerra/packagerenderer.C
cinelerra-5.1/cinelerra/playbackconfig.C
cinelerra-5.1/cinelerra/playbackconfig.h
cinelerra-5.1/cinelerra/playbackprefs.C
cinelerra-5.1/cinelerra/playbackprefs.h
cinelerra-5.1/cinelerra/pluginclient.C
cinelerra-5.1/cinelerra/presets.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/presets.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/presets.inc [new file with mode: 0644]
cinelerra-5.1/cinelerra/presetsgui.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/presetsgui.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/presetsgui.inc [new file with mode: 0644]
cinelerra-5.1/cinelerra/record.C
cinelerra-5.1/cinelerra/record.h
cinelerra-5.1/cinelerra/recordgui.C
cinelerra-5.1/cinelerra/recordgui.h
cinelerra-5.1/cinelerra/recordmonitor.C
cinelerra-5.1/cinelerra/recordmonitor.h
cinelerra-5.1/cinelerra/recordprefs.C
cinelerra-5.1/cinelerra/recordprefs.h
cinelerra-5.1/cinelerra/recordscopes.C
cinelerra-5.1/cinelerra/recordvideo.C
cinelerra-5.1/cinelerra/recordwindow.h
cinelerra-5.1/cinelerra/remotecontrol.C
cinelerra-5.1/cinelerra/render.C
cinelerra-5.1/cinelerra/savefile.C
cinelerra-5.1/cinelerra/scopewindow.C
cinelerra-5.1/cinelerra/signalstatus.C
cinelerra-5.1/cinelerra/testwindow.h
cinelerra-5.1/cinelerra/theme.C
cinelerra-5.1/cinelerra/theme.h
cinelerra-5.1/cinelerra/track.C
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/cinelerra/tracksedit.C
cinelerra-5.1/cinelerra/vautomation.C
cinelerra-5.1/cinelerra/vdevice1394.C
cinelerra-5.1/cinelerra/vdevice1394.h
cinelerra-5.1/cinelerra/vdevicebase.h
cinelerra-5.1/cinelerra/vdeviceprefs.C
cinelerra-5.1/cinelerra/vdeviceprefs.h
cinelerra-5.1/cinelerra/vdevicex11.C
cinelerra-5.1/cinelerra/vdevicex11.h
cinelerra-5.1/cinelerra/videodevice.C
cinelerra-5.1/cinelerra/videodevice.h
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/cinelerra/vrender.C
cinelerra-5.1/configure.ac
cinelerra-5.1/ffmpeg/decode.opts
cinelerra-5.1/guicast/Makefile
cinelerra-5.1/guicast/bcbitmap.h
cinelerra-5.1/guicast/bcbutton.C
cinelerra-5.1/guicast/bccapture.C
cinelerra-5.1/guicast/bccapture.h
cinelerra-5.1/guicast/bccmodels.h
cinelerra-5.1/guicast/bccolors.C [moved from cinelerra-5.1/cinelerra/cicolors.C with 99% similarity]
cinelerra-5.1/guicast/bccolors.h [moved from cinelerra-5.1/cinelerra/cicolors.h with 81% similarity]
cinelerra-5.1/guicast/bccolors.inc [moved from cinelerra-5.1/cinelerra/cicolors.inc with 100% similarity]
cinelerra-5.1/guicast/bcfilebox.C
cinelerra-5.1/guicast/bclistbox.C
cinelerra-5.1/guicast/bclistbox.h
cinelerra-5.1/guicast/bclistboxitem.h
cinelerra-5.1/guicast/bcmenubar.C
cinelerra-5.1/guicast/bcmenuitem.C
cinelerra-5.1/guicast/bcmenuitem.h
cinelerra-5.1/guicast/bcmeter.C
cinelerra-5.1/guicast/bcpan.C
cinelerra-5.1/guicast/bcpopupmenu.C
cinelerra-5.1/guicast/bcpot.C
cinelerra-5.1/guicast/bcprogress.C
cinelerra-5.1/guicast/bcresources.C
cinelerra-5.1/guicast/bcresources.h
cinelerra-5.1/guicast/bcscrollbar.C
cinelerra-5.1/guicast/bcslider.C
cinelerra-5.1/guicast/bctextbox.C
cinelerra-5.1/guicast/bctextbox.h
cinelerra-5.1/guicast/bctitle.h
cinelerra-5.1/guicast/bctoggle.C
cinelerra-5.1/guicast/bctoggle.h
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/guicast/bcwindowbase.h
cinelerra-5.1/guicast/bcwindowdraw.C
cinelerra-5.1/guicast/fonts.h
cinelerra-5.1/guicast/guicast.h
cinelerra-5.1/guicast/test4.C
cinelerra-5.1/guicast/vframe.C
cinelerra-5.1/guicast/vframe.h
cinelerra-5.1/guicast/vicon.C
cinelerra-5.1/plugin_defs
cinelerra-5.1/plugins/C41/c41.C
cinelerra-5.1/plugins/Makefile
cinelerra-5.1/plugins/audioscope/audioscope.C
cinelerra-5.1/plugins/audioscope/audioscope.h
cinelerra-5.1/plugins/bluebanana/bluebanana.C
cinelerra-5.1/plugins/bluebanana/bluebanana.h
cinelerra-5.1/plugins/bluebanana/bluebananaslider.h
cinelerra-5.1/plugins/bluebanana/bluebananawindow.h
cinelerra-5.1/plugins/brightness/brightness.h
cinelerra-5.1/plugins/burn/burn.C
cinelerra-5.1/plugins/burn/burn.h
cinelerra-5.1/plugins/chromakey/chromakey.C
cinelerra-5.1/plugins/chromakeyhsv/chromakey.C
cinelerra-5.1/plugins/color3way/color3way.h
cinelerra-5.1/plugins/colorbalance/colorbalance.h
cinelerra-5.1/plugins/crikey/crikey.C
cinelerra-5.1/plugins/diffkey/diffkey.C
cinelerra-5.1/plugins/echo/echo.C
cinelerra-5.1/plugins/echocancel/echocancel.C
cinelerra-5.1/plugins/findobj/findobj.C
cinelerra-5.1/plugins/gamma/gamma.C
cinelerra-5.1/plugins/gamma/gamma.h
cinelerra-5.1/plugins/gradient/gradient.h
cinelerra-5.1/plugins/histogram/histogram.C
cinelerra-5.1/plugins/histogram/histogram.h
cinelerra-5.1/plugins/histogram_bezier/bistogram.C
cinelerra-5.1/plugins/histogram_bezier/bistogram.h
cinelerra-5.1/plugins/holo/holo.C
cinelerra-5.1/plugins/holo/holo.h
cinelerra-5.1/plugins/huesaturation/huesaturation.C
cinelerra-5.1/plugins/interpolate/interpolate.C
cinelerra-5.1/plugins/interpolatevideo/Makefile
cinelerra-5.1/plugins/interpolatevideo/interpolatevideo.C
cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.C [new symlink]
cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.h [new symlink]
cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.inc [new symlink]
cinelerra-5.1/plugins/interpolatevideo/opticflow.C
cinelerra-5.1/plugins/interpolatevideo/opticflow.h
cinelerra-5.1/plugins/invertvideo/invert.C
cinelerra-5.1/plugins/libeffecttv/effecttv.C
cinelerra-5.1/plugins/libeffecttv/effecttv.h
cinelerra-5.1/plugins/motion-hv/Makefile
cinelerra-5.1/plugins/motion-hv/motion-hv.C
cinelerra-5.1/plugins/motion-hv/motioncache-hv.C [new file with mode: 0644]
cinelerra-5.1/plugins/motion-hv/motioncache-hv.h [new file with mode: 0644]
cinelerra-5.1/plugins/motion-hv/motioncache-hv.inc [new file with mode: 0644]
cinelerra-5.1/plugins/motion-hv/motionscan-hv.C
cinelerra-5.1/plugins/motion-hv/motionscan-hv.h
cinelerra-5.1/plugins/motion2point/Makefile
cinelerra-5.1/plugins/motion2point/motioncache-hv.C [new symlink]
cinelerra-5.1/plugins/motion2point/motioncache-hv.h [new symlink]
cinelerra-5.1/plugins/motion2point/motioncache-hv.inc [new symlink]
cinelerra-5.1/plugins/reverb/reverb.C
cinelerra-5.1/plugins/reverb/reverb.h
cinelerra-5.1/plugins/reverb/reverbwindow.C
cinelerra-5.1/plugins/rgbshift/rgbshift.C
cinelerra-5.1/plugins/spectrogram/spectrogram.C
cinelerra-5.1/plugins/spherecam/Makefile [new file with mode: 0644]
cinelerra-5.1/plugins/spherecam/picon_cinfinity.png [new file with mode: 0644]
cinelerra-5.1/plugins/spherecam/spherecam.C [new file with mode: 0644]
cinelerra-5.1/plugins/spherecam/spherecam.C.bak [new file with mode: 0644]
cinelerra-5.1/plugins/spherecam/spherecam.h [new file with mode: 0644]
cinelerra-5.1/plugins/spherecam/spherecam.h.bak [new file with mode: 0644]
cinelerra-5.1/plugins/swapframes/swapframes.C
cinelerra-5.1/plugins/threshold/histogramengine.C
cinelerra-5.1/plugins/threshold/histogramengine.h
cinelerra-5.1/plugins/threshold/threshold.C
cinelerra-5.1/plugins/threshold/threshold.h
cinelerra-5.1/plugins/timeavg/timeavg.C
cinelerra-5.1/plugins/timefront/timefront.h
cinelerra-5.1/plugins/timestretchrt/timestretchrt.C
cinelerra-5.1/plugins/timestretchrt/timestretchrt.h
cinelerra-5.1/plugins/videoscope/videoscope.C
cinelerra-5.1/plugins/yuv/yuv.C
cinelerra-5.1/plugins/yuv/yuv.h
cinelerra-5.1/plugins/yuv411/yuv411win.h
cinelerra-5.1/plugins/yuvshift/yuvshift.C
cinelerra-5.1/thirdparty/src/libXft-2.3.2.patch1 [new file with mode: 0644]

diff --git a/cinelerra-5.1/Cinelerra_factory b/cinelerra-5.1/Cinelerra_factory
new file mode 100644 (file)
index 0000000..97c2aa4
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<PLUGIN TITLE=Compressor>
+<KEYFRAME TITLE=loud><COMPRESSOR TRIGGER=0 REACTION_LEN=-1.0000000000000014e-01 DECAY_LEN=9.9999999999999367e-02 SMOOTHING_ONLY=0 INPUT=2>
+<LEVEL X=-4.9852631578947367e+01 Y=0>
+</KEYFRAME>
+<KEYFRAME TITLE=soft><COMPRESSOR TRIGGER=0 REACTION_LEN=-1.0000000000000014e-01 DECAY_LEN=4.9999999999999982e+00 SMOOTHING_ONLY=0 INPUT=2>
+<LEVEL X=-4.9852631578947367e+01 Y=0>
+</KEYFRAME>
+<KEYFRAME TITLE=voice><COMPRESSOR TRIGGER=0 REACTION_LEN=-1.0000000000000001e-01 DECAY_LEN=1.0000000000000001e-01 SMOOTHING_ONLY=0 INPUT=2>
+<LEVEL X=-3.0484210526315792e+01 Y=-80>
+<LEVEL X=-1.9873684210526321e+01 Y=0>
+</KEYFRAME>
+<KEYFRAME TITLE="live audio"><COMPRESSOR TRIGGER=0 REACTION_LEN=1.0000000000000001e-01 DECAY_LEN=1.0000000000000001e-01 SMOOTHING_ONLY=0 INPUT=2>
+<LEVEL X=-4.9852631578947367e+01 Y=0>
+</KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Lens>
+<KEYFRAME TITLE="15mm full frame stretch"><LENS FOCAL_LENGTH0=5.999998e-01 FOCAL_LENGTH1=6.000000e-01 FOCAL_LENGTH2=6.000000e-01 FOCAL_LENGTH3=6.000000e-01 ASPECT=1 RADIUS=1.020000e+00 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE="15mm 1.6x stretch"><LENS FOCAL_LENGTH0=3.699997e-01 FOCAL_LENGTH1=3.700000e-01 FOCAL_LENGTH2=3.700000e-01 FOCAL_LENGTH3=3.700000e-01 ASPECT=1 RADIUS=8.500000e-01 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE="15mm full frame hemi"><LENS FOCAL_LENGTH0=5.999998e-01 FOCAL_LENGTH1=6.000000e-01 FOCAL_LENGTH2=6.000000e-01 FOCAL_LENGTH3=6.000000e-01 ASPECT=1.200000e+00 RADIUS=1.020000e+00 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE="15mm 1920x1080"><LENS FOCAL_LENGTH0=5.799997e-01 FOCAL_LENGTH1=5.800000e-01 FOCAL_LENGTH2=5.800000e-01 FOCAL_LENGTH3=5.800000e-01 ASPECT=1 RADIUS=9.400000e-01 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE="15mm 1.6x video"><LENS FOCAL_LENGTH0=3.699998e-01 FOCAL_LENGTH1=3.700001e-01 FOCAL_LENGTH2=3.700001e-01 FOCAL_LENGTH3=3.700001e-01 ASPECT=1 RADIUS=8.400001e-01 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE=gopro><LENS FOCAL_LENGTH0=4.999998e-01 FOCAL_LENGTH1=5.000001e-01 FOCAL_LENGTH2=5.000001e-01 FOCAL_LENGTH3=5.000001e-01 ASPECT=1 RADIUS=1.200000e+00 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE="gopro hemi"><LENS FOCAL_LENGTH0=4.999998e-01 FOCAL_LENGTH1=5.000001e-01 FOCAL_LENGTH2=5.000001e-01 FOCAL_LENGTH3=5.000001e-01 ASPECT=1.330000e+00 RADIUS=7.300000e-01 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE=gopro2.7k><LENS FOCAL_LENGTH0=4.399988e-01 FOCAL_LENGTH1=4.400000e-01 FOCAL_LENGTH2=4.400000e-01 FOCAL_LENGTH3=4.400000e-01 ASPECT=1 RADIUS=8.500000e-01 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+<KEYFRAME TITLE="gopro 4k"><LENS FOCAL_LENGTH0=4.999998e-01 FOCAL_LENGTH1=5.000001e-01 FOCAL_LENGTH2=5.000001e-01 FOCAL_LENGTH3=5.000001e-01 ASPECT=1 RADIUS=8.700000e-01 MODE=3 CENTER_X=50 CENTER_Y=50 DRAW_GUIDES=0></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Spectrogram>
+<KEYFRAME TITLE=sissel><SPECTROGRAM LEVEL=1.4901161193847656e-08 NORMALIZE=0 WINDOW_SIZE=4096 XZOOM=1 MODE=0 HISTORY_SIZE=4 W=750 H=656>
+</KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Downsample>
+<KEYFRAME TITLE="UV 2x2"><DOWNSAMPLE HORIZONTAL=2 VERTICAL=2 HORIZONTAL_X=0 VERTICAL_Y=0 R=0 G=1 B=1 A=0></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Scale>
+<KEYFRAME TITLE="d-1 to gootube"><SCALE WIDTH=4.400000e-01 HEIGHT=5.000000e-01></KEYFRAME>
+<KEYFRAME TITLE="640x480 to d-1"><SCALE WIDTH=1.100000e+00 HEIGHT=1></KEYFRAME>
+<KEYFRAME TITLE="fix D-1 on gootube"><SCALE WIDTH=1 HEIGHT=1.125100e+00></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Motion>
+<KEYFRAME TITLE=coptercam><MOTION BLOCK_COUNT=1 GLOBAL_POSITIONS=256 ROTATE_POSITIONS=4 GLOBAL_BLOCK_W=45 GLOBAL_BLOCK_H=52 ROTATION_BLOCK_W=33 ROTATION_BLOCK_H=32 BLOCK_X=50 BLOCK_Y=50 GLOBAL_RANGE_W=39 GLOBAL_RANGE_H=47 ROTATION_RANGE=10 ROTATION_CENTER=0 MAGNITUDE=50 RETURN_SPEED=3 MODE1=1 GLOBAL=1 ROTATE=1 MODE2=5 DRAW_VECTORS=0 MODE3=11 TRACK_FRAME=0 BOTTOM_IS_MASTER=1 HORIZONTAL_ONLY=0 VERTICAL_ONLY=0></KEYFRAME>
+<KEYFRAME TITLE=running><MOTION BLOCK_COUNT=1 GLOBAL_POSITIONS=1024 ROTATE_POSITIONS=4 GLOBAL_BLOCK_W=34 GLOBAL_BLOCK_H=46 BLOCK_X=50 BLOCK_Y=50 GLOBAL_RANGE_W=100 GLOBAL_RANGE_H=100 ROTATION_RANGE=5 ROTATION_CENTER=0 MAGNITUDE=50 RETURN_SPEED=10 ROTATE_MAGNITUDE=15 ROTATE_RETURN_SPEED=10 ACTION_TYPE=3 GLOBAL=1 ROTATE=1 TRACKING_TYPE=1 DRAW_VECTORS=1 TRACKING_OBJECT=2 TRACK_FRAME=0 BOTTOM_IS_MASTER=1 HORIZONTAL_ONLY=0 VERTICAL_ONLY=0></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Reverb>
+<KEYFRAME TITLE=loud><REVERB LEVELINIT=0 DELAY_INIT=20 REF_LEVEL1=-1.7999996185302734e+01 REF_LEVEL2=-3.8000030517578125e+01 REF_TOTAL=124 REF_LENGTH=1059 LOWPASS1=24539 LOWPASS2=24539>
+</KEYFRAME>
+<KEYFRAME TITLE=long><REVERB LEVELINIT=0 DELAY_INIT=20 REF_LEVEL1=-16 REF_LEVEL2=-3.8000030517578125e+01 REF_TOTAL=137 REF_LENGTH=3034 LOWPASS1=24539 LOWPASS2=24539>
+</KEYFRAME>
+<KEYFRAME TITLE=piano><REVERB LEVELINIT=0 DELAY_INIT=90 REF_LEVEL1=-28 REF_LEVEL2=-40 REF_TOTAL=163 REF_LENGTH=600 LOWPASS1=24539 LOWPASS2=4425>
+</KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE="Interpolate Video">
+<KEYFRAME TITLE="10fps analog"><INTERPOLATEVIDEO INPUT_RATE=10 USE_KEYFRAMES=0 OPTIC_FLOW=1 DRAW_VECTORS=0 SEARCH_RADIUS=16 MACROBLOCK_SIZE=32></KEYFRAME>
+<KEYFRAME TITLE=iss><INTERPOLATEVIDEO INPUT_RATE=1 USE_KEYFRAMES=0 OPTIC_FLOW=1 DRAW_VECTORS=1 SEARCH_RADIUS=111 MACROBLOCK_SIZE=101></KEYFRAME>
+<KEYFRAME TITLE=hd><INTERPOLATEVIDEO INPUT_RATE=2.3976023976023978e+01 USE_KEYFRAMES=0 OPTIC_FLOW=1 DRAW_VECTORS=0 SEARCH_RADIUS=40 MACROBLOCK_SIZE=50></KEYFRAME>
+<KEYFRAME TITLE=weather><INTERPOLATEVIDEO INPUT_RATE=5 USE_KEYFRAMES=0 OPTIC_FLOW=1 DRAW_VECTORS=0 SEARCH_RADIUS=32 MACROBLOCK_SIZE=60></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE="Chroma key (HSV)">
+<KEYFRAME TITLE=blue><CHROMAKEY_HSV RED=0 GREEN=1.137255e-01 BLUE=1 MIN_BRIGHTNESS=0 MAX_BRIGHTNESS=100 SATURATION=0 MIN_SATURATION=20 TOLERANCE=30 IN_SLOPE=0 OUT_SLOPE=0 ALPHA_OFFSET=0 SPILL_THRESHOLD=0 SPILL_AMOUNT=0 SHOW_MASK=0></KEYFRAME>
+<KEYFRAME TITLE=pink><CHROMAKEY_HSV RED=1 GREEN=0 BLUE=8.313726e-01 MIN_BRIGHTNESS=0 MAX_BRIGHTNESS=100 SATURATION=0 MIN_SATURATION=20 TOLERANCE=20 IN_SLOPE=0 OUT_SLOPE=0 ALPHA_OFFSET=0 SPILL_THRESHOLD=0 SPILL_AMOUNT=0 SHOW_MASK=0></KEYFRAME>
+<KEYFRAME TITLE=cyan><CHROMAKEY_HSV RED=0 GREEN=9.647059e-01 BLUE=1 MIN_BRIGHTNESS=0 MAX_BRIGHTNESS=100 SATURATION=0 MIN_SATURATION=1.850000e+01 TOLERANCE=30 IN_SLOPE=0 OUT_SLOPE=0 ALPHA_OFFSET=0 SPILL_THRESHOLD=0 SPILL_AMOUNT=0 SHOW_MASK=0></KEYFRAME>
+<KEYFRAME TITLE=red><CHROMAKEY_HSV RED=1 GREEN=0 BLUE=9.137255e-01 MIN_BRIGHTNESS=11 MAX_BRIGHTNESS=100 SATURATION=0 MIN_SATURATION=20 TOLERANCE=20 IN_SLOPE=0 OUT_SLOPE=0 ALPHA_OFFSET=0 SPILL_THRESHOLD=0 SPILL_AMOUNT=0 SHOW_MASK=0></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=Histogram>
+<KEYFRAME TITLE=cr2><HISTOGRAM AUTOMATIC=0 THRESHOLD=9.990000e-01 PLOT=1 SPLIT=0 W=440 H=579 PARADE=0 MODE=3 LOW_OUTPUT_0=0 HIGH_OUTPUT_0=1 LOW_INPUT_0=0 HIGH_INPUT_0=1 GAMMA_0=1 LOW_OUTPUT_1=0 HIGH_OUTPUT_1=1 LOW_INPUT_1=0 HIGH_INPUT_1=1 GAMMA_1=1 LOW_OUTPUT_2=0 HIGH_OUTPUT_2=1 LOW_INPUT_2=0 HIGH_INPUT_2=1 GAMMA_2=1 LOW_OUTPUT_3=0 HIGH_OUTPUT_3=1 LOW_INPUT_3=0 HIGH_INPUT_3=5.548077e-01 GAMMA_3=2>
+</KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE="EQ Parametric">
+<KEYFRAME TITLE=ultrarunner><PARAMETRICEQ WETNESS=0 WINDOW_SIZE=4096>
+<BAND NUMBER=0 FREQ=2095 QUALITY=7.700000e-01 MAGNITUDE=5.800000e+00 MODE=3>
+<BAND NUMBER=1 FREQ=440 QUALITY=1 MAGNITUDE=0 MODE=0>
+<BAND NUMBER=2 FREQ=440 QUALITY=1 MAGNITUDE=0 MODE=0>
+</KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE=ReframeRT>
+<KEYFRAME TITLE=dave><REFRAMERT SCALE=2 DENOM=1 STRETCH=1></KEYFRAME>
+</PLUGIN>
+<PLUGIN TITLE="Sphere Cam">
+<KEYFRAME TITLE="gear360 4k"><SPHERECAM ENABLED_0=1 FOV_0=192 CENTER_X_0=2.520000e+01 CENTER_Y_0=5.179997e+01 ROTATE_X_0=100 ROTATE_Y_0=50 ROTATE_Z_0=0 ENABLED_1=1 FOV_1=1.917000e+02 CENTER_X_1=7.499998e+01 CENTER_Y_1=5.079998e+01 ROTATE_X_1=5.019999e+01 ROTATE_Y_1=4.940001e+01 ROTATE_Z_1=8.000001e-01 FEATHER=1 DRAW_GUIDES=0 MODE=1></KEYFRAME>
+<KEYFRAME TITLE="gear360 7k"><SPHERECAM ENABLED_0=1 FOV_0=194 CENTER_X_0=2.520000e+01 CENTER_Y_0=5.149998e+01 ROTATE_X_0=50 ROTATE_Y_0=50 ROTATE_Z_0=0 ENABLED_1=1 FOV_1=1.946000e+02 CENTER_X_1=7.499999e+01 CENTER_Y_1=5.129996e+01 ROTATE_X_1=0 ROTATE_Y_1=4.980000e+01 ROTATE_Z_1=1 FEATHER=1 DRAW_GUIDES=0 MODE=1></KEYFRAME>
+<KEYFRAME TITLE="gear360 sideways 4k"><SPHERECAM ENABLED_0=1 FOV_0=192 CENTER_X_0=2.530000e+01 CENTER_Y_0=5.129998e+01 ROTATE_X_0=100 ROTATE_Y_0=50 ROTATE_Z_0=90 ENABLED_1=1 FOV_1=1.917000e+02 CENTER_X_1=7.499998e+01 CENTER_Y_1=5.109998e+01 ROTATE_X_1=5.019999e+01 ROTATE_Y_1=4.980000e+01 ROTATE_Z_1=-8.889997e+01 FEATHER=1 DRAW_GUIDES=0 MODE=1></KEYFRAME>
+<KEYFRAME TITLE="gear360 sideways, 7k"><SPHERECAM ENABLED_0=1 FOV_0=194 CENTER_X_0=2.520000e+01 CENTER_Y_0=5.139998e+01 ROTATE_X_0=50 ROTATE_Y_0=50 ROTATE_Z_0=90 ENABLED_1=1 FOV_1=1.946000e+02 CENTER_X_1=7.499999e+01 CENTER_Y_1=5.079997e+01 ROTATE_X_1=0 ROTATE_Y_1=4.990000e+01 ROTATE_Z_1=-8.900002e+01 FEATHER=1 DRAW_GUIDES=0 MODE=1></KEYFRAME>
+</PLUGIN>
index a6426923cb64cb5da95603f0ae5bb31815ded62c..70f4728f47fc548b5a37cd3faff2aea18baa6e77 100644 (file)
@@ -31,7 +31,7 @@ export mkinstalldirs install_sh inst_sh
 
 # install to bin
 binstall:      install-recursive
-       cp -a COPYING README models ffmpeg msg info tips bin/.
+       cp -a COPYING README models Cinelerra_factory ffmpeg msg info tips bin/.
        sed -e 's/\<cin\>/$(WANT_CIN)/g' < image/cin.desktop \
                > "bin/applications/$(WANT_CIN).desktop"
        cp -a image/cin.svg "bin/pixmaps/$(WANT_CIN)".svg
@@ -49,7 +49,7 @@ cinstall:
        cd bin; $(inst_sh) "$(DESTDIR)$(WANT_CINLIB_DIR)" \
                bdwrite cutads hveg2enc mpeg2enc mplex mplexlo
        cd bin; $(inst_sh) "$(DESTDIR)$(datadir)/$(WANT_CIN)" \
-               COPYING README models ffmpeg msg info tips doc
+               COPYING README models Cinelerra_factory ffmpeg msg info tips doc
        cd bin/locale; $(inst_sh) "$(DESTDIR)$(localedir)" .
        cd bin/plugins; $(inst_sh) "$(DESTDIR)$(WANT_PLUGIN_DIR)" .
        cd bin/ladspa; $(inst_sh) "$(DESTDIR)$(WANT_LADSPA_DIR)" .
index ae6c41e00dae84a97b83973c2244d3dc8ede12c5..04a9fd7ccf11eadc39ba67e2d1f74bd06061a60e 100644 (file)
@@ -22,7 +22,7 @@ clean:
 
 install:
        for dir in $(SUBDIRS); do $(MAKE) -C $$dir install; done
-       cp -a COPYING README models ffmpeg msg info tips bin/.
+       cp -a COPYING README models Cinelerra_factory ffmpeg msg info tips bin/.
        for d in picon*; do cp -a $$d/. bin/plugins/$$d/.; done
 
 rebuild:
index 6fe883550bb4c6be5333ac7f1d1337499dbf7dc0..bd59f62ea7093578ac7e6194992a768125fa7646 100644 (file)
@@ -59,7 +59,6 @@ OBJS = \
        $(OBJDIR)/channel.o \
        $(OBJDIR)/channelpicker.o \
        $(OBJDIR)/chantables.o \
-       $(OBJDIR)/cicolors.o \
        $(OBJDIR)/clipedit.o \
        $(OBJDIR)/clippopup.o \
        $(OBJDIR)/colorpicker.o \
@@ -230,6 +229,7 @@ OBJS = \
        $(OBJDIR)/pluginvclient.o \
        $(OBJDIR)/preferences.o \
        $(OBJDIR)/preferencesthread.o \
+       $(OBJDIR)/presets.o \
        $(OBJDIR)/probeprefs.o \
        $(OBJDIR)/proxy.o \
        $(OBJDIR)/question.o \
index 0c167602ffa8f5c21bf1fa4df7011be96c5d6a23..3b58cad65914515034410c0b2a08ee86822dc5a1 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "aautomation.h"
 #include "atrack.inc"
-#include "colors.h"
+#include "bccolors.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "floatauto.h"
index cff01da035b300cd20338cb605cc06f1b22125d9..be7ba2c67b704e80841dfa860ff21247fd83e73a 100644 (file)
 #include "adeviceprefs.h"
 #include "audioalsa.h"
 #include "audiodevice.inc"
+#include "bcsignals.h"
 #include "bitspopup.h"
 #include "edl.h"
 #include "language.h"
+#include "mwindow.h"
 #include "playbackconfig.h"
 #include "preferences.h"
 #include "preferencesthread.h"
 #include "recordconfig.h"
+#include "theme.h"
 #include <string.h>
 
-#define DEVICE_H 50
+//#define DEVICE_H 50
 
 ADevicePrefs::ADevicePrefs(int x, int y, PreferencesWindow *pwindow, PreferencesDialog *dialog,
        AudioOutConfig *out_config, AudioInConfig *in_config, int mode)
@@ -141,7 +144,14 @@ int ADevicePrefs::initialize(int creation)
 
 int ADevicePrefs::get_h(int recording)
 {
-       return !recording ? DEVICE_H + 30 : DEVICE_H;
+       int margin = pwindow->mwindow->theme->widget_border;
+       int result = BC_Title::calculate_h(dialog, "X", MEDIUMFONT) + margin +
+               BC_TextBox::calculate_h(dialog, MEDIUMFONT, 1, 1);
+       if( !recording ) {
+               result += BC_CheckBox::calculate_h(dialog) + margin;
+       }
+
+       return result;
 }
 
 int ADevicePrefs::delete_objects()
@@ -261,6 +271,7 @@ int ADevicePrefs::create_oss_objs()
 {
        char *output_char = 0;
        int *output_int = 0;
+       int margin = pwindow->mwindow->theme->widget_border;
        int y1 = y;
        BC_Resources *resources = BC_WindowBase::get_resources();
 
@@ -279,7 +290,7 @@ int ADevicePrefs::create_oss_objs()
                        break;
                }
                dialog->add_subwindow(oss_enable[i] = new OSSEnable(x1, y1 + 20, output_int));
-               x1 += oss_enable[i]->get_w() + 5;
+               x1 += oss_enable[i]->get_w() + margin;
 #endif
                switch(mode) {
                case MODEPLAY:
@@ -299,10 +310,10 @@ int ADevicePrefs::create_oss_objs()
                        dialog->add_subwindow(path_title);
                }
 
-               oss_path[i] = new ADeviceTextBox(x1, y1 + 20, output_char);
+               oss_path[i] = new ADeviceTextBox(
+                       x1, y1 + path_title->get_h() + margin, output_char);
                dialog->add_subwindow(oss_path[i]);
-
-               x1 += oss_path[i]->get_w() + 5;
+               x1 += oss_path[i]->get_w() + margin;
                if(i == 0) {
                        switch(mode) {
                        case MODEPLAY:
@@ -318,14 +329,15 @@ int ADevicePrefs::create_oss_objs()
                        bits_title = new BC_Title(x1, y, _("Bits:"),
                                        MEDIUMFONT, resources->text_default);
                        dialog->add_subwindow(bits_title);
-                       oss_bits = new BitsPopup(dialog, x1, y1 + 20, output_int,
-                               0, 0, 0, 0, 1);
+                       oss_bits = new BitsPopup(dialog,
+                               x1, y1 + bits_title->get_h() + margin, 
+                               output_int, 0, 0, 0, 0, 1);
                        oss_bits->create_objects();
                }
 
-               x1 += oss_bits->get_w() + 5;
-               y1 += DEVICE_H;
-break;  // apparently, 'i' must be zero
+               x1 += oss_bits->get_w() + margin;
+//             y1 += DEVICE_H;
+               break;
        }
 
        return 0;
@@ -336,16 +348,16 @@ int ADevicePrefs::create_alsa_objs()
 #ifdef HAVE_ALSA
        char *output_char = 0;
        int *output_int = 0;
-       int y1 = y;
+       int margin = pwindow->mwindow->theme->widget_border;
        BC_Resources *resources = BC_WindowBase::get_resources();
 
-       int x1 = x + menu->get_w() + 5;
+       int x1 = x + menu->get_w() + margin;
+       int y1 = y;
 
        ArrayList<char*> *alsa_titles = new ArrayList<char*>;
        alsa_titles->set_array_delete();
        AudioALSA::list_devices(alsa_titles, 0, mode);
 
-
        alsa_drivers = new ArrayList<BC_ListBoxItem*>;
        for(int i = 0; i < alsa_titles->total; i++)
                alsa_drivers->append(new BC_ListBoxItem(alsa_titles->values[i]));
@@ -366,7 +378,9 @@ int ADevicePrefs::create_alsa_objs()
        path_title = new BC_Title(x1, y, _("Device:"),
                        MEDIUMFONT, resources->text_default);
        dialog->add_subwindow(path_title);
-       alsa_device = new ALSADevice(dialog, x1, y1 + 20, output_char, alsa_drivers);
+       y1 += path_title->get_h() + margin;
+       alsa_device = new ALSADevice(dialog,
+               x1, y1, output_char, alsa_drivers);
        alsa_device->create_objects();
        int x2 = x1;
 
@@ -385,10 +399,12 @@ int ADevicePrefs::create_alsa_objs()
        bits_title = new BC_Title(x1, y, _("Bits:"),
                        MEDIUMFONT, resources->text_default);
        dialog->add_subwindow(bits_title);
-       alsa_bits = new BitsPopup(dialog, x1, y1 + 20, output_int, 0, 0, 0, 0, 1);
+       y1 = y + bits_title->get_h() + margin;
+       alsa_bits = new BitsPopup(dialog,
+                       x1, y1, output_int, 0, 0, 0, 0, 1);
        alsa_bits->create_objects();
 
-       y1 += alsa_bits->get_h() + 20 + 5;
+       y1 += alsa_bits->get_h();
        x1 = x2;
 
        if(mode == MODEPLAY) {
@@ -615,15 +631,15 @@ ADriverMenu::~ADriverMenu()
 
 void ADriverMenu::create_objects()
 {
+#ifdef HAVE_ALSA
+       add_item(new ADriverItem(this, AUDIO_ALSA_TITLE, AUDIO_ALSA));
+#endif
+
 #ifdef HAVE_OSS
        add_item(new ADriverItem(this, AUDIO_OSS_TITLE, AUDIO_OSS));
        add_item(new ADriverItem(this, AUDIO_OSS_ENVY24_TITLE, AUDIO_OSS_ENVY24));
 #endif
 
-#ifdef HAVE_ALSA
-       add_item(new ADriverItem(this, AUDIO_ALSA_TITLE, AUDIO_ALSA));
-#endif
-
 #ifdef HAVE_ESOUND
        if(!do_input) add_item(new ADriverItem(this, AUDIO_ESOUND_TITLE, AUDIO_ESOUND));
 #endif
index 2712610760b4bede9c76bc79386623cff6631c27..ebe5051ff20a69aca3490918a01620093c429a36 100644 (file)
@@ -50,7 +50,8 @@ public:
        ~ADevicePrefs();
 
        void reset();
-       static int get_h(int recording = 0);
+//     static int get_h(int recording = 0);
+       int get_h(int recording = 0);
        int update(AudioOutConfig *out_config);
 // creation - set if this is the first initialize of the object
 //            to prevent file format from being overwritten
index af87bdbb91750ed1f2dd9cac55d714c3ca9a21b1..bb56d8bfc9ce38bcbb158112368ae0dcdf1efc7c 100644 (file)
@@ -134,6 +134,8 @@ int Asset::init_values()
 
        tiff_cmodel = 0;
        tiff_compression = 0;
+       mov_sphere = 0;
+       jpeg_sphere = 0;
 
        use_header = 1;
        id = EDL::next_id();
@@ -271,6 +273,10 @@ void Asset::copy_format(Asset *asset, int do_index)
 
        tiff_cmodel = asset->tiff_cmodel;
        tiff_compression = asset->tiff_compression;
+       
+       
+       mov_sphere = asset->mov_sphere;
+       jpeg_sphere = asset->jpeg_sphere;
 }
 
 int64_t Asset::get_index_offset(int channel)
@@ -360,7 +366,9 @@ int Asset::equivalent(Asset &asset, int test_audio, int test_video, EDL *edl)
                        interlace_fixmethod     == asset.interlace_fixmethod &&
                        width == asset.width &&
                        height == asset.height &&
-                       !strcmp(vcodec, asset.vcodec));
+                       !strcmp(vcodec, asset.vcodec) &&
+                       mov_sphere == asset.mov_sphere &&
+                       jpeg_sphere == asset.jpeg_sphere);
                if(result && format == FILE_FFMPEG)
                        result = !strcmp(ff_video_options, asset.ff_video_options) &&
                                ff_video_bitrate == asset.ff_video_bitrate &&
@@ -506,6 +514,8 @@ int Asset::read_video(FileXML *file)
        file->tag.get_property("VCODEC", vcodec);
 
        video_length = file->tag.get_property("VIDEO_LENGTH", (int64_t)0);
+       mov_sphere = file->tag.get_property("MOV_SPHERE", 0);
+       jpeg_sphere = file->tag.get_property("JPEG_SPHERE", 0);
        single_frame = file->tag.get_property("SINGLE_FRAME", (int64_t)0);
 
        interlace_autofixoption = file->tag.get_property("INTERLACE_AUTOFIX",0);
@@ -661,6 +671,8 @@ int Asset::write_video(FileXML *file)
                file->tag.set_property("VCODEC", vcodec);
 
        file->tag.set_property("VIDEO_LENGTH", video_length);
+       file->tag.set_property("MOV_SPHERE", mov_sphere);
+       file->tag.set_property("JPEG_SPHERE", jpeg_sphere);
        file->tag.set_property("SINGLE_FRAME", single_frame);
 
        file->tag.set_property("INTERLACE_AUTOFIX", interlace_autofixoption);
@@ -825,6 +837,8 @@ void Asset::load_defaults(BC_Hash *defaults,
        tiff_cmodel = GET_DEFAULT("TIFF_CMODEL", tiff_cmodel);
        tiff_compression = GET_DEFAULT("TIFF_COMPRESSION", tiff_compression);
 
+       mov_sphere = GET_DEFAULT("MOV_SPHERE", mov_sphere);
+       jpeg_sphere = GET_DEFAULT("JPEG_SPHERE", jpeg_sphere);
        boundaries();
 }
 
@@ -912,8 +926,16 @@ void Asset::save_defaults(BC_Hash *defaults,
                UPDATE_DEFAULT("EXR_COMPRESSION", exr_compression);
                UPDATE_DEFAULT("TIFF_CMODEL", tiff_cmodel);
                UPDATE_DEFAULT("TIFF_COMPRESSION", tiff_compression);
+
+
+
+               UPDATE_DEFAULT("MOV_SPHERE", mov_sphere);
+               UPDATE_DEFAULT("JPEG_SPHERE", jpeg_sphere);
        }
 
+
+
+
        if(do_bits)
        {
                UPDATE_DEFAULT("BITS", bits);
@@ -978,6 +1000,7 @@ int Asset::dump(FILE *fp)
                video_data, layers, program, frame_rate, width, height,
                vcodec, aspect_ratio,string);
        fprintf(fp,"   video_length %jd repeat %d\n", video_length, single_frame);
+       printf("   mov_sphere=%d jpeg_sphere=%d\n", mov_sphere, jpeg_sphere);
        return 0;
 }
 
index 4fa58aa41a010adb314b5d264da07b98a3c203d8..871ab22515592993715fcc4417fd09545a8d84f4 100644 (file)
@@ -150,6 +150,7 @@ public:
        char vcodec[BCTEXTLEN];
 
 // Length in frames
+// -1 means a still photo
        int64_t video_length;
 
 
@@ -226,6 +227,9 @@ public:
 
        int ac3_bitrate;
 
+// Insert tag for spherical playback
+       int mov_sphere, jpeg_sphere;
+
 // Image file sequences.  Background rendering doesn't want to write a
 // sequence header but instead wants to start the sequence numbering at a certain
 // number.  This ensures deletion of all the frames which aren't being used.
index c153e3db8935ed9ef0e3cc59ed00f04c4ed5c0e5..75c1bfa2d1efeaf663ae9d355ad4830e978d52ec 100644 (file)
@@ -145,14 +145,13 @@ AssetPopupInfo::~AssetPopupInfo()
 int AssetPopupInfo::handle_event()
 {
        int cur_x, cur_y;
-       popup->gui->get_abs_cursor_xy(cur_x, cur_y, 0);
-       
-       if( mwindow->session->drag_assets->total ) {
-               mwindow->awindow->asset_edit->edit_asset(
+       popup->gui->get_abs_cursor_xy(cur_x, cur_y);
+       if( mwindow->session->drag_assets->size() ) {
+               AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
+               asset_edit->edit_asset(
                        mwindow->session->drag_assets->values[0], cur_x, cur_y);
        }
-       else
-       if( mwindow->session->drag_clips->total ) {
+       else if( mwindow->session->drag_clips->size() ) {
                popup->gui->awindow->clip_edit->edit_clip(
                        mwindow->session->drag_clips->values[0], cur_x, cur_y);
        }
index 9387ed9d4120e2154015c9fed922f8300dc69ae8..ed9df7b90105614a2f726cea39bab7a66a8c61bb 100644 (file)
@@ -177,3 +177,15 @@ int ATrack::paste_derived(int64_t start, int64_t end, int64_t total_length, File
        return 0;
 }
 
+void ATrack::deglitch(double position, 
+       int edit_labels, int edit_plugins, int edit_autos)
+{
+       int64_t samples = to_units(position, 0);
+       edits->deglitch(samples);
+       if( edit_plugins ) {
+               for(int i = 0; i < plugin_set.size(); i++) {
+                       plugin_set.get(i)->deglitch(samples);
+               }
+       }
+}
+
index 010b3923d8c2edef263ff28b327b59e047891220..74a4d935fe9e7202086ad250585d4561586804ed 100644 (file)
@@ -76,6 +76,10 @@ public:
 
 
        int modify_handles(int64_t oldposition, int64_t newposition, int currentend);
+       void deglitch(double position, 
+               int edit_labels,
+               int edit_plugins,
+               int edit_autos);
 
        int64_t length();
 //     int get_dimensions(double &view_start,
index 727bdb2c6cfabb389be619d9be5df39ff29d300b..44c5eabe168bf0b1637f6a3760bbd75a49ad62b8 100644 (file)
 
 AudioConfig::AudioConfig()
 {
+       audio_in_driver =  AUDIO_ALSA;
+       afirewire_in_port = 0;
+       afirewire_in_channel = 63;
+       strcpy(oss_in_device, "/dev/dsp");
+       oss_in_channels = 2;
+       oss_in_bits = 16;
+       strcpy(esound_in_server, "");
+       esound_in_port = 0;
+
+       audio_out_driver = AUDIO_ALSA;
+       strpcy(oss_out_device, "/dev/dsp");
+       oss_out_channels = 2;
+       oss_out_bits = 16;
+       strpcy(esound_out_server, "");
+       esound_out_port = 0;
+
+       audio_duplex_driver = AUDIO_ALSA;
+       strcpy(oss_duplex_device, "/dev/dsp");
+       oss_duplex_channels = 2;
+       oss_duplex_bits = 16;
+       strcpy(esound_duplex_server, "");
+       esound_duplex_port = 0;
 }
 
 AudioConfig::~AudioConfig()
@@ -72,7 +94,7 @@ AudioConfig& AudioConfig::operator=(AudioConfig &that)
 
 int AudioConfig::load_defaults(BC_Hash *defaults)
 {
-       audio_in_driver =             defaults->get("AUDIOINDRIVER", AUDIO_OSS);
+       audio_in_driver =             defaults->get("AUDIOINDRIVER", AUDIO_ALSA);
        afirewire_in_port =           defaults->get("AFIREWIRE_IN_PORT", 0);
        afirewire_in_channel =        defaults->get("AFIREWIRE_IN_CHANNEL", 63);
        sprintf(oss_in_device, "/dev/dsp");
@@ -83,8 +105,8 @@ int AudioConfig::load_defaults(BC_Hash *defaults)
                                      defaults->get("ESOUND_IN_SERVER", esound_in_server);
        esound_in_port =              defaults->get("ESOUND_IN_PORT", 0);
 
-       audio_out_driver =                defaults->get("AUDIO_OUT_DRIVER", AUDIO_OSS);
-       audio_duplex_driver =             defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_OSS);
+       audio_out_driver =                defaults->get("AUDIO_OUT_DRIVER", AUDIO_ALSA);
+       audio_duplex_driver =             defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_ALSA);
        sprintf(oss_out_device, "/dev/dsp");
                                      defaults->get("OSS_OUT_DEVICE", oss_out_device);
        oss_out_channels =                defaults->get("OUT_CHANNELS", 2);
@@ -93,7 +115,7 @@ int AudioConfig::load_defaults(BC_Hash *defaults)
                                      defaults->get("ESOUND_OUT_SERVER", esound_out_server);
        esound_out_port =             defaults->get("ESOUND_OUT_PORT", 0);
 
-       audio_duplex_driver =         defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_OSS);
+       audio_duplex_driver =         defaults->get("AUDIO_DUPLEX_DRIVER", AUDIO_ALSA);
        sprintf(oss_duplex_device, "/dev/dsp");
                                      defaults->get("OSS_DUPLEX_DEVICE", oss_duplex_device);
        oss_duplex_channels =         defaults->get("DUPLEX_CHANNELS", 2);
index 1ce714fbbf715f38985c6ca58624b48df15464a7..2a21dd4d743c3e0e4a08d901f45bfcb705373b51 100644 (file)
@@ -24,7 +24,7 @@
 #include "autos.h"
 #include "atrack.inc"
 #include "bcsignals.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
index 7e1f56f0d3d29f7f565cfecd7739662214e9e3ab..d5f3204cc93df3a146c31bff7c7a976c9c9e1f0a 100644 (file)
@@ -35,7 +35,6 @@ AWindow::AWindow(MWindow *mwindow)
        this->mwindow = mwindow;
        current_folder[0] = 0;
        asset_remove = 0;
-       asset_edit = 0;
        clip_edit = 0;
        label_edit = 0;
 }
@@ -49,8 +48,8 @@ AWindow::~AWindow()
                gui->unlock_window();
        }
        Thread::join();
+       asset_editors.remove_all_objects();
        delete asset_remove;
-       delete asset_edit;
        delete label_edit;
        delete clip_edit;
        delete effect_tip;
@@ -62,7 +61,6 @@ void AWindow::create_objects()
        gui->create_objects();
        gui->async_update_assets();
        asset_remove = new AssetRemoveThread(mwindow);
-       asset_edit = new AssetEdit(mwindow);
        clip_edit = new ClipEdit(mwindow, this, 0);
        label_edit = new LabelEdit(mwindow, this, 0);
        effect_tip = new EffectTipDialog(mwindow, this);
@@ -78,6 +76,21 @@ int AWindow::load_defaults(BC_Hash *defaults)
 }
 
 
+AssetEdit *AWindow::get_asset_editor()
+{
+       AssetEdit *asset_edit = 0;
+       for( int i=0; !asset_edit && i<asset_editors.size(); ++i ) {
+               AssetEdit *thread = asset_editors[i];
+               if( !thread->running() ) asset_edit = thread;
+       }
+       if( !asset_edit ) {
+               asset_edit = new AssetEdit(mwindow);
+               asset_editors.append(asset_edit);
+       }
+       return asset_edit;
+}
+
+
 void AWindow::run()
 {
        gui->run_window();
index e7003f9a56d7efee8f0e0cce7c0dbb9c780a6bbe..40410b537f9a428facaf5c507f608f15fa561a9f 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef AWINDOW_H
 #define AWINDOW_H
 
+#include "arraylist.h"
 #include "assetedit.inc"
 #include "assetremove.inc"
 #include "awindowgui.inc"
@@ -42,6 +43,7 @@ public:
 
        void run();
        void create_objects();
+       AssetEdit *get_asset_editor();
        int load_defaults(BC_Hash *defaults);
        int save_defaults(BC_Hash *defaults);
 
@@ -49,7 +51,7 @@ public:
 
        AWindowGUI *gui;
        MWindow *mwindow;
-       AssetEdit *asset_edit;
+       ArrayList<AssetEdit*> asset_editors;
        AssetRemoveThread *asset_remove;
        ClipEdit *clip_edit;
        LabelEdit *label_edit;
index 5bca38f3687eb34c281042fc881da2a708d65fce..1267c001cd289b43079c538f58a189be1be54259 100644 (file)
@@ -1806,21 +1806,21 @@ int AWindowDeleteProject::handle_event()
        return 1;
 }
 
-AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y)
- : BC_Button(x, y, mwindow->theme->infoasset_data)
-{
-       this->mwindow = mwindow;
-       this->gui = gui;
-       set_tooltip(_("Edit information on asset"));
-}
-
-int AWindowInfo::handle_event()
-{
-       int cur_x, cur_y;
-       gui->get_abs_cursor_xy(cur_x, cur_y, 0);
-       gui->awindow->asset_edit->edit_asset(gui->selected_asset(), cur_x, cur_y);
-       return 1;
-}
+// AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y)
+//  : BC_Button(x, y, mwindow->theme->infoasset_data)
+// {
+//     this->mwindow = mwindow;
+//     this->gui = gui;
+//     set_tooltip(_("Edit information on asset"));
+// }
+// 
+// int AWindowInfo::handle_event()
+// {
+//     int cur_x, cur_y;
+//     gui->get_abs_cursor_xy(cur_x, cur_y, 0);
+//     gui->awindow->asset_edit->edit_asset(gui->selected_asset(), cur_x, cur_y);
+//     return 1;
+// }
 
 AWindowRedrawIndex::AWindowRedrawIndex(MWindow *mwindow, AWindowGUI *gui, int x, int y)
  : BC_Button(x, y, mwindow->theme->redrawindex_data)
@@ -2021,4 +2021,3 @@ int AWindowListSort::handle_event()
        return 1;
 }
 
-
index 8e02543aa5f855b5950201ded9ee8fcc0b74ff63..40b1e1bf8d08b22dadac577f04ba56b8203891dc 100644 (file)
@@ -121,8 +121,8 @@ int CacheBase::delete_oldest()
                        oldest = current;
        }
        if( oldest && oldest->position >= 0 ) {
+               result = oldest->get_size();
                del_item(oldest);
-               result = 1;
        }
        lock->unlock();
        return result;
index ae37fbb4d5f9a1910eeee93dd946c84b17b76718..a548891abede571876ac2e51efd0d36d474b2180 100644 (file)
@@ -78,7 +78,8 @@ public:
 // Called when done with the item returned by get_.
 // Ignore if item was 0.
        void unlock();
-// delete oldest member, returns 1 if item deleted or 0 if none found
+// Delete oldest item.  
+// Return number of bytes freed if successful.  Return 0 if nothing to delete.
        int delete_oldest();
 // Calculate current size of cache in bytes
        int64_t get_memory_usage();
index 72d8a906544c86c63ab63b2f1d94ea5c9e675b93..e07dd33923c9e4a04c1da01e982f955715cedce9 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -332,8 +332,8 @@ void Canvas::get_transfers(EDL *edl,
        float &canvas_x1, float &canvas_y1, float &canvas_x2, float &canvas_y2,
        int canvas_w, int canvas_h)
 {
-// printf("Canvas::get_transfers %d %d\n", canvas_w,
-//             canvas_h);
+//printf("Canvas::get_transfers %d canvas_w=%d canvas_h=%d\n", 
+// __LINE__,  canvas_w, canvas_h);
 // automatic canvas size detection
        if(canvas_w < 0) canvas_w = get_canvas()->get_w();
        if(canvas_h < 0) canvas_h = get_canvas()->get_h();
@@ -430,6 +430,11 @@ void Canvas::get_transfers(EDL *edl,
                        {
                                out_h = (int)(out_w / edl->get_aspect_ratio() + 0.5);
                                canvas_y1 = canvas_h / 2 - out_h / 2;
+// printf("Canvas::get_transfers %d canvas_h=%d out_h=%f canvas_y1=%f\n",
+// __LINE__,
+// canvas_h,
+// out_h,
+// canvas_y1);
                        }
                        canvas_x2 = canvas_x1 + out_w;
                        canvas_y2 = canvas_y1 + out_h;
@@ -459,7 +464,8 @@ void Canvas::get_transfers(EDL *edl,
        canvas_y1 = MAX(0, canvas_y1);
        canvas_x2 = MAX(canvas_x1, canvas_x2);
        canvas_y2 = MAX(canvas_y1, canvas_y2);
-// printf("Canvas::get_transfers 2 %f,%f %f,%f -> %f,%f %f,%f\n",
+// printf("Canvas::get_transfers %d %f,%f %f,%f -> %f,%f %f,%f\n",
+// __LINE__,
 // output_x1,
 // output_y1,
 // output_x2,
@@ -853,8 +859,8 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
 
        if( refresh_frame &&
           (refresh_frame->get_w() != device->out_w ||
-           refresh_frame->get_h() != device->out_h ||
-           refresh_frame->get_color_model() != best_color_model) ) {
+           refresh_frame->get_h() != device->out_h ) ) {
+// x11 direct render uses BC_BGR8888, use tranfer_from to remap
                delete refresh_frame;  refresh_frame = 0;
        }
 
@@ -872,7 +878,7 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
                get_canvas()->lock_window(" Canvas::output_refresh");
        }
        else
-               refresh_frame->copy_from(output_frame);
+               refresh_frame->transfer_from(output_frame);
 }
 
 
index b96be4f354bd539577d375e2044c1f715ded1863..a044338e459e357445256cbcbf339958d87da1b5 100644 (file)
@@ -1773,9 +1773,10 @@ void ChannelInfo::delete_batch()
 }
 
 ChannelScan::ChannelScan(MWindow *mwindow)
- : BC_MenuItem(_("Scan..."), _("Shift-S"), 'S')
+ : BC_MenuItem(_("Scan..."), _("Ctrl-Alt-s"), 's')
 {
-       set_shift();
+       set_ctrl();
+       set_alt();
        this->mwindow = mwindow;
 }
 
index 602fbbd03802354f344e7e57026ee571973eb82d..2f9df23c98be119a07287adaf934e185d89459aa 100644 (file)
@@ -141,7 +141,8 @@ int ClipPopupInfo::handle_event()
        popup->gui->get_abs_cursor_xy(cur_x, cur_y, 0);
 
        if( mwindow->session->drag_assets->total ) {
-               mwindow->awindow->asset_edit->edit_asset(
+               AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
+               asset_edit->edit_asset(
                        mwindow->session->drag_assets->values[0], cur_x, cur_y);
        }
        else
index 5c43fb93da1c49afe173a8970e5e0710cd26925e..a95f6ef381089faefa14f756fad665c6f3e33be1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "bcbutton.h"
 #include "bccapture.h"
+#include "bccolors.h"
 #include "bcdisplayinfo.h"
 #include "colorpicker.h"
 #include "condition.h"
@@ -28,7 +29,7 @@
 #include "language.h"
 #include "mutex.h"
 #include "mwindow.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.h"
 
 #include <string.h>
index 24a515fa83a3f3ec6009ab7211651dab01990545..20eff1207d05532fca714077f2b5c8c4b049bf72 100644 (file)
@@ -604,7 +604,7 @@ int CWindowGUI::drag_stop()
                if(mwindow->session->drag_assets->total)
                {
                        mwindow->gui->lock_window("CWindowGUI::drag_stop 1");
-                       mwindow->clear(0);
+                       mwindow->clear(0, 1);
                        mwindow->load_assets(mwindow->session->drag_assets,
                                mwindow->edl->local_session->get_selectionstart(),
                                LOADMODE_PASTE,
@@ -619,7 +619,7 @@ int CWindowGUI::drag_stop()
                if(mwindow->session->drag_clips->total)
                {
                        mwindow->gui->lock_window("CWindowGUI::drag_stop 2");
-                       mwindow->clear(0);
+                       mwindow->clear(0, 1);
                        mwindow->paste_edls(mwindow->session->drag_clips,
                                LOADMODE_PASTE,
                                mwindow->session->track_highlighted,
@@ -2167,15 +2167,24 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
        float blue = (float)*row++ / max; \
        if(do_yuv) \
        { \
-               mwindow->edl->local_session->red += red + V_TO_R * (blue - 0.5); \
-               mwindow->edl->local_session->green += red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
-               mwindow->edl->local_session->blue += red + U_TO_B * (green - 0.5); \
+               float r = red + V_TO_R * (blue - 0.5); \
+               float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
+               float b = red + U_TO_B * (green - 0.5); \
+               mwindow->edl->local_session->red += r; \
+               mwindow->edl->local_session->green += g; \
+               mwindow->edl->local_session->blue += b; \
+               if(r > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = r; \
+               if(g > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = g; \
+               if(b > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = b; \
        } \
        else \
        { \
                mwindow->edl->local_session->red += red; \
                mwindow->edl->local_session->green += green; \
                mwindow->edl->local_session->blue += blue; \
+               if(red > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = red; \
+               if(green > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = green; \
+               if(blue > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = blue; \
        } \
 }
 
@@ -2184,6 +2193,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        mwindow->edl->local_session->red = 0;
                        mwindow->edl->local_session->green = 0;
                        mwindow->edl->local_session->blue = 0;
+                       mwindow->edl->local_session->red_max = 0;
+                       mwindow->edl->local_session->green_max = 0;
+                       mwindow->edl->local_session->blue_max = 0;
                        for(int i = row1; i < row2; i++)
                        {
                                for(int j = column1; j < column2; j++)
index d73a265b5727d15d3e4391d479ea21845ddc57b4..73f1f23254a5925e7d1e4e28a8f647e4f25bd2fd 100644 (file)
@@ -1,7 +1,6 @@
-
 /*
  * CINELERRA
- * Copyright (C) 2008-2014 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,7 +22,7 @@
 #include <stdint.h>
 
 #include "automation.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "clip.h"
 #include "condition.h"
 #include "cpanel.h"
@@ -461,7 +460,7 @@ void CWindowCropGUI::update()
 
 
 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
- : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 250)
+ : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 290)
 {
 }
 
@@ -514,6 +513,8 @@ void CWindowEyedropGUI::create_objects()
 
        y = title6->get_y() + this->v->get_h() + 2*margin;
        add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
+       y += sample->get_h() + margin;
+       add_subwindow(use_max = new CWindowEyedropCheckBox(mwindow, this, x, y));
        update();
        unlock_window();
 }
@@ -528,27 +529,28 @@ void CWindowEyedropGUI::update()
 
        radius->update((int64_t)mwindow->edl->session->eyedrop_radius);
 
-       float r = mwindow->edl->local_session->red;
-       float g = mwindow->edl->local_session->green;
-       float b = mwindow->edl->local_session->blue;
-       red->update(r);
-       green->update(g);
-       blue->update(b);
+       LocalSession *local_session = mwindow->edl->local_session;
+       int use_max = local_session->use_max;
+       float r = use_max ? local_session->red_max : local_session->red;
+       float g = use_max ? local_session->green_max : local_session->green;
+       float b = use_max ? local_session->blue_max : local_session->blue;
+       this->red->update(r);
+       this->green->update(g);
+       this->blue->update(b);
+
        int rx = 255*r + 0.5;  bclamp(rx,0,255);
        int gx = 255*g + 0.5;  bclamp(gx,0,255);
        int bx = 255*b + 0.5;  bclamp(bx,0,255);
        char rgb_text[BCSTRLEN];
        sprintf(rgb_text, "#%02x%02x%02x", rx, gx, bx);
        rgb_hex->update(rgb_text);
-
+       
        float y, u, v;
-       YUV::rgb_to_yuv_f(mwindow->edl->local_session->red,
-               mwindow->edl->local_session->green,
-               mwindow->edl->local_session->blue,
-               y, u, v);
+       YUV::rgb_to_yuv_f(r, g, b, y, u, v);
        this->y->update(y);
        this->u->update(u);  u += 0.5;
        this->v->update(v);  v += 0.5;
+
        int yx = 255*y + 0.5;  bclamp(yx,0,255);
        int ux = 255*u + 0.5;  bclamp(ux,0,255);
        int vx = 255*v + 0.5;  bclamp(vx,0,255);
@@ -690,6 +692,23 @@ int CWindowCurveToggle::handle_event()
 }
 
 
+CWindowEyedropCheckBox::CWindowEyedropCheckBox(MWindow *mwindow, 
+       CWindowEyedropGUI *gui, int x, int y)
+ : BC_CheckBox(x, y, mwindow->edl->local_session->use_max, _("Use maximum"))
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+}
+
+int CWindowEyedropCheckBox::handle_event()
+{
+       mwindow->edl->local_session->use_max = get_value();
+       
+       gui->update();
+       return 1;
+}
+
+
 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
  : CWindowToolGUI(mwindow,
        thread,
index 651627e0860f8206d12aac83fa23f4edbb3b274b..9361034200c5977c233984da6fe3d38c36049565 100644 (file)
@@ -253,7 +253,7 @@ public:
 };
 
 
-
+class CWindowEyedropCheckBox;
 class CWindowEyedropGUI : public CWindowToolGUI
 {
 public:
@@ -266,12 +266,27 @@ public:
 
        BC_Title *current;
        CWindowCoord *radius;
+       CWindowEyedropCheckBox *use_max;
        BC_Title *red, *green, *blue, *y, *u, *v;
        BC_Title *rgb_hex, *yuv_hex;
        BC_SubWindow *sample;
 };
 
 
+class CWindowEyedropCheckBox : public BC_CheckBox
+{
+public:
+       CWindowEyedropCheckBox(MWindow *mwindow, 
+               CWindowEyedropGUI *gui,
+               int x, 
+               int y);
+
+       int handle_event();
+       MWindow *mwindow;
+       CWindowEyedropGUI *gui;
+};
+
+
 
 class CWindowCameraGUI : public CWindowToolGUI
 {
index 3658922df6d816a62cc1486e396072d7900649fd..d9f55ba74d546a89eaf3f756e595d82224237a78 100644 (file)
@@ -713,13 +713,17 @@ int Edit::shift_end_out(int edit_mode,
                                next->startproject += cut_length;
                                next->startsource += cut_length;
                                next->length -= cut_length;
-//printf("Edit::shift_end_out 2 %d\n", cut_length);
+//printf("Edit::shift_end_out %d cut_length=%d\n", __LINE__, cut_length);
                        }
                        else
                        {
+//printf("Edit::shift_end_out %d cut_length=%d next->length=%d\n", __LINE__, cut_length, next->length);
                                cut_length = next->length;
+                               next->startproject += next->length;
+                               next->startsource += next->length;
                                next->length = 0;
                                length += cut_length;
+//track->dump();
                        }
                }
                else
index a8e668f844c3dedf15322cc0abc320e7600a2525..4f54457bdc6f464db93c2938b36bea968dc12b6c 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -768,7 +768,7 @@ int Edits::modify_handles(double oldposition, double newposition, int currentend
                                else
                                {
 // move end of edit out
-//printf("Edits::modify_handle 6\n");
+//printf("Edits::modify_handle %d edit_mode=%d\n", __LINE__, edit_mode);
                                        current_edit->shift_end_out(edit_mode,
                                                track->to_units(newposition, 0),
                                                track->to_units(oldposition, 0),
@@ -843,3 +843,124 @@ void Edits::shift_effects_recursive(int64_t position, int64_t length, int edit_a
        track->shift_effects(position, length, edit_autos);
 }
 
+// only used for audio but also used for plugins which inherit from Edits
+void Edits::deglitch(int64_t position)
+{
+// range from the splice junk appears
+       int64_t threshold = (int64_t)((double)edl->session->sample_rate / 
+               edl->session->frame_rate) / 2;
+       Edit *current = 0;
+
+// the last edit before the splice
+       Edit *edit1 = 0;
+       if(first)
+       {
+               for(current = first; current; current = NEXT)
+               {
+                       if(current->startproject + current->length >= position - threshold)
+                       {
+                               edit1 = current;
+                               break;
+                       }
+               }
+
+// ignore if it ends after the splice
+               if(current && current->startproject + current->length >= position)
+               {
+                       edit1 = 0;
+               }
+       }
+
+// the first edit after the splice
+       Edit *edit2 = 0;
+       if(last)
+       {
+               for(current = last; current; current = PREVIOUS)
+               {
+                       if(current->startproject < position + threshold)
+                       {
+                               edit2 = current;
+                               break;
+                       }
+               }
+
+       // ignore if it starts before the splice
+               if(current && current->startproject < position)
+               {
+                       edit2 = 0;
+               }
+       }
+
+
+
+
+// printf("Edits::deglitch %d position=%ld edit1=%p edit2=%p\n", __LINE__,
+// position, 
+// edit1, 
+// edit2);
+// delete junk between the edits
+       if(edit1 != edit2)
+       {
+               if(edit1 != 0)
+               {
+// end the starting edit later
+                       current = edit1->next;
+                       while(current != 0 &&
+                               current != edit2 &&
+                               current->startproject < position)
+                       {
+                               Edit* next = NEXT;
+
+                               edit1->length += current->length;
+                               remove(current);
+
+                               current = next;
+                       }
+               }
+               
+               if(edit2 != 0)
+               {
+// start the ending edit earlier
+                       current = edit2->previous;
+                       while(current != 0 && 
+                               current != edit1 &&
+                               current->startproject >= position)
+                       {
+                               Edit *previous = PREVIOUS;
+
+                               int64_t length = current->length;
+//printf("Edits::deglitch %d length=%ld\n", __LINE__, length);
+                               if(!edit2->silence() && 
+                                       length > edit2->startsource)
+                               {
+                                       length = edit2->startsource;
+                               }
+
+                               // shift edit2 by using material from its source
+                               edit2->startproject -= length;
+                               edit2->startsource -= length;
+                               // assume enough is at the end
+                               edit2->length += length;
+
+                               // shift edit2 & its source earlier by remainder
+                               if(length < current->length)
+                               {
+                                       int64_t remainder = current->length - length;
+                                       edit2->startproject -= remainder;
+                                       // assume enough is at the end
+                                       edit2->length += remainder;
+                               }
+
+                               remove(current);
+
+
+                               current = previous;
+                       }
+               }
+       }
+       
+}
+
+
+
+
index d35917c71127c831c268ff7bf0a85df70eeb21ff..040c6bfa4cba746101b9d4269e3f12edf41106c4 100644 (file)
@@ -123,6 +123,7 @@ public:
                int edit_plugins,
                int edit_autos,
                Edits *trim_edits);
+       void deglitch(int64_t position);
        virtual int optimize();
 
        virtual int clone_derived(Edit* new_edit, Edit* old_edit) { return 0; }
index d6810aa763b05bd779b34a4a3c441c648aa381bf..cd20a7b0d56e570d3a36de7b47bd6315fcff947e 100644 (file)
@@ -808,12 +808,23 @@ void EDL::set_outpoint(double position)
        }
 }
 
+void EDL::deglitch(double position)
+{
+       if( !session->cursor_on_frames ) return;
+       Track *current_track = tracks->first; 
+       for( ; current_track; current_track=current_track->next ) {
+               if( !current_track->record ) continue;
+               if( current_track->data_type != TRACK_AUDIO ) continue;
+               ATrack *atrack = (ATrack*)current_track;
+               atrack->deglitch(position, 
+                       session->labels_follow_edits, 
+                       session->plugins_follow_edits, 
+                       session->autos_follow_edits);
+       }
+}
 
-int EDL::clear(double start,
-       double end,
-       int clear_labels,
-       int clear_plugins,
-       int edit_autos)
+int EDL::clear(double start, double end,
+       int clear_labels, int clear_plugins, int edit_autos)
 {
        if(start == end)
        {
index 3b1d22538726dad9422534d3fcc430cd33b8f194..45740cdf05f2ec9a6f412a9a17d006d57d15d89e 100644 (file)
@@ -189,6 +189,7 @@ public:
                int clear_labels,
                int clear_plugins,
                int edit_autos);
+       void deglitch(double position);
 // Insert the asset at a point in the EDL
        void insert_asset(Asset *asset,
                EDL *nested_edl,
index 0b6f218a4961d3e0b15c2cbbebd2f0173847f358..337d4bd4c5a2c7cd95d9ce19192aca743da04f17 100644 (file)
@@ -48,9 +48,9 @@ class EDL;
 #define EDIT_HANDLE_MODES 3
 
 // Behavior for the edit handles based on mouse button
-#define MOVE_ALL_EDITS 0
-#define MOVE_ONE_EDIT 1
-#define MOVE_NO_EDITS 2
+#define MOVE_ALL_EDITS 0 // default for left button
+#define MOVE_ONE_EDIT 1 // default for middle button
+#define MOVE_NO_EDITS 2 // default for right button
 #define MOVE_EDITS_DISABLED 3
 
 // AWindow folders
index 5876b9198bc96b101da278af04e160d8c5b056f6..d4c6df80aa43a408b0cf09036321eed29be1044a 100644 (file)
@@ -116,15 +116,15 @@ EDLSession::EDLSession(EDL *edl)
        record_write_length = 131072;
        record_realtime_toc = 1;
 
-        safe_regions = 0;
+       safe_regions = 0;
        sample_rate = 48000;
-        scrub_speed = 2.;
-        show_assets = 1;
-        show_titles = 1;
+       scrub_speed = 2.;
+       show_assets = 1;
+       show_titles = 1;
        test_playback_edits = 1;
        time_format = TIME_HMSF;
-        nudge_format = 1;
-        tool_window = 0;
+       nudge_format = 1;
+       tool_window = 0;
        for(int i = 0; i < MAXCHANNELS; i++) {
                vchannel_x[i] = 64*i;
                vchannel_y[i] = 0;
@@ -133,13 +133,13 @@ EDLSession::EDLSession(EDL *edl)
        aconfig_in = new AudioInConfig;
        vconfig_in = new VideoInConfig;
        recording_format = new Asset;
-        video_every_frame = 0;
-        video_asynchronous = 0;
+       video_every_frame = 0;
+//     video_asynchronous = 0;
        video_tracks = 1;
        video_write_length = 30;
-        view_follows_playback = 1;
-        vwindow_meter = 0;
-        vwindow_zoom = 1.;
+       view_follows_playback = 1;
+       vwindow_meter = 0;
+       vwindow_zoom = 1.;
 
        playback_config = new PlaybackConfig;
 }
@@ -159,7 +159,7 @@ int EDLSession::need_rerender(EDLSession *ptr)
        return ((playback_preload != ptr->playback_preload) ||
                (interpolation_type != ptr->interpolation_type) ||
                (video_every_frame != ptr->video_every_frame) ||
-               (video_asynchronous != ptr->video_asynchronous) ||
+//             (video_asynchronous != ptr->video_asynchronous) ||
                (real_time_playback != ptr->real_time_playback) ||
                (playback_software_position != ptr->playback_software_position) ||
                (test_playback_edits != ptr->test_playback_edits) ||
@@ -167,7 +167,9 @@ int EDLSession::need_rerender(EDLSession *ptr)
                (decode_subtitles != ptr->decode_subtitles) ||
                (subtitle_number != ptr->subtitle_number) ||
                (interpolate_raw != ptr->interpolate_raw) ||
-               (white_balance_raw != ptr->white_balance_raw));
+               (white_balance_raw != ptr->white_balance_raw) ||
+               (proxy_scale != ptr->proxy_scale) ||
+               (proxy_use_scaler != ptr->proxy_use_scaler));
 }
 
 void EDLSession::equivalent_output(EDLSession *session, double *result)
@@ -328,7 +330,7 @@ int EDLSession::load_defaults(BC_Hash *defaults)
        }
        video_channels = defaults->get("VCHANNELS", video_channels);
        video_every_frame = defaults->get("VIDEO_EVERY_FRAME", 0);
-       video_asynchronous = defaults->get("VIDEO_ASYNCHRONOUS", 0);
+//     video_asynchronous = defaults->get("VIDEO_ASYNCHRONOUS", 0);
        video_tracks = defaults->get("VTRACKS", video_tracks);
        video_write_length = defaults->get("VIDEO_WRITE_LENGTH", 30);
        view_follows_playback = defaults->get("VIEW_FOLLOWS_PLAYBACK", 1);
@@ -441,7 +443,7 @@ int EDLSession::save_defaults(BC_Hash *defaults)
        defaults->update("SAFE_REGIONS", safe_regions);
        defaults->update("SAMPLERATE", sample_rate);
        defaults->update("SCRUB_SPEED", scrub_speed);
-       defaults->update("SI_USEDURATION",si_useduration);
+       defaults->update("SI_USEDURATION",si_useduration);
        defaults->update("SI_DURATION",si_duration);
        defaults->update("SHOW_ASSETS", show_assets);
        defaults->update("SHOW_TITLES", show_titles);
@@ -458,7 +460,7 @@ int EDLSession::save_defaults(BC_Hash *defaults)
        }
        defaults->update("VCHANNELS", video_channels);
        defaults->update("VIDEO_EVERY_FRAME", video_every_frame);
-       defaults->update("VIDEO_ASYNCHRONOUS", video_asynchronous);
+//     defaults->update("VIDEO_ASYNCHRONOUS", video_asynchronous);
        defaults->update("VTRACKS", video_tracks);
        defaults->update("VIDEO_WRITE_LENGTH", video_write_length);
        defaults->update("VIEW_FOLLOWS_PLAYBACK", view_follows_playback);
@@ -723,7 +725,7 @@ int EDLSession::save_video_config(FileXML *file)
        file->tag.set_property("COLORMODEL", string);
        ilacemode_to_xmltext(string, interlace_mode);
        file->tag.set_property("INTERLACE_MODE",string);
-    file->tag.set_property("CHANNELS", video_channels);
+       file->tag.set_property("CHANNELS", video_channels);
        for(int i = 0; i < video_channels; i++)
        {
                sprintf(string, "VCHANNEL_X_%d", i);
@@ -872,7 +874,7 @@ int EDLSession::copy(EDLSession *session)
        video_channels = session->video_channels;
        *vconfig_in = *session->vconfig_in;
        video_every_frame = session->video_every_frame;
-       video_asynchronous = session->video_asynchronous;
+//     video_asynchronous = session->video_asynchronous;
        video_tracks = session->video_tracks;
        video_write_length = session->video_write_length;
        view_follows_playback = session->view_follows_playback;
index d5d610ee742dc6a68edd5d9a61b630ae5953f0b6..89748b6550fcfad693445a0326f1b4cf3ba0b120 100644 (file)
@@ -214,7 +214,7 @@ public:
 // play every frame
        int video_every_frame;
 // decode video asynchronously
-       int video_asynchronous;
+//     int video_asynchronous;
        int video_tracks;
 // number of frames to write to disk at a time during video recording.
        int video_write_length;
index e031dcdbac7f19e184954f828683cb3eaf386a2a..1b4e100dfec252dc7295cedafa093a690bba07c5 100644 (file)
@@ -328,6 +328,8 @@ int FFStream::decode_activate()
                                if( decoder->capabilities & AV_CODEC_CAP_DR1 )
                                        avctx->flags |= CODEC_FLAG_EMU_EDGE;
                                avcodec_parameters_to_context(avctx, st->codecpar);
+                               if( !av_dict_get(copts, "threads", NULL, 0) )
+                                       avctx->thread_count = ffmpeg->ff_cpus();
                                ret = avcodec_open2(avctx, decoder, &copts);
                        }
                        if( ret >= 0 ) {
@@ -2001,6 +2003,8 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                av_dict_set(&sopts, "cin_bitrate", 0, 0);
                av_dict_set(&sopts, "cin_quality", 0, 0);
 
+               if( !av_dict_get(sopts, "threads", NULL, 0) )
+                       ctx->thread_count = ff_cpus();
                ret = avcodec_open2(ctx, codec, &sopts);
                if( ret >= 0 ) {
                        ret = avcodec_parameters_from_context(st->codecpar, ctx);
@@ -2682,6 +2686,8 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
                }
                if( ret >= 0 ) {
                        avcodec_parameters_to_context(avctx, st->codecpar);
+                       if( !av_dict_get(copts, "threads", NULL, 0) )
+                               avctx->thread_count = ff_cpus();
                        ret = avcodec_open2(avctx, decoder, &copts);
                }
                av_dict_free(&copts);
index 0fb926b26d6601fd4e99018bf4f2f08bf1f19664..4b9c1be85a5ccc60c4544442de152593834e2b7b 100644 (file)
@@ -75,6 +75,7 @@
 #include "samples.h"
 #include "vframe.h"
 
+//static int temp_debug = 0;
 //suppress noref warning
 void *vorbis0_ov_callbacks[] = {
  &OV_CALLBACKS_DEFAULT, &OV_CALLBACKS_NOCLOSE,
@@ -99,8 +100,10 @@ File::~File()
                format_completion->unlock();
        }
 
-       if( temp_frame ) delete temp_frame;
-
+       if( temp_frame ) {
+//printf("File::~File %d temp_debug=%d\n", __LINE__, --temp_debug);
+               delete temp_frame;
+       }
 
        close_file(0);
 
@@ -298,7 +301,6 @@ void File::set_white_balance_raw(int value)
        this->white_balance_raw = value;
 }
 
-
 void File::set_cache_frames(int value)
 {
 // caching only done locally
@@ -319,7 +321,7 @@ int File::purge_cache()
 
 int File::delete_oldest()
 {
-// caching only done locally
+// return the number of bytes freed
        return frame_cache->delete_oldest();
 }
 
@@ -474,8 +476,6 @@ int File::open_file(Preferences *preferences,
        this->wr = wr;
        file = 0;
 
-       if( debug ) printf("File::open_file %d\n", __LINE__);
-
        if( debug ) printf("File::open_file %p %d\n", this, __LINE__);
 
        switch( this->asset->format ) {
@@ -1113,14 +1113,7 @@ int File::read_frame(VFrame *frame, int is_thread)
        const int debug = 0;
 //printf("File::read_frame pos=%jd cache=%d 1frame=%d\n",
 // current_frame, use_cache, asset->single_frame);
-       if( debug ) PRINT_TRACE
-
-//printf("File::read_frame %d\n", __LINE__);
-
        if( video_thread && !is_thread ) return video_thread->read_frame(frame);
-
-//printf("File::read_frame %d\n", __LINE__);
-       if( debug ) PRINT_TRACE
        if( !file ) return 1;
        if( debug ) PRINT_TRACE
        int result = 0;
@@ -1128,6 +1121,7 @@ int File::read_frame(VFrame *frame, int is_thread)
        int advance_position = 1;
        int cache_active = use_cache || asset->single_frame ? 1 : 0;
        int64_t cache_position = !asset->single_frame ? current_frame : -1;
+
 // Test cache
        if( cache_active && frame_cache->get_frame(frame, cache_position,
                        current_layer, asset->frame_rate) ) {
@@ -1138,8 +1132,9 @@ int File::read_frame(VFrame *frame, int is_thread)
 // Need temp
        else if( frame->get_color_model() != BC_COMPRESSED &&
                (supported_colormodel != frame->get_color_model() ||
-               frame->get_w() != asset->width ||
-               frame->get_h() != asset->height) ) {
+               (!file->can_scale_input() &&
+                       (frame->get_w() != asset->width ||
+                        frame->get_h() != asset->height))) ) {
 
 //                     printf("File::read_frame %d\n", __LINE__);
 // Can't advance position here because it needs to be added to cache
@@ -1150,14 +1145,8 @@ int File::read_frame(VFrame *frame, int is_thread)
                        }
                }
 
-//                     printf("File::read_frame %d\n", __LINE__);
                if( !temp_frame ) {
-                       temp_frame = new VFrame(0,
-                               -1,
-                               asset->width,
-                               asset->height,
-                               supported_colormodel,
-                               -1);
+                       temp_frame = new VFrame(asset->width, asset->height, supported_colormodel);
                }
 
 //                     printf("File::read_frame %d\n", __LINE__);
@@ -1191,10 +1180,7 @@ int File::read_frame(VFrame *frame, int is_thread)
        return 0;
 }
 
-int File::can_copy_from(Asset *asset,
-       int64_t position,
-       int output_w,
-       int output_h)
+int File::can_copy_from(Asset *asset, int64_t position, int output_w, int output_h)
 {
        if( asset && file ) {
                return asset->width == output_w &&
index 4d80870ac3db729d1f7f9f5e19d243e2f1e4a319..f62739e0990b23605f1ac0ff3d1c86867daacde9 100644 (file)
@@ -86,8 +86,9 @@ public:
 // to delete the file object.  Otherwise we'd delete just the cached frames
 // while the list of open files grew.
        void set_cache_frames(int value);
-// Delete frame cache.  Return 0 if successful.  Return 1 if
-// nothing to delete.
+// Delete oldest frame from cache.
+// Return number of bytes freed if successful.
+// Return 0 if nothing to delete.
        int purge_cache();
 // Delete oldest frame from cache.  Return 0 if successful.  Return 1 if
 // nothing to delete.
index 3555e1e267f9a2f0bf69c0c1d7ac73bf16cd99e0..1fc58c0b28b99260926f7a75ab2a7f6da444feff 100644 (file)
@@ -127,6 +127,7 @@ public:
        virtual int colormodel_supported(int colormodel) { return BC_RGB888; }
 // This file can copy compressed frames directly from the asset
        virtual int can_copy_from(Asset *asset, int64_t position) { return 0; }
+       virtual int can_scale_input() { return 0; }
        virtual int get_render_strategy(ArrayList<int>* render_strategies) { return VRENDER_VPIXEL; }
 
 // Manages an audio history buffer
index 99fa71193af683c2df5194f7f67911ccf2bfeea9..f3f535681234e3bbefe1a17d841eae4443458c55 100644 (file)
@@ -338,33 +338,13 @@ int FileFFMPEG::colormodel_supported(int colormodel)
 int FileFFMPEG::get_best_colormodel(Asset *asset, int driver)
 {
        switch(driver) {
-       case PLAYBACK_X11:
-               return BC_RGB888;
-       case PLAYBACK_X11_XV:
-       case PLAYBACK_ASYNCHRONOUS:
-               return BC_YUV888;
-       case PLAYBACK_X11_GL:
-               return BC_YUV888;
-       case PLAYBACK_DV1394:
-       case PLAYBACK_FIREWIRE:
-               return BC_YUV422P;
-       case VIDEO4LINUX2:
-               return BC_RGB888;
-       case VIDEO4LINUX2JPEG:
-               return BC_COMPRESSED;
-       case CAPTURE_DVB:
-       case VIDEO4LINUX2MPEG:
-               return BC_YUV422P;
-       case CAPTURE_JPEG_WEBCAM:
-               return BC_COMPRESSED;
-       case CAPTURE_YUYV_WEBCAM:
-               return BC_YUV422;
-       case CAPTURE_FIREWIRE:
-       case CAPTURE_IEC61883:
-               return BC_YUV422P;
+// the direct X11 color model requires scaling in the codec
+       case PLAYBACK_X11: return BC_BGR8888;
+//     case PLAYBACK_X11: return BC_RGB888;
+       case PLAYBACK_X11_GL: return BC_RGB888;
        }
 
-       return BC_RGB888;
+       return BC_YUV420P;
 }
 
 int FileFFMPEG::can_render(const char *fformat, const char *type)
index 51e191519918e39ec73ac3f343c526dff462da1a..973cde15c847ff8f42eb48b624732a94311f522e 100644 (file)
@@ -50,6 +50,7 @@ public:
        int write_frames(VFrame ***frames,int len);
        int read_samples(double *buffer,int64_t len);
        int read_frame(VFrame *frame);
+       int can_scale_input() { return 1; }
        int64_t get_memory_usage(void);
        int colormodel_supported(int colormodel);
        static int get_best_colormodel(Asset *asset, int driver);
index e3f57bb85c5dc500a929bbf4cc5aafacdd1c5a0d..3abfa99fad9515309f4a7a67990da2bd8ba12bd2 100644 (file)
@@ -163,6 +163,59 @@ int FileJPEG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
                frame->get_color_model(),
                1);
 
+// insert spherical tag
+       if(asset->jpeg_sphere)
+       {
+               const char *sphere_tag = 
+                       "http://ns.adobe.com/xap/1.0/\x00<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?>\n"
+                       "<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::Cinelerra'>\n"
+                       "<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n"
+                       "\n"
+                       " <rdf:Description rdf:about=''\n"
+                       "  xmlns:GPano='http://ns.google.com/photos/1.0/panorama/'>\n"
+                       "  <GPano:ProjectionType>equirectangular</GPano:ProjectionType>\n"
+                       " </rdf:Description>\n"
+                       "</rdf:RDF>\n"
+                       "</x:xmpmeta>\n"
+                       "<?xpacket end='w'?>";
+
+// calculate length by skipping the \x00 byte
+               int skip = 32;
+               int tag_len = strlen(sphere_tag + skip) + skip;
+               int tag_len2 = tag_len + 2;
+               int tag_len3 = tag_len + 4;
+               
+               data->allocate_compressed_data(
+                       mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor) + tag_len3);
+               data->set_compressed_size(
+                       mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor) + tag_len3);
+                       
+               int jfif_size = 0x14;
+               uint8_t *ptr = data->get_data();
+               memcpy(ptr, 
+                       mjpeg_output_buffer((mjpeg_t*)jpeg_unit->compressor), 
+                       jfif_size);
+               ptr += jfif_size;
+               *ptr++ = 0xff;
+               *ptr++ = 0xe1;
+               *ptr++ = (tag_len2 >> 8) & 0xff;
+               *ptr++ = tag_len2 & 0xff;
+               memcpy(ptr,
+                       sphere_tag,
+                       tag_len);
+               ptr += tag_len;
+               memcpy(ptr,
+                       mjpeg_output_buffer((mjpeg_t*)jpeg_unit->compressor) + jfif_size,
+                       mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor) - jfif_size);
+       }
+       else
+       {
+               data->allocate_compressed_data(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor));
+               data->set_compressed_size(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor));
+               memcpy(data->get_data(), 
+                       mjpeg_output_buffer((mjpeg_t*)jpeg_unit->compressor), 
+                       mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor));
+       }
        data->allocate_compressed_data(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor));
        data->set_compressed_size(mjpeg_output_size((mjpeg_t*)jpeg_unit->compressor));
        memcpy(data->get_data(),
@@ -295,7 +348,7 @@ JPEGConfigVideo::JPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset)
        parent_window->get_abs_cursor_x(1),
        parent_window->get_abs_cursor_y(1),
        400,
-       100)
+       200)
 {
        this->parent_window = parent_window;
        this->asset = asset;
@@ -310,17 +363,13 @@ void JPEGConfigVideo::create_objects()
        int x = 10, y = 10;
        lock_window("JPEGConfigVideo::create_objects");
        add_subwindow(new BC_Title(x, y, _("Quality:")));
-       add_subwindow(new BC_ISlider(x + 80,
-               y,
-               0,
-               200,
-               200,
-               0,
-               100,
-               asset->jpeg_quality,
-               0,
-               0,
+       BC_ISlider *slider;
+       add_subwindow(slider = new BC_ISlider(x + 80, y,
+               0, 200, 200, 0, 100, asset->jpeg_quality, 0, 0,
                &asset->jpeg_quality));
+       y += slider->get_h() + 10;
+       add_subwindow(new BC_CheckBox(x, y, 
+               &asset->jpeg_sphere, _("Tag for spherical playback")));
 
        add_subwindow(new BC_OKButton(this));
        show_window(1);
index 8f79da07046bf2082b6d5112503c9bbb9b1966af..4614f3f831f40cf9e842f3be3dafd65b629448c5 100644 (file)
@@ -296,7 +296,7 @@ int FileList::read_frame(VFrame *frame)
 
                FILE *in;
 
-// Fix path for VFS
+// Fix path for VFS.  Not used anymore.
                if(!strncmp(asset->path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
                        sprintf(string, "%s%s", RENDERFARM_FS_PREFIX, path);
                else
index 0526875ba4c73debd051670c56affaa60ec53fd9..8310942cb6ac158375c3a46d87193421277b343b 100644 (file)
@@ -998,7 +998,9 @@ int FileMPEG::get_best_colormodel(Asset *asset, int driver)
        switch(driver)
        {
                case PLAYBACK_X11:
-                       return BC_RGB888;
+//                     return BC_RGB888;
+// the direct X11 color model requires scaling in the codec
+                       return BC_BGR8888;
                case PLAYBACK_X11_XV:
                case PLAYBACK_ASYNCHRONOUS:
                        return zmpeg3_cmdl(asset->vmpeg_cmodel) > 0 ?
index 0c870bd10a664cef3d6bf7b2e90993d2df1abb39..9b8db9dd15ddad4f045a1a167f0926a649425d3a 100644 (file)
@@ -110,6 +110,7 @@ public:
         static const char *zmpeg3_cmdl_name(int cmdl);
 // This file can copy frames directly from the asset
        int can_copy_from(Asset *asset, int64_t position);
+       int can_scale_input() { return 1; }
 
 private:
        void to_streamchannel(int channel, int &stream_out, int &channel_out);
index 60d0b6c2905d5dce9d1295f7151dacdbcf18ebd8..7d94acdc8bda3dd592e139cc09d60efe116f94c9 100644 (file)
@@ -118,6 +118,7 @@ void FormatTools::create_objects(
        int x = init_x;
        int y = init_y;
        int ylev = init_y;
+       int margin = mwindow->theme->widget_border;
 
        this->locked_compressor = locked_compressor;
        this->recording = recording;
@@ -179,10 +180,10 @@ void FormatTools::create_objects(
 
        x = init_x;
        window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
-       x += 90;
+       x += format_title->get_w() + margin;
        window->add_subwindow(format_text = new BC_TextBox(x, y, 160, 1,
                File::formattostr(asset->format)));
-       x += format_text->get_w();
+       x += format_text->get_w() + margin;
 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
        window->add_subwindow(format_button = new FormatFormat(x, y, this));
        format_button->create_objects();
@@ -194,14 +195,13 @@ void FormatTools::create_objects(
        format_ffmpeg->create_objects();
        x = init_x;
        y += format_button->get_h() + 10;
-       if(do_audio)
-       {
-               window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT,  BC_WindowBase::get_resources()->audiovideo_color));
-               x += 80;
+       if( do_audio ) {
+               window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT,
+                       BC_WindowBase::get_resources()->audiovideo_color));
+               x += audio_title->get_w() + margin;
                window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
-               x += aparams_button->get_w() + 10;
-               if(prompt_audio)
-               {
+               x += aparams_button->get_w() + margin;
+               if(prompt_audio) {
                        window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
                }
                x = init_x;
@@ -225,30 +225,27 @@ void FormatTools::create_objects(
        }
 
 //printf("FormatTools::create_objects 7\n");
-       if(do_video)
-       {
-               if(horizontal_layout && do_audio){
+       if( do_video ) {
+               if( horizontal_layout && do_audio ) {
                        x += 370;
                        y = ylev;
                }
 
 //printf("FormatTools::create_objects 8\n");
-               window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT,  BC_WindowBase::get_resources()->audiovideo_color));
-               x += 80;
-               if(prompt_video_compression)
-               {
+               window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT,
+                       BC_WindowBase::get_resources()->audiovideo_color));
+               x += video_title->get_w() + margin;
+               if(prompt_video_compression) {
                        window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
-                       x += vparams_button->get_w() + 10;
+                       x += vparams_button->get_w() + margin;
                }
 
 //printf("FormatTools::create_objects 9\n");
-               if(prompt_video)
-               {
+               if(prompt_video) {
                        window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
                        y += video_switch->get_h();
                }
-               else
-               {
+               else {
                        y += vparams_button->get_h();
                }
 
index 54b1612f23fd368215e97cceacb0b388e7040620..28ff8c6f089e318ae5bb1010045105919fde02f2 100644 (file)
@@ -139,8 +139,7 @@ void KeyFrame::get_contents(BC_Hash *ptr, char **text, char **extra)
 }
 
 void KeyFrame::update_parameter(BC_Hash *params,
-       const char *text,
-       char *extra)
+       const char *text, const char *extra)
 {
        FileXML output;
        FileXML input;
index d21ae1253fe4fbae0eb84009b9624330f89d6277..29cdb3c5f8b30d7771c4e18969d3817f029a900f 100644 (file)
@@ -66,9 +66,7 @@ public:
 // extra text in a newly allocated string
        void get_contents(BC_Hash *ptr, char **text, char **extra);
 // Update a single parameter or the anonymous text depending on which argument is nonzero
-       void update_parameter(BC_Hash *params,
-               const char *text,
-               char *extra);
+       void update_parameter(BC_Hash *params, const char *text, const char *extra);
 
 private:
        char data[MESSAGESIZE];
index 197ceed992bfdf08d4c3b941084a92a8bbdf395a..8e6019f005b5924b9c0bd5b83acac55186b60124 100644 (file)
@@ -1,27 +1,29 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
+ * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
+ * 
  */
 
 #include "bchash.h"
 #include "bcsignals.h"
 #include "edl.h"
+#include "file.h"
+#include "filesystem.h"
 #include "keyframe.h"
 #include "keyframes.h"
 #include "keyframegui.h"
@@ -33,6 +35,8 @@
 #include "mwindow.h"
 #include "mwindowgui.h"
 #include "plugin.h"
+#include "preferences.h"
+#include "presets.h"
 #include "theme.h"
 #include "trackcanvas.h"
 #include "tracks.h"
@@ -46,50 +50,59 @@ KeyFrameThread::KeyFrameThread(MWindow *mwindow)
        keyframe = 0;
        keyframe_data = new ArrayList<BC_ListBoxItem*>[KEYFRAME_COLUMNS];
        plugin_title[0] = 0;
+       is_factory = 0;
+       preset_text[0] = 0;
        window_title[0] = 0;
-       column_titles[0] = (char*)_("Parameter");
-       column_titles[1] = (char*)_("Value");
+       column_titles[0] = (char*)"Parameter";
+       column_titles[1] = (char*)"Value";
        column_width[0] = 0;
        column_width[1] = 0;
+       presets_data = new ArrayList<BC_ListBoxItem*>;
+       presets_db = new PresetsDB;
 }
 
 KeyFrameThread::~KeyFrameThread()
 {
-       close_window();
-       for(int i = 0; i < KEYFRAME_COLUMNS; i++)
+       for( int i=0; i<KEYFRAME_COLUMNS; ++i )
                keyframe_data[i].remove_all_objects();
        delete [] keyframe_data;
+       presets_data->remove_all_objects();
+       delete presets_data;
+       is_factories.remove_all();
+       preset_titles.remove_all_objects();
 }
 
 
+#ifdef EDIT_KEYFRAME
 void KeyFrameThread::update_values()
 {
 // Get the current selection before deleting the tables
        int selection = -1;
-       for(int i = 0; i < keyframe_data[0].size(); i++) {
-               if(keyframe_data[0].get(i)->get_selected()) {
+       for( int i=0; i<keyframe_data[0].size(); ++i ) {
+               if( keyframe_data[0].get(i)->get_selected() ) {
                        selection = i;
                        break;
                }
        }
 
-       for(int i = 0; i < KEYFRAME_COLUMNS; i++)
+       for( int i=0; i<KEYFRAME_COLUMNS; ++i )
                keyframe_data[i].remove_all_objects();
 
 
 // Must lock main window to read keyframe
        mwindow->gui->lock_window("KeyFrameThread::update_values");
-       if(!plugin || !mwindow->edl->tracks->plugin_exists(plugin)) {
+       if( !plugin || !mwindow->edl->tracks->plugin_exists(plugin) ) {
                mwindow->gui->unlock_window();
                return;
        }
 
        KeyFrame *keyframe = 0;
-       if(this->keyframe && plugin->keyframe_exists(this->keyframe)) {
+       if( this->keyframe && plugin->keyframe_exists(this->keyframe) ) {
 // If user edited a specific keyframe, use it.
                keyframe = this->keyframe;
        }
-       else if(plugin->track) {
+       else
+       if( plugin->track ) {
 // Use currently highlighted keyframe
                keyframe = plugin->get_prev_keyframe(
                        plugin->track->to_units(
@@ -97,43 +110,62 @@ void KeyFrameThread::update_values()
                        PLAY_FORWARD);
        }
 
-       if(keyframe) {
+       if( keyframe ) {
                BC_Hash hash;
-               char *text = 0, *extra = 0;
-               keyframe->get_contents(&hash, &text, &extra);
-
-               for(int i = 0; i < hash.size(); i++)
-               {
+               char *text = 0, *data = 0;
+               keyframe->get_contents(&hash, &text, &data);
+               
+               for( int i=0; i<hash.size(); ++i ) {
                        keyframe_data[0].append(new BC_ListBoxItem(hash.get_key(i)));
                        keyframe_data[1].append(new BC_ListBoxItem(hash.get_value(i)));
                }
-               keyframe_data[0].append(new BC_ListBoxItem((char*)_("TEXT")));
-               keyframe_data[1].append(new BC_ListBoxItem(text ? text : ""));
-
+               keyframe_data[0].append(new BC_ListBoxItem((char*)"TEXT"));
+               keyframe_data[1].append(new BC_ListBoxItem(text));
+               keyframe_data[0].append(new BC_ListBoxItem((char*)"DATA"));
+               keyframe_data[1].append(new BC_ListBoxItem(data));
+               
                delete [] text;
-               delete [] extra;
+               delete [] data;
        }
 
        column_width[0] = mwindow->session->keyframedialog_column1;
        column_width[1] = mwindow->session->keyframedialog_column2;
-       if(selection >= 0 && selection < keyframe_data[0].size()) {
-               for(int i = 0; i < KEYFRAME_COLUMNS; i++)
+       if( selection >= 0 && selection < keyframe_data[0].size() ) {
+               for( int i=0; i<KEYFRAME_COLUMNS; ++i )
                        keyframe_data[i].get(selection)->set_selected(1);
        }
        mwindow->gui->unlock_window();
 }
+#endif
 
 
 void KeyFrameThread::start_window(Plugin *plugin, KeyFrame *keyframe)
 {
 
-       if(!BC_DialogThread::is_running()) {
-               if(!mwindow->edl->tracks->plugin_exists(plugin)) return;
+       if( !BC_DialogThread::is_running() ) {
+               if( !mwindow->edl->tracks->plugin_exists(plugin) ) return;
                this->keyframe = keyframe;
                this->plugin = plugin;
                plugin->calculate_title(plugin_title, 0);
-               sprintf(window_title, _(PROGRAM_NAME ": %s Keyframe"), plugin_title);
+               sprintf(window_title, PROGRAM_NAME ": %s Keyframe", plugin_title);
+
+// Load all the presets from disk
+               char path[BCTEXTLEN];
+               FileSystem fs;
+// system wide presets
+               sprintf(path, "%s/%s", File::get_cindat_path(), FACTORY_FILE);
+               fs.complete_path(path);
+               presets_db->load_from_file(path, 1, 1);
+// user presets
+               sprintf(path, "%s/%s", File::get_config_path(), PRESETS_FILE);
+               fs.complete_path(path);
+               presets_db->load_from_file(path, 0, 0);
+
+               calculate_preset_list();
+
+#ifdef EDIT_KEYFRAME
                update_values();
+#endif
                mwindow->gui->unlock_window();
                BC_DialogThread::start();
                mwindow->gui->lock_window("KeyFrameThread::start_window");
@@ -146,24 +178,32 @@ void KeyFrameThread::start_window(Plugin *plugin, KeyFrame *keyframe)
 BC_Window* KeyFrameThread::new_gui()
 {
        mwindow->gui->lock_window("KeyFrameThread::new_gui");
-
-       int x = mwindow->gui->get_abs_cursor_x(0) -
+       
+       int x = mwindow->gui->get_abs_cursor_x(0) - 
                mwindow->session->plugindialog_w / 2;
-       int y = mwindow->gui->get_abs_cursor_y(0) -
+       int y = mwindow->gui->get_abs_cursor_y(0) - 
                mwindow->session->plugindialog_h / 2;
 
-       KeyFrameWindow *window = new KeyFrameWindow(mwindow,
-               this, x, y, window_title);
-       window->create_objects();
+       KeyFrameWindow *window = new KeyFrameWindow(mwindow, 
+               this, 
+               x, 
+               y,
+               window_title);
 
+       window->create_objects();
+       
+       
        mwindow->gui->unlock_window();
+
        return window;
 }
 
 void KeyFrameThread::handle_done_event(int result)
 {
-       if( !result )
-               apply_value();
+// Apply the preset
+       if( !result ) {
+               apply_preset(preset_text, is_factory);
+       }
 }
 
 void KeyFrameThread::handle_close_event(int result)
@@ -172,85 +212,217 @@ void KeyFrameThread::handle_close_event(int result)
        keyframe = 0;
 }
 
+void KeyFrameThread::close_window()
+{
+       lock_window("KeyFrameThread::close_window");
+       if( get_gui() ) {
+               get_gui()->lock_window("KeyFrameThread::close_window");
+               get_gui()->set_done(1);
+               get_gui()->unlock_window();
+       }
+       unlock_window();
+}
+
+
+
+void KeyFrameThread::calculate_preset_list()
+{
+       presets_data->remove_all_objects();
+       is_factories.remove_all();
+       preset_titles.remove_all_objects();
+       int total_presets = presets_db->get_total_presets(plugin_title, 0);
+
+// sort the list
+       presets_db->sort(plugin_title);
+       
+       for( int i=0; i<total_presets; ++i ) {
+               char text[BCTEXTLEN];
+               char *orig_title = presets_db->get_preset_title( plugin_title, i);
+               if( !orig_title ) continue;
+               int is_factory = presets_db->get_is_factory(plugin_title, i);
+               sprintf(text, "%s%s", is_factory ? "*" : "", orig_title);
+               presets_data->append(new BC_ListBoxItem(text));
+
+               preset_titles.append(strdup(orig_title));
+               is_factories.append(is_factory);
+       }
+}
+
 
 void KeyFrameThread::update_gui(int update_value_text)
 {
-       if(BC_DialogThread::is_running()) {
+#ifdef EDIT_KEYFRAME
+       if( BC_DialogThread::is_running() ) {
                mwindow->gui->lock_window("KeyFrameThread::update_gui");
                update_values();
                mwindow->gui->unlock_window();
 
                lock_window("KeyFrameThread::update_gui");
                KeyFrameWindow *window = (KeyFrameWindow*)get_gui();
-               if(window) {
+               if( window ) {
                        window->lock_window("KeyFrameThread::update_gui");
                        window->keyframe_list->update(keyframe_data,
-                               (const char **)column_titles,
+                               column_titles,
                                column_width,
                                KEYFRAME_COLUMNS,
                                window->keyframe_list->get_xposition(),
                                window->keyframe_list->get_yposition(),
                                window->keyframe_list->get_highlighted_item());
-                       if( update_value_text ) {
-                               int selection_number = window->keyframe_list->get_selection_number(0, 0);
-                               if( selection_number >= 0 && selection_number < keyframe_data[1].size()) {
-                                       char *edit_value = keyframe_data[1].get(selection_number)->get_text();
-                                       window->value_text->update(edit_value);
-                               }
+                       if( update_value_text &&
+                               window->keyframe_list->get_selection_number(0, 0) >= 0 &&
+                               window->keyframe_list->get_selection_number(0, 0) < keyframe_data[1].size() ) {
+                               window->value_text->update(
+                                       keyframe_data[1].get(window->keyframe_list->get_selection_number(0, 0))->get_text());
                        }
                        window->unlock_window();
                }
                unlock_window();
        }
+#endif
+}
+
+void KeyFrameThread::save_preset(const char *title, int is_factory)
+{
+       get_gui()->unlock_window();
+       mwindow->gui->lock_window("KeyFrameThread::save_preset");
+       
+// Test EDL for plugin existence
+       if( !mwindow->edl->tracks->plugin_exists(plugin) ) {
+               mwindow->gui->unlock_window();
+               get_gui()->lock_window("KeyFrameThread::save_preset 2");
+               return;
+       }
+
+// Get current plugin keyframe
+       EDL *edl = mwindow->edl;
+       Track *track = plugin->track;
+       KeyFrame *keyframe = plugin->get_prev_keyframe(
+                       track->to_units(edl->local_session->get_selectionstart(1), 0), 
+                       PLAY_FORWARD);
+
+// Send to database
+       presets_db->save_preset(plugin_title, title, keyframe->get_data());
+
+       mwindow->gui->unlock_window();
+       get_gui()->lock_window("KeyFrameThread::save_preset 2");
+
+// Update list
+       calculate_preset_list();
+       ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data,
+               0, 0, 1);
+}
+
+void KeyFrameThread::delete_preset(const char *title, int is_factory)
+{
+       get_gui()->unlock_window();
+       mwindow->gui->lock_window("KeyFrameThread::save_preset");
+       
+// Test EDL for plugin existence
+       if( !mwindow->edl->tracks->plugin_exists(plugin) ) {
+               mwindow->gui->unlock_window();
+               get_gui()->lock_window("KeyFrameThread::delete_preset 1");
+               return;
+       }
+
+       presets_db->delete_preset(plugin_title, title, is_factory);
+       
+       mwindow->gui->unlock_window();
+       get_gui()->lock_window("KeyFrameThread::delete_preset 2");
+
+// Update list
+       calculate_preset_list();
+       ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data,
+               0, 0, 1);
 }
 
+
+void KeyFrameThread::apply_preset(const char *title, int is_factory)
+{
+       if( presets_db->preset_exists(plugin_title, title, is_factory) ) {
+               get_gui()->unlock_window();
+               mwindow->gui->lock_window("KeyFrameThread::apply_preset");
+
+// Test EDL for plugin existence
+               if( !mwindow->edl->tracks->plugin_exists(plugin) ) {
+                       mwindow->gui->unlock_window();
+                       get_gui()->lock_window("KeyFrameThread::apply_preset 1");
+                       return;
+               }
+
+               mwindow->undo->update_undo_before();
+
+#ifdef USE_KEYFRAME_SPANNING
+               KeyFrame keyframe;
+               presets_db->load_preset(plugin_title, title, &keyframe, is_factory);
+               plugin->keyframes->update_parameter(&keyframe);
+#else
+               KeyFrame *keyframe = plugin->get_keyframe();
+               presets_db->load_preset(plugin_title, title, keyframe, is_factory);
+#endif
+               mwindow->save_backup();
+               mwindow->undo->update_undo_after(_("apply preset"), LOAD_AUTOMATION); 
+
+               mwindow->update_plugin_guis(0);
+               mwindow->gui->draw_overlays(1);
+               mwindow->sync_parameters(CHANGE_PARAMS);
+
+
+               update_gui(1);
+               mwindow->gui->unlock_window();
+               get_gui()->lock_window("KeyFrameThread::apply_preset");
+       }
+}
+
+#ifdef EDIT_KEYFRAME
 void KeyFrameThread::apply_value()
 {
-       const char *text = 0;
-       BC_Hash hash;
+       const char *text = 0, *data = 0;
+       BC_Hash *hash = 0;
        KeyFrameWindow *window = (KeyFrameWindow*)get_gui();
        int selection = window->keyframe_list->get_selection_number(0, 0);
 //printf("KeyFrameThread::apply_value %d %d\n", __LINE__, selection);
-       if(selection < 0) return;
-
-       if(selection == keyframe_data[0].size() - 1)
+       if( selection < 0 ) return;
+       
+       if( selection == keyframe_data[0].size() - 2 )
                text = window->value_text->get_text();
+       else if( selection == keyframe_data[0].size() - 1 )
+               data = window->value_text->get_text();
        else {
-               char *key = keyframe_data[0].get(selection)->get_text();
+               const char *key = keyframe_data[0].get(selection)->get_text();
                const char *value = window->value_text->get_text();
-               hash.update(key, value);
+               hash = new BC_Hash();
+               hash->update(key, value);
        }
 
        get_gui()->unlock_window();
        mwindow->gui->lock_window("KeyFrameThread::apply_value");
-       if(plugin && mwindow->edl->tracks->plugin_exists(plugin)) {
+       if( plugin && mwindow->edl->tracks->plugin_exists(plugin) ) {
                mwindow->undo->update_undo_before();
-               if(mwindow->session->keyframedialog_all) {
+               if( mwindow->session->keyframedialog_all ) {
 // Search for all keyframes in selection but don't create a new one.
                        Track *track = plugin->track;
                        int64_t start = track->to_units(mwindow->edl->local_session->get_selectionstart(0), 0);
                        int64_t end = track->to_units(mwindow->edl->local_session->get_selectionend(0), 0);
                        int got_it = 0;
-                       for(KeyFrame *current = (KeyFrame*)plugin->keyframes->last;
-                               current;
-                               current = (KeyFrame*)PREVIOUS) {
+                       KeyFrame *current = (KeyFrame*)plugin->keyframes->last;
+                       for( ; current; current=(KeyFrame*)PREVIOUS ) {
                                got_it = 1;
-                               if(current && current->position < end) {
-                                       current->update_parameter(&hash, text, 0);
+                               if( current && current->position < end ) {
+                                   current->update_parameter(hash, text, data);
 // Stop at beginning of range
-                                       if(current->position <= start) break;
+                                       if( current->position <= start ) break;
                                }
                        }
 
-                       if(!got_it) {
-                               KeyFrame* keyframe = (KeyFrame*)plugin->keyframes->default_auto;
-                               keyframe->update_parameter(&hash, text, 0);
+                       if( !got_it ) {
+                               current = (KeyFrame*)plugin->keyframes->default_auto;
+                               current->update_parameter(hash, text, data);
                        }
                }
                else {
 // Create new keyframe if enabled
                        KeyFrame *keyframe = plugin->get_keyframe();
-                       keyframe->update_parameter(&hash, text, 0);
+                       keyframe->update_parameter(hash, text, data);
                }
        }
        else {
@@ -258,28 +430,37 @@ printf("KeyFrameThread::apply_value %d: plugin doesn't exist\n", __LINE__);
        }
 
        mwindow->save_backup();
-       mwindow->undo->update_undo_after(_("edit keyframe"), LOAD_AUTOMATION);
+       mwindow->undo->update_undo_after(_("edit keyframe"), LOAD_AUTOMATION); 
 
        mwindow->update_plugin_guis(0);
        mwindow->gui->draw_overlays(1);
        mwindow->sync_parameters(CHANGE_PARAMS);
-
-
-
        mwindow->gui->unlock_window();
 
        update_gui(0);
 
        get_gui()->lock_window("KeyFrameThread::apply_value");
+       delete hash;
 }
+#endif
+
 
 
 KeyFrameWindow::KeyFrameWindow(MWindow *mwindow,
-       KeyFrameThread *thread, int x, int y, char *title_string)
- : BC_Window(title_string, x, y,
-       mwindow->session->keyframedialog_w,
-       mwindow->session->keyframedialog_h,
-       320, 240, 1, 0, 1)
+       KeyFrameThread *thread,
+       int x,
+       int y,
+       char *title_string)
+ : BC_Window(title_string, 
+       x,
+       y,
+       mwindow->session->keyframedialog_w, 
+       mwindow->session->keyframedialog_h, 
+       320, 
+       240,
+       1,
+       0,
+       1)
 {
        this->mwindow = mwindow;
        this->thread = thread;
@@ -294,29 +475,104 @@ void KeyFrameWindow::create_objects()
        thread->column_width[1] = mwindow->session->keyframedialog_column2;
        lock_window("KeyFrameWindow::create_objects");
 
+#ifdef EDIT_KEYFRAME
+
+
        add_subwindow(title1 = new BC_Title(theme->keyframe_list_x,
-               theme->keyframe_list_y -
-                       BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) -
+               theme->keyframe_list_y - 
+                       BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) - 
                        theme->widget_border,
-               _("Keyframe parameters:"), LARGEFONT));
+               _("Keyframe parameters:"),
+               LARGEFONT));
        add_subwindow(keyframe_list = new KeyFrameList(thread,
-               this, theme->keyframe_list_x, theme->keyframe_list_y,
-               theme->keyframe_list_w, theme->keyframe_list_h));
+               this,
+               theme->keyframe_list_x,
+               theme->keyframe_list_y,
+               theme->keyframe_list_w, 
+               theme->keyframe_list_h));
+//     add_subwindow(title2 = new BC_Title(theme->keyframe_text_x,
+//             theme->keyframe_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border,
+//             _("Global Text:")));
+//     add_subwindow(keyframe_text = new KeyFrameText(thread,
+//             this,
+//             theme->keyframe_text_x,
+//             theme->keyframe_text_y,
+//             theme->keyframe_text_w));
        add_subwindow(title3 = new BC_Title(theme->keyframe_value_x,
                theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border,
                _("Edit value:")));
        add_subwindow(value_text = new KeyFrameValue(thread,
-               this, theme->keyframe_value_x, theme->keyframe_value_y, theme->keyframe_value_w));
+               this,
+               theme->keyframe_value_x,
+               theme->keyframe_value_y,
+               theme->keyframe_value_w));
        add_subwindow(all_toggle = new KeyFrameAll(thread,
-               this, theme->keyframe_all_x, theme->keyframe_all_y));
+               this, 
+               theme->keyframe_all_x,
+               theme->keyframe_all_y));
+
+#endif
+
 
-       add_subwindow(new KeyFrameParamsOK(thread, this));
+
+       add_subwindow(title4 = new BC_Title(theme->presets_list_x,
+               theme->presets_list_y - 
+                       BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) - 
+                       theme->widget_border,
+               _("Presets:"),
+               LARGEFONT));
+       add_subwindow(preset_list = new KeyFramePresetsList(thread,
+               this,
+               theme->presets_list_x,
+               theme->presets_list_y,
+               theme->presets_list_w, 
+               theme->presets_list_h));
+       add_subwindow(title5 = new BC_Title(theme->presets_text_x,
+               theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border,
+               _("Preset title:")));
+       add_subwindow(preset_text = new KeyFramePresetsText(thread,
+               this,
+               theme->presets_text_x,
+               theme->presets_text_y,
+               theme->presets_text_w));
+       add_subwindow(delete_preset = new KeyFramePresetsDelete(thread,
+               this,
+               theme->presets_delete_x,
+               theme->presets_delete_y));
+       add_subwindow(save_preset = new KeyFramePresetsSave(thread,
+               this,
+               theme->presets_save_x,
+               theme->presets_save_y));
+       add_subwindow(apply_preset = new KeyFramePresetsApply(thread,
+               this,
+               theme->presets_apply_x,
+               theme->presets_apply_y));
+
+
+
+
+       add_subwindow(new KeyFramePresetsOK(thread, this));
        add_subwindow(new BC_CancelButton(this));
 
        show_window();
        unlock_window();
 }
 
+// called when going in & out of a factory preset
+void KeyFrameWindow::update_editing()
+{
+       if( thread->is_factory ) {
+               delete_preset->disable();
+               save_preset->disable();
+       }
+       else {
+               delete_preset->enable();
+               save_preset->enable();
+       }
+}
+
+
+
 int KeyFrameWindow::resize_event(int w, int h)
 {
        Theme *theme = mwindow->theme;
@@ -324,24 +580,74 @@ int KeyFrameWindow::resize_event(int w, int h)
        mwindow->session->keyframedialog_h = h;
        theme->get_keyframedialog_sizes(this);
 
+#ifdef EDIT_KEYFRAME
+
        title1->reposition_window(theme->keyframe_list_x,
                theme->keyframe_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
+//     title2->reposition_window(theme->keyframe_text_x,
+//             theme->keyframe_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
        title3->reposition_window(theme->keyframe_value_x,
                theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
-       keyframe_list->reposition_window(theme->keyframe_list_x, theme->keyframe_list_y,
-               theme->keyframe_list_w, theme->keyframe_list_h);
-       value_text->reposition_window(theme->keyframe_value_x, theme->keyframe_value_y,
+       keyframe_list->reposition_window(theme->keyframe_list_x,
+               theme->keyframe_list_y,
+               theme->keyframe_list_w, 
+               theme->keyframe_list_h);
+//     text->reposition_window(theme->keyframe_text_x,
+//             theme->keyframe_text_y,
+//             theme->keyframe_text_w);
+       value_text->reposition_window(theme->keyframe_value_x,
+               theme->keyframe_value_y,
                theme->keyframe_value_w);
-       all_toggle->reposition_window(theme->keyframe_all_x, theme->keyframe_all_y);
+       all_toggle->reposition_window(theme->keyframe_all_x,
+               theme->keyframe_all_y);
+
+#endif // EDIT_KEYFRAME
+
+
+
+
+       title4->reposition_window(theme->presets_list_x,
+               theme->presets_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
+       title5->reposition_window(theme->presets_text_x,
+               theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
+       preset_list->reposition_window(theme->presets_list_x,
+               theme->presets_list_y,
+               theme->presets_list_w, 
+               theme->presets_list_h);
+       preset_text->reposition_window(theme->presets_text_x,
+               theme->presets_text_y,
+               theme->presets_text_w);
+       delete_preset->reposition_window(theme->presets_delete_x,
+               theme->presets_delete_y);
+       save_preset->reposition_window(theme->presets_save_x,
+               theme->presets_save_y);
+       apply_preset->reposition_window(theme->presets_apply_x,
+               theme->presets_apply_y);
 
        return 0;
 }
 
+
+
+
+#ifdef EDIT_KEYFRAME
+
+
 KeyFrameList::KeyFrameList(KeyFrameThread *thread,
-       KeyFrameWindow *window, int x, int y, int w, int h)
- : BC_ListBox(x, y, w, h, LISTBOX_TEXT,
-       thread->keyframe_data, (const char **)thread->column_titles,
-       thread->column_width, KEYFRAME_COLUMNS)
+       KeyFrameWindow *window,
+       int x,
+       int y,
+       int w, 
+       int h)
+ : BC_ListBox(x, 
+               y, 
+               w, 
+               h,
+               LISTBOX_TEXT,
+               thread->keyframe_data,
+               thread->column_titles,
+               thread->column_width,
+               KEYFRAME_COLUMNS)
 {
        this->thread = thread;
        this->window = window;
@@ -368,9 +674,40 @@ int KeyFrameList::column_resize_event()
 }
 
 
+
+
+// KeyFrameText::KeyFrameText(KeyFrameThread *thread,
+//     KeyFrameWindow *window,
+//     int x,
+//     int y,
+//     int w)
+//  : BC_TextBox(x, 
+//     y, 
+//     w, 
+//     1, 
+//     "")
+// {
+//     this->thread = thread;
+//     this->window = window;
+// }
+// 
+// int KeyFrameText::handle_event()
+// {
+//     return 0;
+// }
+
+
+
 KeyFrameValue::KeyFrameValue(KeyFrameThread *thread,
-       KeyFrameWindow *window, int x, int y, int w)
- : BC_TextBox(x, y, w, 1, "")
+       KeyFrameWindow *window,
+       int x,
+       int y,
+       int w)
+ : BC_TextBox(x, 
+       y, 
+       w, 
+       1, 
+       (char*)"")
 {
        this->thread = thread;
        this->window = window;
@@ -378,14 +715,21 @@ KeyFrameValue::KeyFrameValue(KeyFrameThread *thread,
 
 int KeyFrameValue::handle_event()
 {
-       thread->update_values();
+       thread->apply_value();
        return 0;
 }
 
 
+
+
+
 KeyFrameAll::KeyFrameAll(KeyFrameThread *thread,
-       KeyFrameWindow *window, int x, int y)
- : BC_CheckBox(x, y, thread->mwindow->session->keyframedialog_all,
+       KeyFrameWindow *window,
+       int x,
+       int y)
+ : BC_CheckBox(x, 
+       y, 
+       thread->mwindow->session->keyframedialog_all, 
        _("Apply to all selected keyframes"))
 {
        this->thread = thread;
@@ -398,18 +742,160 @@ int KeyFrameAll::handle_event()
        return 1;
 }
 
-KeyFrameParamsOK::KeyFrameParamsOK(KeyFrameThread *thread, KeyFrameWindow *window)
+#endif // EDIT_KEYFRAME
+
+
+
+
+
+
+
+
+
+
+KeyFramePresetsList::KeyFramePresetsList(KeyFrameThread *thread,
+       KeyFrameWindow *window,
+       int x,
+       int y,
+       int w, 
+       int h)
+ : BC_ListBox(x, 
+               y, 
+               w, 
+               h,
+               LISTBOX_TEXT,
+               thread->presets_data)
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int KeyFramePresetsList::selection_changed()
+{
+       int number = get_selection_number(0, 0);
+       if( number >= 0 ) {
+               strcpy(thread->preset_text, thread->preset_titles.get(number));
+               thread->is_factory = thread->is_factories.get(number);
+// show title without factory symbol in the textbox
+               window->preset_text->update(
+                       thread->presets_data->get(number)->get_text());
+               window->update_editing();
+       }
+       
+       return 0;
+}
+
+int KeyFramePresetsList::handle_event()
+{
+       thread->apply_preset(thread->preset_text, thread->is_factory);
+       window->set_done(0);
+       return 0;
+}
+
+
+KeyFramePresetsText::KeyFramePresetsText(KeyFrameThread *thread,
+       KeyFrameWindow *window, int x, int y, int w)
+ : BC_TextBox(x, y, w, 1, thread->preset_text)
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+// user entered a title
+int KeyFramePresetsText::handle_event()
+{
+       strcpy(thread->preset_text, get_text());
+// once changed, it's now not a factory preset
+       thread->is_factory = 0;
+       window->update_editing();
+       return 0;
+}
+
+
+KeyFramePresetsDelete::KeyFramePresetsDelete(KeyFrameThread *thread,
+       KeyFrameWindow *window,
+       int x,
+       int y)
+ : BC_GenericButton(x, y, _("Delete"))
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int KeyFramePresetsDelete::handle_event()
+{
+       if( !thread->is_factory ) {
+               thread->delete_preset(thread->preset_text, thread->is_factory);
+       }
+       return 1;
+}
+
+
+KeyFramePresetsSave::KeyFramePresetsSave(KeyFrameThread *thread,
+       KeyFrameWindow *window,
+       int x,
+       int y)
+: BC_GenericButton(x, y, _("Save"))
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int KeyFramePresetsSave::handle_event()
+{
+       if( !thread->is_factory ) {
+               thread->save_preset(thread->preset_text, thread->is_factory);
+       }
+       return 1;
+}
+
+
+
+
+
+
+
+
+KeyFramePresetsApply::KeyFramePresetsApply(KeyFrameThread *thread,
+       KeyFrameWindow *window,
+       int x,
+       int y)
+ : BC_GenericButton(x, y, _("Apply"))
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int KeyFramePresetsApply::handle_event()
+{
+       thread->apply_preset(thread->preset_text, thread->is_factory);
+       return 1;
+}
+
+
+KeyFramePresetsOK::KeyFramePresetsOK(KeyFrameThread *thread,
+       KeyFrameWindow *window)
  : BC_OKButton(window)
 {
        this->thread = thread;
        this->window = window;
 }
 
-int KeyFrameParamsOK::keypress_event()
+int KeyFramePresetsOK::keypress_event()
 {
        if( get_keypress() == RETURN ) {
-               thread->apply_value();
-               return 1;
+// Apply the preset
+               if( thread->presets_db->preset_exists(thread->plugin_title, 
+                       thread->preset_text, thread->is_factory) ) {
+                       window->set_done(0);
+                       return 1;
+               }
+               else {
+                       if( !thread->is_factory ) {
+                               thread->save_preset(thread->preset_text, thread->is_factory);
+                               return 1;
+                       }
+               }
        }
        return 0;
 }
index 9f98c06838cdf04afda36df3adb74a6e54f83413..c6cdb85c0c4e4660cce7a8bc8c56335a17616119 100644 (file)
@@ -1,22 +1,22 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
+ * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
+ * 
  */
 
 #ifndef KEYFRAMEGUI_H
 
 #include "bcdialog.h"
 #include "guicast.h"
+#include "presets.inc"
 
 class KeyFrameWindow;
 
 
+
+
 #define KEYFRAME_COLUMNS 2
 // Enable editing of detailed keyframe parameters.
+#define EDIT_KEYFRAME
+
 class KeyFrameThread : public BC_DialogThread
 {
 public:
@@ -44,8 +49,13 @@ public:
        void handle_close_event(int result);
        void update_values();
        void save_value(char *value);
+       void save_preset(const char *title, int is_factory);
+       void delete_preset(const char *title, int is_factory);
+       void apply_preset(const char *title, int is_factory);
        void apply_value();
+       void calculate_preset_list();
        void update_gui(int update_value_text = 1);
+       void close_window();
 
        ArrayList<BC_ListBoxItem*> *keyframe_data;
        Plugin *plugin;
@@ -53,38 +63,134 @@ public:
        MWindow *mwindow;
        char window_title[BCTEXTLEN];
        char plugin_title[BCTEXTLEN];
-       char *column_titles[KEYFRAME_COLUMNS];
+
+// the currently selected preset is a factory preset
+       int is_factory;
+// title of the currently selected preset from the DB
+       char preset_text[BCTEXTLEN];
+       
+       const char *column_titles[KEYFRAME_COLUMNS];
        int column_width[KEYFRAME_COLUMNS];
+// list of preset text to display
+       ArrayList<BC_ListBoxItem*> *presets_data;
+// flag for each preset shown
+       ArrayList<int> is_factories;
+// title of each preset shown
+       ArrayList<char*> preset_titles;
+       PresetsDB *presets_db;
 };
 
+#ifdef EDIT_KEYFRAME
+
+
 class KeyFrameList : public BC_ListBox
 {
 public:
        KeyFrameList(KeyFrameThread *thread,
-               KeyFrameWindow *window, int x, int y, int w, int h);
+               KeyFrameWindow *window,
+               int x,
+               int y,
+               int w, 
+               int h);
        int selection_changed();
        int handle_event();
        int column_resize_event();
        KeyFrameThread *thread;
        KeyFrameWindow *window;
 };
+#endif
 
-class KeyFrameParamList : public BC_ListBox
+class KeyFramePresetsList : public BC_ListBox
 {
 public:
-       KeyFrameParamList(KeyFrameThread *thread,
-               KeyFrameWindow *window, int x, int y, int w, int h);
+       KeyFramePresetsList(KeyFrameThread *thread,
+               KeyFrameWindow *window,
+               int x,
+               int y,
+               int w, 
+               int h);
        int selection_changed();
        int handle_event();
        KeyFrameThread *thread;
        KeyFrameWindow *window;
 };
 
+class KeyFramePresetsText : public BC_TextBox
+{
+public:
+       KeyFramePresetsText(KeyFrameThread *thread,
+               KeyFrameWindow *window,
+               int x,
+               int y,
+               int w);
+       int handle_event();
+       KeyFrameThread *thread;
+       KeyFrameWindow *window;
+};
+
+
+class KeyFramePresetsDelete : public BC_GenericButton
+{
+public:
+       KeyFramePresetsDelete(KeyFrameThread *thread,
+               KeyFrameWindow *window,
+               int x,
+               int y);
+       int handle_event();
+       KeyFrameThread *thread;
+       KeyFrameWindow *window;
+};
+
+class KeyFramePresetsSave : public BC_GenericButton
+{
+public:
+       KeyFramePresetsSave(KeyFrameThread *thread,
+               KeyFrameWindow *window,
+               int x,
+               int y);
+       int handle_event();
+       KeyFrameThread *thread;
+       KeyFrameWindow *window;
+};
+
+class KeyFramePresetsApply : public BC_GenericButton
+{
+public:
+       KeyFramePresetsApply(KeyFrameThread *thread,
+               KeyFrameWindow *window,
+               int x,
+               int y);
+       int handle_event();
+       KeyFrameThread *thread;
+       KeyFrameWindow *window;
+};
+
+/*
+ * class KeyFrameText : public BC_TextBox
+ * {
+ * public:
+ *     KeyFrameText(KeyFrameThread *thread,
+ *             KeyFrameWindow *window,
+ *             int x,
+ *             int y,
+ *             int w);
+ *     int handle_event();
+ *     KeyFrameThread *thread;
+ *     KeyFrameWindow *window;
+ * };
+ */
+
+#ifdef EDIT_KEYFRAME
+
+
 class KeyFrameValue : public BC_TextBox
 {
 public:
        KeyFrameValue(KeyFrameThread *thread,
-               KeyFrameWindow *window, int x, int y, int w);
+               KeyFrameWindow *window,
+               int x,
+               int y,
+               int w);
        int handle_event();
        KeyFrameThread *thread;
        KeyFrameWindow *window;
@@ -94,29 +200,42 @@ class KeyFrameAll : public BC_CheckBox
 {
 public:
        KeyFrameAll(KeyFrameThread *thread,
-               KeyFrameWindow *window, int x, int y);
+               KeyFrameWindow *window,
+               int x,
+               int y);
        int handle_event();
        KeyFrameThread *thread;
        KeyFrameWindow *window;
 };
 
-class KeyFrameParamsOK : public BC_OKButton
+#endif
+
+
+class KeyFramePresetsOK : public BC_OKButton
 {
 public:
-       KeyFrameParamsOK(KeyFrameThread *thread,
+       KeyFramePresetsOK(KeyFrameThread *thread,
                KeyFrameWindow *window);
        int keypress_event();
        KeyFrameThread *thread;
        KeyFrameWindow *window;
 };
 
+
+
 class KeyFrameWindow : public BC_Window
 {
 public:
        KeyFrameWindow(MWindow *mwindow,
-               KeyFrameThread *thread, int x, int y, char *title);
+               KeyFrameThread *thread,
+               int x,
+               int y,
+               char *title);
        void create_objects();
        int resize_event(int w, int h);
+       void update_editing();
+
+#ifdef EDIT_KEYFRAME
 
 // List of parameters, values, & whether the parameter is defined by the current keyframe.
        KeyFrameList *keyframe_list;
@@ -125,10 +244,34 @@ public:
 // Value text of the current parameter
        KeyFrameValue *value_text;
        KeyFrameAll *all_toggle;
-       BC_Title *title1, *title3;
+#endif
+       
+       KeyFramePresetsList *preset_list;
+       KeyFramePresetsText *preset_text;
+       KeyFramePresetsDelete *delete_preset;
+       KeyFramePresetsSave *save_preset;
+       KeyFramePresetsApply *apply_preset;
+
+#ifdef EDIT_KEYFRAME
+
+       BC_Title *title1;
+//     BC_Title *title2;
+       BC_Title *title3;
+#endif
+
+       BC_Title *title4;
+       BC_Title *title5;
 
        MWindow *mwindow;
        KeyFrameThread *thread;
 };
 
+
+
+
 #endif
+
+
+
+
+
index 5d8249fe780d97e5eec9075b384265391f3f3561..0008bcd30a1d7051253903cdc2e9de84692e3132 100644 (file)
@@ -104,6 +104,8 @@ LocalSession::LocalSession(EDL *edl)
        floatauto_type = FloatAuto::SMOOTH;
 
        red = green = blue = 0;
+       red_max = green_max = blue_max = 0;
+       use_max = 0;
 }
 
 LocalSession::~LocalSession()
@@ -138,14 +140,17 @@ void LocalSession::copy_from(LocalSession *that)
        preview_end = that->preview_end;
        red = that->red;
        green = that->green;
+       blue = that->blue;
+       red_max = that->red_max;
+       green_max = that->green_max;
+       blue_max = that->blue_max;
+       use_max = that->use_max;
 
        for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
                automation_mins[i] = that->automation_mins[i];
                automation_maxs[i] = that->automation_maxs[i];
        }
        floatauto_type = that->floatauto_type;
-
-       blue = that->blue;
 }
 
 void LocalSession::save_xml(FileXML *file, double start)
@@ -192,6 +197,10 @@ void LocalSession::save_xml(FileXML *file, double start)
        file->tag.set_property("RED", red);
        file->tag.set_property("GREEN", green);
        file->tag.set_property("BLUE", blue);
+       file->tag.set_property("RED_MAX", red_max);
+       file->tag.set_property("GREEN_MAX", green_max);
+       file->tag.set_property("BLUE_MAX", blue_max);
+       file->tag.set_property("USE_MAX", use_max);
 
        for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
                if (!Automation::autogrouptypes_fixedrange[i]) {
@@ -217,6 +226,9 @@ void LocalSession::synchronize_params(LocalSession *that)
        red = that->red;
        green = that->green;
        blue = that->blue;
+       red_max = that->red_max;
+       green_max = that->green_max;
+       blue_max = that->blue_max;
 }
 
 
@@ -261,7 +273,10 @@ void LocalSession::load_xml(FileXML *file, unsigned long load_flags)
                red = file->tag.get_property("RED", red);
                green = file->tag.get_property("GREEN", green);
                blue = file->tag.get_property("BLUE", blue);
-
+               red_max = file->tag.get_property("RED_MAX", red_max);
+               green_max = file->tag.get_property("GREEN_MAX", green_max);
+               blue_max = file->tag.get_property("BLUE_MAX", blue_max);
+               use_max = file->tag.get_property("USE_MAX", use_max);
 
                for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
                        if (!Automation::autogrouptypes_fixedrange[i]) {
@@ -310,6 +325,10 @@ int LocalSession::load_defaults(BC_Hash *defaults)
        red = defaults->get("RED", 0.0);
        green = defaults->get("GREEN", 0.0);
        blue = defaults->get("BLUE", 0.0);
+       red_max = defaults->get("RED_MAX", 0.0);
+       green_max = defaults->get("GREEN_MAX", 0.0);
+       blue_max = defaults->get("BLUE_MAX", 0.0);
+       use_max = defaults->get("USE_MAX", 0);
 
        for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
                if (!Automation::autogrouptypes_fixedrange[i]) {
@@ -340,6 +359,10 @@ int LocalSession::save_defaults(BC_Hash *defaults)
        defaults->update("RED", red);
        defaults->update("GREEN", green);
        defaults->update("BLUE", blue);
+       defaults->update("RED_MAX", red_max);
+       defaults->update("GREEN_MAX", green_max);
+       defaults->update("BLUE_MAX", blue_max);
+       defaults->update("USE_MAX", use_max);
 
        for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
                if (!Automation::autogrouptypes_fixedrange[i]) {
index 547fcb8afa27be359d01c91086cc7fb2874f45d2..e2ee664e2ec40beb4a0935f18f6cc739ce21faa3 100644 (file)
@@ -109,6 +109,8 @@ public:
 
 // Eye dropper
        float red, green, blue;
+       float red_max, green_max, blue_max;
+       int use_max;
 private:
 // The reason why selection ranges and inpoints have to be separate:
 // The selection position has to change to set new in points.
index f03ac9d0aa7a87f1b78c25c1be297f91d51f120d..3fbbc5761ba228c3662b29025d4d0747f9c459dd 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 1997-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,8 @@
 #include "theme.h"
 
 MainClock::MainClock(MWindow *mwindow, int x, int y, int w)
- : BC_Title(x, y, "", MEDIUM_7SEGMENT, BLACK, 0, w)
+ : BC_Title(x, y, "", CLOCKFONT, //MEDIUM_7SEGMENT,
+       mwindow->theme->clock_fg_color, 0, w)
 {
        this->mwindow = mwindow;
        position_offset = 0;
index bc089e7f5848f5155449856233d13d722f942e69..a0a661fdb930e9aed9692bf4a9875d624409cb6a 100644 (file)
@@ -516,7 +516,7 @@ void MenuEffectThread::run()
 
                mwindow->undo->update_undo_before("", 0);
                if(load_mode == LOADMODE_PASTE)
-                       mwindow->clear(0);
+                       mwindow->clear(0, 1);
 
                mwindow->load_assets(&assets, -1, load_mode, 0, 0,
                        mwindow->edl->session->labels_follow_edits,
index e700e71f675f718987e635051a5de43599091225..a7bd7e3d507f38f2df50479d3045ebee65fa6a71 100644 (file)
@@ -316,7 +316,7 @@ public:
 // Clears active region in EDL.
 // If clear_handle, edit boundaries are cleared if the range is 0.
 // Called by paste, record, menueffects, render, and CWindow drop.
-       void clear(int clear_handle);
+       void clear(int clear_handle, int deglitch);
        void clear_labels();
        int clear_labels(double start, double end);
        void concatenate_tracks();
index 48d2648479ae85f6e3e0146f9ba0086009adc337..366236ffc28936958dd75402faa5d2eb52e35b66 100644 (file)
 #define DEFAULT_THEME "UnFlat"
 #define DEFAULT_PICON "cinfinity"
 #define CONFIG_FILE "Cinelerra_rc"
+// user presets
 #define PRESETS_FILE "Cinelerra_presets"
+// factory presets
+#define FACTORY_FILE "Cinelerra_factory"
 #define PICTURE_FILE "Cinelerra_picture"
 #define PLUGIN_FILE "Cinelerra_plugins"
 #define LADSPA_FILE "ladspa_plugins."
index 0e4121b121ae18e17b414cedc264912507ac5cc0..4e1c5c7415d76314da93fb85d398683a9327046f 100644 (file)
@@ -301,7 +301,7 @@ void MWindow::asset_to_rate()
 void MWindow::clear_entry()
 {
        undo->update_undo_before();
-       clear(1);
+       clear(1, 1);
 
        edl->optimize();
        save_backup();
@@ -315,7 +315,7 @@ void MWindow::clear_entry()
                send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
 }
 
-void MWindow::clear(int clear_handle)
+void MWindow::clear(int clear_handle, int deglitch)
 {
        double start = edl->local_session->get_selectionstart();
        double end = edl->local_session->get_selectionend();
@@ -326,6 +326,12 @@ void MWindow::clear(int clear_handle)
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits);
        }
+       
+// always needed by paste operations
+       if(deglitch)
+       {
+               edl->deglitch(start);
+       }
 }
 
 void MWindow::set_automation_mode(int mode)
@@ -525,6 +531,7 @@ void MWindow::cut(double start, double end, double new_position)
                edl->session->labels_follow_edits,
                edl->session->plugins_follow_edits,
                edl->session->autos_follow_edits);
+       edl->deglitch(start);
 
 
        edl->optimize();
@@ -862,15 +869,20 @@ void MWindow::finish_modify_handles()
 
        if( (session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
                (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT) ) {
+//printf("MWindow::finish_modify_handles %d\n", __LINE__);
                edl->local_session->set_selectionstart(session->drag_position);
                edl->local_session->set_selectionend(session->drag_position);
+               edl->deglitch(session->drag_position);
        }
        else
        if( edit_mode != MOVE_NO_EDITS ) {
+//printf("MWindow::finish_modify_handles %d\n", __LINE__);
                edl->local_session->set_selectionstart(session->drag_start);
                edl->local_session->set_selectionend(session->drag_start);
+               edl->deglitch(session->drag_start);
        }
 
+// clamp the selection to 0
        if( edl->local_session->get_selectionstart(1) < 0 ) {
                edl->local_session->set_selectionstart(0);
                edl->local_session->set_selectionend(0);
@@ -1047,6 +1059,10 @@ void MWindow::mute_selection()
                edl->paste_silence(start, end, 0,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits);
+               edl->deglitch(start);
+               edl->deglitch(end);
+
+               
                save_backup();
                undo->update_undo_after(_("mute"), LOAD_EDITS);
 
@@ -1108,7 +1124,7 @@ int MWindow::paste(double start,
        int edit_plugins,
        int edit_autos)
 {
-       clear(0);
+       clear(0, 1);
 
 // Want to insert with assets shared with the master EDL.
        insert(start, file,
@@ -1131,7 +1147,7 @@ void MWindow::paste()
                gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
                FileXML file;
                file.read_from_string(string);
-               clear(0);
+               clear(0, 1);
 
                insert(start, &file,
                        edl->session->labels_follow_edits,
@@ -1609,6 +1625,8 @@ void MWindow::paste_silence()
                edl->session->labels_follow_edits,
                edl->session->plugins_follow_edits,
                edl->session->autos_follow_edits);
+       edl->deglitch(start);
+       edl->deglitch(end);
        edl->optimize();
        save_backup();
        undo->update_undo_after(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
@@ -2145,6 +2163,10 @@ void MWindow::trim_selection()
                edl->session->labels_follow_edits,
                edl->session->plugins_follow_edits,
                edl->session->autos_follow_edits);
+       edl->deglitch(0);
+       edl->deglitch(edl->local_session->get_selectionend() -
+               edl->local_session->get_selectionstart());
+       
 
        save_backup();
        undo->update_undo_after(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
index 9f0c70d507c1545b48bb58f943ea386922c5c78c..14df0a12900a26add674d579d44724b05a327268 100644 (file)
@@ -84,8 +84,7 @@ int New::handle_event()
 
 void New::create_new_edl()
 {
-       if(!new_edl)
-       {
+       if( !new_edl ) {
                new_edl = new EDL;
                new_edl->create_objects();
                new_edl->load_defaults(mwindow->defaults);
@@ -96,12 +95,9 @@ void New::create_new_edl()
 int New::create_new_project()
 {
        mwindow->cwindow->playback_engine->que->send_command(STOP,
-               CHANGE_NONE,
-               0,
-               0);
+               CHANGE_NONE, 0, 0);
 
-       for(int i = 0; i < mwindow->vwindows.size(); i++)
-       {
+       for( int i=0; i<mwindow->vwindows.size(); ++i ) {
                VWindow *vwindow = mwindow->vwindows.get(i);
                if( !vwindow->is_running() ) continue;
                vwindow->playback_engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
@@ -113,8 +109,6 @@ int New::create_new_project()
        mwindow->gui->lock_window();
        mwindow->reset_caches();
 
-
-
        memcpy(new_edl->session->achannel_positions,
                &mwindow->preferences->channel_positions[
                        MAXCHANNELS * (new_edl->session->audio_channels - 1)],
@@ -152,8 +146,6 @@ NewThread::~NewThread()
        close_window();
 }
 
-
-
 BC_Window* NewThread::new_gui()
 {
        mwindow->edl->save_defaults(mwindow->defaults);
@@ -170,29 +162,22 @@ BC_Window* NewThread::new_gui()
        return nwindow;
 }
 
-
-
 void NewThread::handle_close_event(int result)
 {
-
        if( !new_project->new_edl ) return;
        new_project->new_edl->save_defaults(mwindow->defaults);
        mwindow->defaults->save();
 
-       if(result)
-       {
+       if( result ) {
 // Aborted
                if( !new_project->new_edl->Garbage::remove_user() )
                        new_project->new_edl = 0;
        }
-       else
-       {
+       else {
                new_project->create_new_project();
        }
 }
 
-
-
 int NewThread::load_defaults()
 {
        auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
@@ -207,8 +192,7 @@ int NewThread::save_defaults()
 
 int NewThread::update_aspect()
 {
-       if(auto_aspect)
-       {
+       if( auto_aspect ) {
                char string[BCTEXTLEN];
                mwindow->create_aspect_ratio(new_project->new_edl->session->aspect_w,
                        new_project->new_edl->session->aspect_h,
@@ -223,8 +207,6 @@ int NewThread::update_aspect()
 }
 
 
-
-
 NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y)
  : BC_Window(_(PROGRAM_NAME ": New Project"), x, y, WIDTH, HEIGHT,
                -1, -1, 0, 0, 1)
@@ -238,7 +220,7 @@ NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y)
 NewWindow::~NewWindow()
 {
        lock_window("NewWindow::~NewWindow");
-       if(format_presets) delete format_presets;
+       if( format_presets ) delete format_presets;
        unlock_window();
 }
 
@@ -261,8 +243,6 @@ void NewWindow::create_objects()
        x = format_presets->x;
        y = format_presets->y;
 
-
-
        y += 40;
        y1 = y;
        add_subwindow(new BC_Title(x, y, _("Audio"), LARGEFONT));
@@ -365,10 +345,7 @@ void NewWindow::create_objects()
        add_subwindow(aspect_h_text = new NewAspectH(this, "", x1, y));
        x1 += aspect_h_text->get_w();
        add_subwindow(new AspectPulldown(mwindow,
-               aspect_w_text,
-               aspect_h_text,
-               x1,
-               y));
+               aspect_w_text, aspect_h_text, x1, y));
 
        x1 = aspect_w_text->get_x();
        y += aspect_w_text->get_h() + 5;
@@ -419,11 +396,6 @@ int NewWindow::update()
 }
 
 
-
-
-
-
-
 NewPresets::NewPresets(MWindow *mwindow, NewWindow *gui, int x, int y)
  : FormatPresets(mwindow, gui, 0, x, y)
 {
@@ -445,7 +417,6 @@ EDL* NewPresets::get_edl()
 }
 
 
-
 NewATracks::NewATracks(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 90, 1, text)
 {
@@ -478,6 +449,7 @@ int NewATracksTumbler::handle_down_event()
        return 1;
 }
 
+
 NewAChannels::NewAChannels(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 90, 1, text)
 {
@@ -490,6 +462,7 @@ int NewAChannels::handle_event()
        return 1;
 }
 
+
 NewAChannelsTumbler::NewAChannelsTumbler(NewWindow *nwindow, int x, int y)
  : BC_Tumbler(x, y)
 {
@@ -523,18 +496,10 @@ int NewSampleRate::handle_event()
        return 1;
 }
 
+
 SampleRatePulldown::SampleRatePulldown(MWindow *mwindow, BC_TextBox *output, int x, int y)
- : BC_ListBox(x,
-       y,
-       100,
-       200,
-       LISTBOX_TEXT,
-       &mwindow->theme->sample_rates,
-       0,
-       0,
-       1,
-       0,
-       1)
+ : BC_ListBox(x, y, 100, 200, LISTBOX_TEXT,
+       &mwindow->theme->sample_rates, 0, 0, 1, 0, 1)
 {
        this->mwindow = mwindow;
        this->output = output;
@@ -548,19 +513,6 @@ int SampleRatePulldown::handle_event()
 }
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
 NewVTracks::NewVTracks(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 90, 1, text)
 {
@@ -573,6 +525,7 @@ int NewVTracks::handle_event()
        return 1;
 }
 
+
 NewVTracksTumbler::NewVTracksTumbler(NewWindow *nwindow, int x, int y)
  : BC_Tumbler(x, y)
 {
@@ -593,6 +546,7 @@ int NewVTracksTumbler::handle_down_event()
        return 1;
 }
 
+
 NewVChannels::NewVChannels(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 90, 1, text)
 {
@@ -605,6 +559,7 @@ int NewVChannels::handle_event()
        return 1;
 }
 
+
 NewVChannelsTumbler::NewVChannelsTumbler(NewWindow *nwindow, int x, int y)
  : BC_Tumbler(x, y)
 {
@@ -625,6 +580,7 @@ int NewVChannelsTumbler::handle_down_event()
        return 1;
 }
 
+
 NewFrameRate::NewFrameRate(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 90, 1, text)
 {
@@ -637,21 +593,11 @@ int NewFrameRate::handle_event()
        return 1;
 }
 
+
 FrameRatePulldown::FrameRatePulldown(MWindow *mwindow,
-       BC_TextBox *output,
-       int x,
-       int y)
- : BC_ListBox(x,
-       y,
-       100,
-       200,
-       LISTBOX_TEXT,
-       &mwindow->theme->frame_rates,
-       0,
-       0,
-       1,
-       0,
-       1)
+       BC_TextBox *output, int x, int y)
+ : BC_ListBox(x, y, 150, 250, LISTBOX_TEXT,
+       &mwindow->theme->frame_rates, 0, 0, 1, 0, 1)
 {
        this->mwindow = mwindow;
        this->output = output;
@@ -665,26 +611,15 @@ int FrameRatePulldown::handle_event()
 }
 
 FrameSizePulldown::FrameSizePulldown(Theme *theme,
-               BC_TextBox *output_w,
-               BC_TextBox *output_h,
-               int x,
-               int y)
- : BC_ListBox(x,
-       y,
-       100,
-       250,
-       LISTBOX_TEXT,
-       &theme->frame_sizes,
-       0,
-       0,
-       1,
-       0,
-       1)
+               BC_TextBox *output_w, BC_TextBox *output_h, int x, int y)
+ : BC_ListBox(x, y, 150, 250, LISTBOX_TEXT,
+       &theme->frame_sizes, 0, 0, 1, 0, 1)
 {
        this->theme = theme;
        this->output_w = output_w;
        this->output_h = output_h;
 }
+
 int FrameSizePulldown::handle_event()
 {
        char *text = get_selection(0, 0)->get_text();
@@ -694,8 +629,7 @@ int FrameSizePulldown::handle_event()
 
        strcpy(string, text);
        ptr = strrchr(string, 'x');
-       if(ptr)
-       {
+       if( ptr ) {
                ptr++;
                h = atol(ptr);
 
@@ -709,6 +643,7 @@ int FrameSizePulldown::handle_event()
        return 1;
 }
 
+
 NewOutputW::NewOutputW(NewWindow *nwindow, int x, int y)
  : BC_TextBox(x, y, 70, 1, nwindow->new_edl->session->output_w)
 {
@@ -721,6 +656,7 @@ int NewOutputW::handle_event()
        return 1;
 }
 
+
 NewOutputH::NewOutputH(NewWindow *nwindow, int x, int y)
  : BC_TextBox(x, y, 70, 1, nwindow->new_edl->session->output_h)
 {
@@ -733,6 +669,7 @@ int NewOutputH::handle_event()
        return 1;
 }
 
+
 NewAspectW::NewAspectW(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 70, 1, text)
 {
@@ -745,6 +682,7 @@ int NewAspectW::handle_event()
        return 1;
 }
 
+
 NewAspectH::NewAspectH(NewWindow *nwindow, const char *text, int x, int y)
  : BC_TextBox(x, y, 70, 1, text)
 {
@@ -757,27 +695,17 @@ int NewAspectH::handle_event()
        return 1;
 }
 
+
 AspectPulldown::AspectPulldown(MWindow *mwindow,
-               BC_TextBox *output_w,
-               BC_TextBox *output_h,
-               int x,
-               int y)
- : BC_ListBox(x,
-       y,
-       100,
-       200,
-       LISTBOX_TEXT,
-       &mwindow->theme->aspect_ratios,
-       0,
-       0,
-       1,
-       0,
-       1)
+               BC_TextBox *output_w, BC_TextBox *output_h, int x, int y)
+ : BC_ListBox(x, y, 100, 200, LISTBOX_TEXT,
+       &mwindow->theme->aspect_ratios, 0, 0, 1, 0, 1)
 {
        this->mwindow = mwindow;
        this->output_w = output_w;
        this->output_h = output_h;
 }
+
 int AspectPulldown::handle_event()
 {
        char *text = get_selection(0, 0)->get_text();
@@ -787,8 +715,7 @@ int AspectPulldown::handle_event()
 
        strcpy(string, text);
        ptr = strrchr(string, ':');
-       if(ptr)
-       {
+       if( ptr ) {
                ptr++;
                h = atof(ptr);
 
@@ -802,6 +729,7 @@ int AspectPulldown::handle_event()
        return 1;
 }
 
+
 ColormodelItem::ColormodelItem(const char *text, int value)
  : BC_ListBoxItem(text)
 {
@@ -809,21 +737,9 @@ ColormodelItem::ColormodelItem(const char *text, int value)
 }
 
 ColormodelPulldown::ColormodelPulldown(MWindow *mwindow,
-               BC_TextBox *output_text,
-               int *output_value,
-               int x,
-               int y)
- : BC_ListBox(x,
-       y,
-       200,
-       150,
-       LISTBOX_TEXT,
-       (ArrayList<BC_ListBoxItem*>*)&mwindow->colormodels,
-       0,
-       0,
-       1,
-       0,
-       1)
+               BC_TextBox *output_text, int *output_value, int x, int y)
+ : BC_ListBox(x, y, 200, 150, LISTBOX_TEXT,
+       (ArrayList<BC_ListBoxItem*>*)&mwindow->colormodels, 0, 0, 1, 0, 1)
 {
        this->mwindow = mwindow;
        this->output_text = output_text;
@@ -840,8 +756,8 @@ int ColormodelPulldown::handle_event()
 
 const char* ColormodelPulldown::colormodel_to_text()
 {
-       for(int i = 0; i < mwindow->colormodels.total; i++)
-               if(mwindow->colormodels.values[i]->value == *output_value)
+       for( int i=0; i<mwindow->colormodels.total; ++i )
+               if( mwindow->colormodels.values[i]->value == *output_value )
                        return mwindow->colormodels.values[i]->get_text();
        return _("Unknown");
 }
@@ -910,12 +826,6 @@ int NewAspectAuto::handle_event()
 }
 
 
-
-
-
-
-
-
 NewSwapExtents::NewSwapExtents(MWindow *mwindow, NewWindow *gui, int x, int y)
  : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents"))
 {
@@ -936,6 +846,3 @@ int NewSwapExtents::handle_event()
        return 1;
 }
 
-
-
-
index 178082a42449eff849b864df011e7de647f5ee6c..e05080999f3f218c0b05a4cb3cccd4a39f8d92ba 100644 (file)
@@ -158,15 +158,8 @@ void PackageRenderer::create_output()
                strncpy(asset->path, package->path, sizeof(asset->path));
 
        file = new File;
-
        file->set_processors(preferences->processors);
-
-//printf("PackageRenderer::create_output %d\n", __LINE__);
-       result = file->open_file(preferences,
-                                       asset,
-                                       0,
-                                       1);
-//printf("PackageRenderer::create_output %d %d\n", __LINE__, result);
+       result = file->open_file(preferences, asset, 0, 1);
 
        if(result && mwindow)
        {
@@ -251,7 +244,12 @@ void PackageRenderer::create_engine()
                direct_frame_copying = 0;
 
 
-//printf("PackageRenderer::create_engine %d\n", __LINE__);
+//printf("PackageRenderer::create_engine %d video_write_length=%d\n", __LINE__, video_write_length);
+// starting frames are corrupted if video_write_length > 2.  Work around it, for now.
+               if(video_write_length > 2)
+               {
+                       video_write_length = 2;
+               }
                file->start_video_thread(video_write_length,
                        command->get_edl()->session->color_model,
                        preferences->processors > 1 ? 2 : 1,
@@ -416,7 +414,8 @@ void PackageRenderer::do_video()
                                        VFrame *preview_output;
 
                                        video_device->new_output_buffer(&preview_output,
-                                               command->get_edl()->session->color_model);
+                                               command->get_edl()->session->color_model,
+                                               command->get_edl());
 
                                        preview_output->copy_from(video_output_ptr);
                                        video_device->write_buffer(preview_output,
@@ -742,6 +741,7 @@ int PackageRenderer::direct_frame_copy(EDL *edl,
 //printf("Render::direct_frame_copy 2\n");
 
                if(!package->use_brender)
+               {
                        error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
                                video_position,
                                PLAY_FORWARD,
@@ -749,7 +749,9 @@ int PackageRenderer::direct_frame_copy(EDL *edl,
                                1,
                                0,
                                0);
-
+//printf("Render::direct_frame_copy %d %d\n", __LINE__, compressed_output->get_compressed_size());
+               }
+               
 
                if(!error && video_preroll > 0)
                {
index 1c329474636f994f1c536979c728c55f5c7d3830..22fee714ef0675a3c74cba4585ecd1195cca4b24 100644 (file)
@@ -239,7 +239,7 @@ const char *VideoOutConfig::default_video_device = "/dev/video0";
 
 VideoOutConfig::VideoOutConfig()
 {
-       driver = PLAYBACK_X11_XV;
+       driver = PLAYBACK_X11;
        x11_host[0] = 0;
        x11_use_fields = USE_NO_FIELDS;
 
@@ -259,6 +259,7 @@ VideoOutConfig::VideoOutConfig()
        contrast = 32768;
        whiteness = 32768;
        out_channel = -1;
+       use_direct_x11 = 1;
 }
 
 VideoOutConfig::~VideoOutConfig()
@@ -276,6 +277,7 @@ int VideoOutConfig::operator==(VideoOutConfig &that)
        return (driver == that.driver) &&
                !strcmp(x11_host, that.x11_host) &&
                (x11_use_fields == that.x11_use_fields) &&
+               (use_direct_x11 == that.use_direct_x11) &&
                (brightness == that.brightness) &&
                (hue == that.hue) &&
                (color == that.color) &&
@@ -309,6 +311,7 @@ void VideoOutConfig::copy_from(VideoOutConfig *src)
        this->driver = src->driver;
        strcpy(this->x11_host, src->x11_host);
        this->x11_use_fields = src->x11_use_fields;
+       this->use_direct_x11 = src->use_direct_x11;
 
        firewire_channel = src->firewire_channel;
        firewire_port = src->firewire_port;
index 99323f640ea226f9c413dbeaad13b68a7c9838c6..1896a5da8c9f839aadf248dc741070a6b1f45632 100644 (file)
@@ -99,6 +99,7 @@ public:
 
        int driver;
        int out_channel;
+       int use_direct_x11;
 
 // X11 options
        char x11_host[BCTEXTLEN];
index cadec09d5fcd8f0c583922451c4056f27fee26de..91adc592dca8dcd3e8381626b25661c3aafb7c9d 100644 (file)
@@ -68,30 +68,19 @@ void PlaybackPrefs::create_objects()
 
        x = mwindow->theme->preferencesoptions_x;
        y = mwindow->theme->preferencesoptions_y;
-       //int margin = mwindow->theme->widget_border;
+       int margin = mwindow->theme->widget_border;
 
 // Audio
-       add_subwindow(new BC_Title(x,
-               y,
-               _("Audio Out"),
-               LARGEFONT));
-
-
-       y += get_text_height(LARGEFONT) + 5;
-
-
        BC_Title *title1, *title2;
+       add_subwindow(title1 = new BC_Title(x, y, _("Audio Out"), LARGEFONT));
+       y += title1->get_h() + margin;
        add_subwindow(title2 = new BC_Title(x, y, _("Playback buffer samples:"), MEDIUMFONT));
-       x2 = MAX(title2->get_w(), title2->get_w()) + 10;
+       x2 = title2->get_x() + title2->get_w() + margin;
 
 SET_TRACE
        sprintf(string, "%d", playback_config->aconfig->fragment_size);
        PlaybackModuleFragment *menu;
-       add_subwindow(menu = new PlaybackModuleFragment(x2,
-               y,
-               pwindow,
-               this,
-               string));
+       add_subwindow(menu = new PlaybackModuleFragment(x2, y, pwindow, this, string));
        menu->add_item(new BC_MenuItem("1024"));
        menu->add_item(new BC_MenuItem("2048"));
        menu->add_item(new BC_MenuItem("4096"));
@@ -141,26 +130,29 @@ SET_TRACE
 
 
 // Video
-       y += audio_device->get_h();
+       y += audio_device->get_h(0) + margin;
 
 SET_TRACE
-       add_subwindow(new BC_Bar(5, y,  get_w() - 10));
+       add_subwindow(new BC_Bar(x, y,  get_w() - x * 2));
        y += 5;
 
 SET_TRACE
-       add_subwindow(new BC_Title(x, y, _("Video Out"), LARGEFONT));
-       y += 30;
+       add_subwindow(title1 = new BC_Title(x, y, _("Video Out"), LARGEFONT));
+       y += title1->get_h() + margin;
 
 SET_TRACE
        add_subwindow(window = new VideoEveryFrame(pwindow, this, x, y));
-
-       add_subwindow(new BC_Title(x + 200, y + 5, _("Framerate achieved:")));
-       add_subwindow(framerate_title = new BC_Title(x + 350, y + 5, "--", MEDIUMFONT, RED));
+       int x1 = x + window->get_w() + 30;
+       const char *txt = _("Framerate achieved:");
+       int y1 = y + (window->get_h() - BC_Title::calculate_h(this, txt)) / 2;
+       add_subwindow(title1 = new BC_Title(x1, y1, txt));
+       x1 += title1->get_w() + margin;
+       add_subwindow(framerate_title = new BC_Title(x1, y1, _("--"), MEDIUMFONT, RED));
        draw_framerate(0);
-       y += window->get_h() + 5;
+       y += window->get_h() + 2*margin;
 
-       add_subwindow(asynchronous = new VideoAsynchronous(pwindow, x, y));
-       y += asynchronous->get_h() + 10;
+//     add_subwindow(asynchronous = new VideoAsynchronous(pwindow, x, y));
+//     y += asynchronous->get_h() + 10;
 
 SET_TRACE
        add_subwindow(title1 = new BC_Title(x, y, _("Scaling equation: Enlarge / Reduce ")));
@@ -174,14 +166,13 @@ SET_TRACE
 
        add_subwindow(title1 = new BC_Title(x, y, _("DVD Subtitle to display:")));
        PlaybackSubtitleNumber *subtitle_number;
-       subtitle_number = new PlaybackSubtitleNumber(x + title1->get_w() + 10,
-               y,
-               pwindow,
-               this);
+       x1 = x + title1->get_w() + margin;
+       subtitle_number = new PlaybackSubtitleNumber(x1, y, pwindow, this);
        subtitle_number->create_objects();
 
        x2 = x + title1->get_w() + 10 + subtitle_number->get_w() + 30;
        PlaybackSubtitle *subtitle_toggle;
+       x1 += subtitle_number->get_w() + margin;
        add_subwindow(subtitle_toggle = new PlaybackSubtitle(x2, y, pwindow, this));
        y += subtitle_toggle->get_h();
 
@@ -197,18 +188,18 @@ SET_TRACE
 
        add_subwindow(interpolate_raw = new PlaybackInterpolateRaw( x, y,
                pwindow, this));
-       y += interpolate_raw->get_h();
+       y += interpolate_raw->get_h() + margin;
 
-       add_subwindow(white_balance_raw = new PlaybackWhiteBalanceRaw( x, y,
+       add_subwindow(white_balance_raw = new PlaybackWhiteBalanceRaw(x, y,
                pwindow, this));
-       y += white_balance_raw->get_h() + 10;
-       if(!pwindow->thread->edl->session->interpolate_raw)
-               white_balance_raw->disable();
+       if(!pwindow->thread->edl->session->interpolate_raw) 
+               white_balance_raw->disable();
+       y += white_balance_raw->get_h() + margin;
 
-       y += white_balance_raw->get_h() + 5;
        add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:")));
-       video_device = new VDevicePrefs(x + vdevice_title->get_w() + 10, y,
-               pwindow, this, playback_config->vconfig, 0, MODEPLAY);
+       y += vdevice_title->get_h() + margin;
+       video_device = new VDevicePrefs(x, y, pwindow, this,
+               playback_config->vconfig, 0, MODEPLAY);
        video_device->initialize(0);
 }
 
@@ -327,7 +318,7 @@ PlaybackInterpolateRaw::PlaybackInterpolateRaw( int x, int y,
 int PlaybackInterpolateRaw::handle_event()
 {
        pwindow->thread->edl->session->interpolate_raw = get_value();
-       if(!pwindow->thread->edl->session->interpolate_raw) {
+       if( !pwindow->thread->edl->session->interpolate_raw ) {
                playback->white_balance_raw->update(0, 0);
                playback->white_balance_raw->disable();
        }
@@ -338,7 +329,6 @@ int PlaybackInterpolateRaw::handle_event()
        return 1;
 }
 
-
 PlaybackWhiteBalanceRaw::PlaybackWhiteBalanceRaw( int x, int y,
                PreferencesWindow *pwindow, PlaybackPrefs *playback)
  : BC_CheckBox(x,
@@ -358,23 +348,22 @@ int PlaybackWhiteBalanceRaw::handle_event()
        return 1;
 }
 
-
-VideoAsynchronous::VideoAsynchronous(PreferencesWindow *pwindow, int x, int y)
- : BC_CheckBox(x, y,
-       pwindow->thread->edl->session->video_every_frame &&
-               pwindow->thread->edl->session->video_asynchronous,
-       _("Decode frames asynchronously"))
-{
-       this->pwindow = pwindow;
-       if(!pwindow->thread->edl->session->video_every_frame)
-               disable();
-}
-
-int VideoAsynchronous::handle_event()
-{
-       pwindow->thread->edl->session->video_asynchronous = get_value();
-       return 1;
-}
+// VideoAsynchronous::VideoAsynchronous(PreferencesWindow *pwindow, int x, int y)
+//  : BC_CheckBox(x, y,
+//     pwindow->thread->edl->session->video_every_frame &&
+//             pwindow->thread->edl->session->video_asynchronous,
+//     _("Decode frames asynchronously"))
+// {
+//     this->pwindow = pwindow;
+//     if(!pwindow->thread->edl->session->video_every_frame)
+//             disable();
+// }
+// 
+// int VideoAsynchronous::handle_event()
+// {
+//     pwindow->thread->edl->session->video_asynchronous = get_value();
+//     return 1;
+// }
 
 
 VideoEveryFrame::VideoEveryFrame(PreferencesWindow *pwindow,
@@ -388,14 +377,14 @@ VideoEveryFrame::VideoEveryFrame(PreferencesWindow *pwindow,
 int VideoEveryFrame::handle_event()
 {
        pwindow->thread->edl->session->video_every_frame = get_value();
-       if(!pwindow->thread->edl->session->video_every_frame) {
-               playback_prefs->asynchronous->update(0, 0);
-               playback_prefs->asynchronous->disable();
-       }
-       else {
-               playback_prefs->asynchronous->update(pwindow->thread->edl->session->video_asynchronous, 0);
-               playback_prefs->asynchronous->enable();
-       }
+//     if(!pwindow->thread->edl->session->video_every_frame) {
+//             playback_prefs->asynchronous->update(0, 0);
+//             playback_prefs->asynchronous->disable();
+//     }
+//     else {
+//             playback_prefs->asynchronous->update(pwindow->thread->edl->session->video_asynchronous, 0);
+//             playback_prefs->asynchronous->enable();
+//     }
        return 1;
 }
 
index 167d3bd62f5a91cfa961ca9b3508690a770ac87c..f2befa9f1108526cad39baea358805fe3f2d1909 100644 (file)
@@ -30,7 +30,7 @@ class PlaybackViewFollows;
 class PlaybackSoftwareTimer;
 class PlaybackRealTime;
 class PlaybackMap51_2;
-class VideoAsynchronous;
+//class VideoAsynchronous;
 class VideoEveryFrame;
 class PlaybackPreload;
 class PlaybackInterpolateRaw;
@@ -70,7 +70,7 @@ public:
        BC_Title *framerate_title;
        PlaybackInterpolateRaw *interpolate_raw;
        PlaybackWhiteBalanceRaw *white_balance_raw;
-       VideoAsynchronous *asynchronous;
+//     VideoAsynchronous *asynchronous;
 
        BC_Title *vdevice_title;
        PlaybackAudioOffset *audio_offset;
@@ -127,6 +127,14 @@ public:
        PreferencesWindow *pwindow;
 };
 
+// class VideoAsynchronous : public BC_CheckBox
+// {
+// public:
+//     VideoAsynchronous(PreferencesWindow *pwindow, int x, int y);
+//     int handle_event();
+//     PreferencesWindow *pwindow;
+// };
+
 class PlaybackMap51_2 : public BC_CheckBox
 {
 public:
@@ -137,14 +145,6 @@ public:
        PlaybackPrefs *playback_prefs;
 };
 
-class VideoAsynchronous : public BC_CheckBox
-{
-public:
-       VideoAsynchronous(PreferencesWindow *pwindow, int x, int y);
-       int handle_event();
-       PreferencesWindow *pwindow;
-};
-
 class VideoEveryFrame : public BC_CheckBox
 {
 public:
index 03e8c3f1e642f43487950ef60b1f213e29a95262..aaec69d86e107e92da749a70a46a63b3a7b6d26e 100644 (file)
@@ -730,39 +730,29 @@ int PluginClient::get_interpolation_type()
 
 float PluginClient::get_red()
 {
-       if(server->mwindow)
-               return server->mwindow->edl->local_session->red;
-       else
-       if(server->edl)
-               return server->edl->local_session->red;
-       else
-               return 0;
+       EDL *edl = server->mwindow ? server->mwindow->edl : server->edl;
+       return !edl ? 0 : edl->local_session->use_max ?
+               edl->local_session->red_max :
+               edl->local_session->red;
 }
 
 float PluginClient::get_green()
 {
-       if(server->mwindow)
-               return server->mwindow->edl->local_session->green;
-       else
-       if(server->edl)
-               return server->edl->local_session->green;
-       else
-               return 0;
+       EDL *edl = server->mwindow ? server->mwindow->edl : server->edl;
+       return !edl ? 0 : edl->local_session->use_max ?
+               edl->local_session->green_max :
+               edl->local_session->green;
 }
 
 float PluginClient::get_blue()
 {
-       if(server->mwindow)
-               return server->mwindow->edl->local_session->blue;
-       else
-       if(server->edl)
-               return server->edl->local_session->blue;
-       else
-               return 0;
+       EDL *edl = server->mwindow ? server->mwindow->edl : server->edl;
+       return !edl ? 0 : edl->local_session->use_max ?
+               edl->local_session->blue_max :
+               edl->local_session->blue;
 }
 
 
-
 int64_t PluginClient::get_source_position()
 {
        return source_position;
diff --git a/cinelerra-5.1/cinelerra/presets.C b/cinelerra-5.1/cinelerra/presets.C
new file mode 100644 (file)
index 0000000..8a28909
--- /dev/null
@@ -0,0 +1,438 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include "bcsignals.h"
+#include "bcwindowbase.inc"
+#include "file.h"
+#include "filesystem.h"
+#include "filexml.h"
+#include "keyframe.h"
+#include "messages.inc"
+#include "mwindow.h"
+#include "pluginserver.h"
+#include "preferences.inc"
+#include "presets.h"
+
+#include <errno.h>
+#include <string.h>
+
+PresetsDB::PresetsDB()
+{
+}
+
+void PresetsDB::clear()
+{
+       plugins.remove_all_objects();
+}
+
+void PresetsDB::load_from_file(char *path, int is_factory, int clear_it)
+{
+       if( clear_it ) clear();
+       FileXML file;
+
+       file.read_from_file(path);
+       load_common(&file, is_factory);
+}
+
+void PresetsDB::load_from_string(char *string, int is_factory, int clear_it)
+{
+       if( clear_it ) clear();
+       
+       FileXML file;
+       file.read_from_string(string);
+       load_common(&file, is_factory);
+}
+
+
+
+void PresetsDB::load_common(FileXML *file, int is_factory)
+{
+       int result = 0;
+       char string[BCTEXTLEN];
+
+       do {
+               result = file->read_tag();
+               if( ! result  ) {
+                       if( file->tag.title_is("PLUGIN") ) {
+                               PresetsDBPlugin *plugin = 0;
+                               sprintf(string, "Unknown");
+                               const char *title = file->tag.get_property("TITLE", string);
+
+// Search for existing plugin
+                               for( int i=0; i<plugins.size(); ++i ) {
+                                       if( !strcasecmp(plugins[i]->title, title) ) {
+                                               plugin = plugins[i];
+                                               break;
+                                       }
+                               }
+
+// Create new plugin
+                               if( !plugin ) {
+                                       plugin = new PresetsDBPlugin(title);
+                                       plugins.append(plugin);
+                               }
+
+                               plugin->load(file, is_factory);
+                       }
+               }
+       } while(!result);
+}
+
+
+void PresetsDB::save()
+{
+       FileXML file;
+       for( int i=0; i<plugins.size(); ++i ) {
+               PresetsDBPlugin *plugin = plugins[i];
+               if( plugin->get_total_presets(1) > 0 ) {
+                       plugin->save(&file);
+               }
+       }
+       file.terminate_string();
+
+       char path[BCTEXTLEN];
+       sprintf(path, "%s/%s", File::get_config_path(), PRESETS_FILE);
+       FileSystem fs;
+       fs.complete_path(path);
+       file.write_to_file(path);
+}
+
+
+int PresetsDB::get_total_presets(char *plugin_title, int user_only)
+{
+       for( int i=0; i<plugins.size(); ++i ) {
+               PresetsDBPlugin *plugin = plugins[i];
+               if( !strcasecmp(plugin->title, plugin_title) ) {
+                       return plugin->get_total_presets(user_only);
+               }
+       }
+
+       return 0;
+}
+
+
+// move factory presets to the start, followed by sorted preset titles
+void PresetsDB::sort(char *plugin_title)
+{
+       PresetsDBPlugin *plugin = 0;
+       for( int i=0; !plugin && i<plugins.size(); ++i ) {
+               if( !strcasecmp(plugins[i]->title, plugin_title) )
+                       plugin = plugins[i];
+       }
+
+       if( plugin ) {
+               int done = 0;
+               int total_presets = plugin->get_total_presets(0);
+               while( !done ) {
+                       done = 1;
+                       for( int i=0; i<total_presets-1; ++i ) {
+                               PresetsDBKeyframe *keyframe1 = plugin->keyframes[i];
+                               PresetsDBKeyframe *keyframe2 = plugin->keyframes[i+1];
+
+                               if( (keyframe2->is_factory && !keyframe1->is_factory) ||
+                                   (keyframe2->is_factory == keyframe1->is_factory &&
+                                    strcmp(keyframe2->title, keyframe1->title) < 0) ) {
+                                       plugin->keyframes.set(i, keyframe2);
+                                       plugin->keyframes.set(i + 1, keyframe1);
+                                       done = 0;
+                               }
+                       }
+               }
+       }
+}
+
+
+char* PresetsDB::get_preset_title(char *plugin_title, int number)
+{
+       for( int i=0; i<plugins.size(); ++i ) {
+               PresetsDBPlugin *plugin = plugins[i];
+               if( !strcasecmp(plugin->title, plugin_title) ) {
+                       if( number < plugin->keyframes.size() )
+                               return plugin->keyframes[number]->title;
+                       printf("PresetsDB::get_preset_title %d buffer overrun\n", __LINE__);
+                       break;
+               }
+       }
+       return 0;
+}
+
+
+int PresetsDB::get_is_factory(char *plugin_title, int number)
+{
+       for( int i=0; i<plugins.size(); ++i ) {
+               PresetsDBPlugin *plugin = plugins[i];
+               if( !strcasecmp(plugin->title, plugin_title) ) {
+                       if( number < plugin->keyframes.size() )
+                               return plugin->keyframes[number]->is_factory;
+                       printf("PresetsDB::get_preset_title %d buffer overrun\n", __LINE__);
+                       break;
+               }
+       }
+       return 0;
+}
+
+
+char* PresetsDB::get_preset_data(char *plugin_title, int number)
+{
+       for( int i=0; i<plugins.size(); ++i ) {
+               PresetsDBPlugin *plugin = plugins[i];
+               if( !strcasecmp(plugin->title, plugin_title) ) {
+                       if( number < plugin->keyframes.size() )
+                               return plugin->keyframes[number]->data;
+                       printf("PresetsDB::get_preset_data %d buffer overrun\n", __LINE__);
+                       break;
+               }
+       }
+       return 0;
+}
+
+PresetsDBPlugin* PresetsDB::get_plugin(const char *plugin_title)
+{
+       for( int i=0; i<plugins.size(); ++i ) {
+               PresetsDBPlugin *plugin = plugins[i];
+               if( !strcasecmp(plugin->title, plugin_title) )
+                       return plugin;
+       }
+       return 0;
+}
+
+PresetsDBPlugin* PresetsDB::new_plugin(const char *plugin_title)
+{
+       PresetsDBPlugin *result = new PresetsDBPlugin(plugin_title);
+       plugins.append(result);
+       return result;
+}
+
+
+void PresetsDB::save_preset(const char *plugin_title, 
+       const char *preset_title, 
+       char *data)
+{
+       PresetsDBPlugin *plugin = get_plugin(plugin_title);
+       if( !plugin ) plugin = new_plugin(plugin_title);
+       PresetsDBKeyframe *keyframe = plugin->get_keyframe(preset_title, 0);
+       if( !keyframe ) keyframe = plugin->new_keyframe(preset_title);
+       keyframe->set_data(data);
+       save();
+
+}
+
+
+void PresetsDB::delete_preset(const char *plugin_title, 
+       const char *preset_title,
+       int is_factory)
+{
+       PresetsDBPlugin *plugin = get_plugin(plugin_title);
+       if( plugin ) {
+               plugin->delete_keyframe(preset_title);
+       }
+       save();
+}
+
+void PresetsDB::load_preset(const char *plugin_title,
+       const char *preset_title, 
+       KeyFrame *keyframe,
+       int is_factory)
+{
+       PresetsDBPlugin *plugin = get_plugin(plugin_title);
+       if( plugin ) {
+               plugin->load_preset(preset_title, keyframe, is_factory);
+       }
+}
+
+int PresetsDB::preset_exists(const char *plugin_title, 
+       const char *preset_title,
+       int is_factory)
+{
+       PresetsDBPlugin *plugin = get_plugin(plugin_title);
+       if( plugin ) {
+               return plugin->preset_exists(preset_title, is_factory);
+       }
+       return 0;
+}
+
+
+
+
+PresetsDBKeyframe::PresetsDBKeyframe(const char *title, int is_factory)
+{
+       this->title = strdup(title);
+       data = 0;
+       this->is_factory = is_factory;
+}
+
+PresetsDBKeyframe::~PresetsDBKeyframe()
+{
+       delete [] title;
+       delete [] data;
+}
+
+void PresetsDBKeyframe::set_data(char *data)
+{
+       delete [] this->data;
+       this->data = new char[strlen(data) + 1];
+       strcpy(this->data, data);
+}
+
+
+PresetsDBPlugin::PresetsDBPlugin(const char *title)
+{
+       this->title = strdup(title);
+}
+
+PresetsDBPlugin::~PresetsDBPlugin()
+{
+       keyframes.remove_all_objects();
+       delete [] title;
+}
+
+int PresetsDBPlugin::get_total_presets(int user_only)
+{
+       if( !user_only )
+               return keyframes.size();
+       int result = 0;
+       for( int j=0; j<keyframes.size(); ++j )
+               if( !keyframes[j]->is_factory ) ++result;
+       return result;
+}
+
+void PresetsDBPlugin::load(FileXML *file, int is_factory)
+{
+       int result = 0;
+       char string[BCTEXTLEN];
+
+       do {
+               result = file->read_tag();
+               if( !result ) {
+                       if( file->tag.title_is("/PLUGIN") ) break;
+                       else
+                       if( file->tag.title_is("KEYFRAME") ) {
+                               sprintf(string, "Unknown");
+                               const char *keyframe_title = file->tag.get_property("TITLE", string);
+                               PresetsDBKeyframe *keyframe = new PresetsDBKeyframe(keyframe_title, is_factory);
+
+                               char data[MESSAGESIZE];
+                               file->read_text_until("/KEYFRAME", data, MESSAGESIZE);
+                               keyframe->set_data(data);
+                               keyframes.append(keyframe);
+               
+                       }
+               }
+       } while(!result);
+}
+
+void PresetsDBPlugin::save(FileXML *file)
+{
+       file->tag.set_title("PLUGIN");
+       file->tag.set_property("TITLE", title);
+       file->append_tag();
+       file->append_newline();
+
+       for( int j=0; j<keyframes.size(); ++j ) {
+               PresetsDBKeyframe *keyframe = keyframes[j];
+               
+               if( !keyframe->is_factory ) {
+                       file->tag.set_title("KEYFRAME");
+                       file->tag.set_property("TITLE", keyframe->title);
+                       file->append_tag();
+                       file->append_text(keyframe->data);
+                       file->tag.set_title("/KEYFRAME");
+                       file->append_tag();
+                       file->append_newline();
+               }
+       }
+
+       file->tag.set_title("/PLUGIN");
+       file->append_tag();
+       file->append_newline();
+}
+
+PresetsDBKeyframe* PresetsDBPlugin::get_keyframe(const char *title, 
+       int is_factory)
+{
+       for( int i=0; i<keyframes.size(); ++i ) {
+               PresetsDBKeyframe *keyframe = keyframes[i];
+               if( !strcasecmp(keyframe->title, title) && 
+                   keyframe->is_factory == is_factory )
+                       return keyframe;
+       }
+       return 0;
+}
+
+void PresetsDBPlugin::delete_keyframe(const char *title)
+{
+       for( int i=0; i<keyframes.size(); ++i ) {
+               PresetsDBKeyframe *keyframe = keyframes[i];
+               if( !strcasecmp(keyframe->title, title) && !keyframe->is_factory )
+                   keyframes.remove_object_number(i);
+                       return;
+       }
+}
+
+
+PresetsDBKeyframe* PresetsDBPlugin::new_keyframe(const char *title)
+{
+       PresetsDBKeyframe *keyframe = new PresetsDBKeyframe(title, 0);
+       keyframes.append(keyframe);
+       return keyframe;
+}
+
+void PresetsDBPlugin::load_preset(const char *preset_title, 
+       KeyFrame *keyframe,
+       int is_factory)
+{
+       PresetsDBKeyframe *src = get_keyframe(preset_title, is_factory);
+       if( src ) {
+               keyframe->set_data(src->data);
+// Save as the plugin's default, Need the path
+//printf("PresetsDBPlugin::load_preset %d %s\n", __LINE__, title);
+               PluginServer *server = MWindow::scan_plugindb(title, -1);
+               if( server ) {
+                       char path[BCTEXTLEN];
+                       server->get_defaults_path(path);
+                       FileSystem fs;
+                       fs.complete_path(path);
+
+                       FILE *fd = fopen(path, "w");
+                       if( fd ) {
+                               if( !fwrite(src->data, strlen(src->data), 1, fd) ) {
+                                       fprintf(stderr, "PresetsDBPlugin::load_preset %d \"%s\": %s\n",
+                                               __LINE__,
+                                               path,
+                                               strerror(errno));
+                               }
+
+                               fclose(fd);
+                       }
+                       else {
+                               fprintf(stderr, "PresetsDBPlugin::load_preset %d \"%s\": %s\n",
+                                       __LINE__, path, strerror(errno));
+                       }
+               }
+       }
+}
+
+int PresetsDBPlugin::preset_exists(const char *preset_title, int is_factory)
+{
+       PresetsDBKeyframe *src = get_keyframe(preset_title, is_factory);
+       return src ? 1 : 0;
+}
+
diff --git a/cinelerra-5.1/cinelerra/presets.h b/cinelerra-5.1/cinelerra/presets.h
new file mode 100644 (file)
index 0000000..1db071e
--- /dev/null
@@ -0,0 +1,128 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef PRESETS_H
+#define PRESETS_H
+
+
+#include "arraylist.h"
+#include "filexml.inc"
+#include "keyframe.inc"
+
+
+// Front end for a DB of presets for all plugins
+
+// A single preset
+class PresetsDBKeyframe
+{
+public:
+       PresetsDBKeyframe(const char *title, int is_factory);
+       ~PresetsDBKeyframe();
+
+       void set_data(char *data);
+
+       char *title;
+       char *data;
+// is a factory preset
+       int is_factory;
+};
+
+// Presets for a single plugin
+class PresetsDBPlugin
+{
+public:
+       PresetsDBPlugin(const char *title);
+       ~PresetsDBPlugin();
+       
+       
+       void load(FileXML *file, int is_factory);
+       void save(FileXML *file);
+
+// Get a preset by name
+       PresetsDBKeyframe* get_keyframe(const char *title, int is_factory);
+// Create a new keyframe
+       PresetsDBKeyframe* new_keyframe(const char *title);
+       void delete_keyframe(const char *title);
+// Load a preset into the keyframe
+       void load_preset(const char *preset_title, 
+               KeyFrame *keyframe,
+               int is_factory);
+       int preset_exists(const char *preset_title, int is_factory);
+       int get_total_presets(int user_only);
+
+       ArrayList<PresetsDBKeyframe*> keyframes;
+       char *title;
+};
+
+class PresetsDB
+{
+public:
+       PresetsDB();
+
+// Load the database from the file.
+       void load_from_file(char *path, int is_factory, int clear_it);
+// load the database from a string
+       void load_from_string(char *string, int is_factory, int clear_it);
+       void load_common(FileXML *file, int is_factory);
+       
+// Save the database to the file.
+       void save();
+       void sort(char *plugin_title);
+
+// Get the total number of presets for a plugin
+       int get_total_presets(char *plugin_title, int user_only);
+// Get the title of a preset
+       char* get_preset_title(char *plugin_title, int number);
+       int get_is_factory(char *plugin_title, int number);
+// Get the data for a preset
+       char* get_preset_data(char *plugin_title, int number);
+// Get a pluginDB by name
+       PresetsDBPlugin* get_plugin(const char *plugin_title);
+// Create a pluginDB
+       PresetsDBPlugin* new_plugin(const char *plugin_title);
+       void save_preset(const char *plugin_title, 
+               const char *preset_title, 
+               char *data);
+       void delete_preset(const char *plugin_title, 
+               const char *preset_title,
+               int is_factory);
+// Load a preset into the keyframe
+       void load_preset(const char *plugin_title, 
+               const char *preset_title, 
+               KeyFrame *keyframe,
+               int is_factory);
+       int preset_exists(const char *plugin_title, 
+               const char *preset_title,
+               int is_factory);
+
+private:
+// Remove all plugin data
+       void clear();
+
+       ArrayList<PresetsDBPlugin*> plugins;
+};
+
+
+
+#endif
+
+
+
diff --git a/cinelerra-5.1/cinelerra/presets.inc b/cinelerra-5.1/cinelerra/presets.inc
new file mode 100644 (file)
index 0000000..cae1427
--- /dev/null
@@ -0,0 +1,32 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef PRESETS_INC
+#define PRESETS_INC
+
+
+class PresetsDB;
+
+#endif
+
+
+
+
diff --git a/cinelerra-5.1/cinelerra/presetsgui.C b/cinelerra-5.1/cinelerra/presetsgui.C
new file mode 100644 (file)
index 0000000..c5dbe8e
--- /dev/null
@@ -0,0 +1,508 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#if 0
+
+
+
+
+#include "edl.h"
+#include "keyframe.h"
+#include "keys.h"
+#include "language.h"
+#include "localsession.h"
+#include "mainsession.h"
+#include "mainundo.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "plugin.h"
+#include "presets.h"
+#include "presetsgui.h"
+#include "theme.h"
+#include "trackcanvas.h"
+#include "tracks.h"
+
+
+
+
+
+
+
+
+
+
+
+PresetsThread::PresetsThread(MWindow *mwindow)
+ : BC_DialogThread()
+{
+       this->mwindow = mwindow;
+       plugin = 0;
+       data = new ArrayList<BC_ListBoxItem*>;
+       presets_db = new PresetsDB;
+       plugin_title[0] = 0;
+       window_title[0] = 0;
+}
+
+PresetsThread::~PresetsThread()
+{
+       delete data;
+}
+
+void PresetsThread::calculate_list()
+{
+       data->remove_all_objects();
+       int total_presets = presets_db->get_total_presets(plugin_title);
+       for(int i = 0; i < total_presets; i++)
+       {
+               data->append(new BC_ListBoxItem(presets_db->get_preset_title(
+                       plugin_title,
+                       i)));
+       }
+}
+
+
+void PresetsThread::start_window(Plugin *plugin)
+{
+       if(!BC_DialogThread::is_running())
+       {
+               this->plugin = plugin;
+               plugin->calculate_title(plugin_title, 0);
+               sprintf(window_title, PROGRAM_NAME ": %s Presets", plugin_title);
+
+
+// Calculate database
+               presets_db->load();
+               calculate_list();
+
+
+               mwindow->gui->unlock_window();
+               BC_DialogThread::start();
+               mwindow->gui->lock_window("PresetsThread::start_window");
+       }
+}
+
+BC_Window* PresetsThread::new_gui()
+{
+       mwindow->gui->lock_window("PresetsThread::new_gui");
+       int x = mwindow->gui->get_abs_cursor_x(0) - 
+               mwindow->session->plugindialog_w / 2;
+       int y = mwindow->gui->get_abs_cursor_y(0) - 
+               mwindow->session->plugindialog_h / 2;
+
+       PresetsWindow *window = new PresetsWindow(mwindow, 
+               this, 
+               x, 
+               y,
+               window_title);
+
+       window->create_objects();
+       mwindow->gui->unlock_window();
+       return window;
+}
+
+void PresetsThread::handle_done_event(int result)
+{
+// Apply the preset
+       if(!result)
+       {
+               char *title = ((PresetsWindow*)get_gui())->title_text->get_text();
+               apply_preset(title);
+       }
+}
+
+void PresetsThread::handle_close_event(int result)
+{
+}
+
+void PresetsThread::save_preset(char *title)
+{
+       get_gui()->unlock_window();
+       mwindow->gui->lock_window("PresetsThread::save_preset");
+       
+// Test EDL for plugin existence
+       if(!mwindow->edl->tracks->plugin_exists(plugin))
+       {
+               mwindow->gui->unlock_window();
+               get_gui()->lock_window("PresetsThread::save_preset 2");
+               return;
+       }
+
+
+// Get current plugin keyframe
+       EDL *edl = mwindow->edl;
+       Track *track = plugin->track;
+       KeyFrame *keyframe = plugin->get_prev_keyframe(
+                       track->to_units(edl->local_session->get_selectionstart(1), 0), 
+                       PLAY_FORWARD);
+
+// Send to database
+       presets_db->save_preset(plugin_title, title, keyframe->get_data());
+
+       mwindow->gui->unlock_window();
+       get_gui()->lock_window("PresetsThread::save_preset 2");
+
+
+// Update list
+       calculate_list();
+       ((PresetsWindow*)get_gui())->list->update(data,
+               0,
+               0,
+               1);
+}
+
+void PresetsThread::delete_preset(char *title)
+{
+       get_gui()->unlock_window();
+       mwindow->gui->lock_window("PresetsThread::save_preset");
+       
+// Test EDL for plugin existence
+       if(!mwindow->edl->tracks->plugin_exists(plugin))
+       {
+               mwindow->gui->unlock_window();
+               get_gui()->lock_window("PresetsThread::delete_preset 1");
+               return;
+       }
+
+       presets_db->delete_preset(plugin_title, title);
+       
+       mwindow->gui->unlock_window();
+       get_gui()->lock_window("PresetsThread::delete_preset 2");
+
+
+// Update list
+       calculate_list();
+       ((PresetsWindow*)get_gui())->list->update(data,
+               0,
+               0,
+               1);
+}
+
+
+void PresetsThread::apply_preset(char *title)
+{
+       if(presets_db->preset_exists(plugin_title, title))
+       {
+               get_gui()->unlock_window();
+               mwindow->gui->lock_window("PresetsThread::apply_preset");
+
+// Test EDL for plugin existence
+               if(!mwindow->edl->tracks->plugin_exists(plugin))
+               {
+                       mwindow->gui->unlock_window();
+                       get_gui()->lock_window("PresetsThread::delete_preset 1");
+                       return;
+               }
+
+               mwindow->undo->update_undo_before();
+               KeyFrame *keyframe = plugin->get_keyframe();
+               presets_db->load_preset(plugin_title, title, keyframe);
+               mwindow->save_backup();
+               mwindow->undo->update_undo_after(_("apply preset"), LOAD_AUTOMATION); 
+
+               mwindow->update_plugin_guis();
+               mwindow->gui->canvas->draw_overlays();
+               mwindow->gui->canvas->flash();
+               mwindow->sync_parameters(CHANGE_PARAMS);
+
+               mwindow->gui->unlock_window();
+               get_gui()->lock_window("PresetsThread::apply_preset");
+       }
+}
+
+
+
+
+
+PresetsList::PresetsList(PresetsThread *thread,
+       PresetsWindow *window,
+       int x,
+       int y,
+       int w, 
+       int h)
+ : BC_ListBox(x, 
+               y, 
+               w, 
+               h,
+               LISTBOX_TEXT,
+               thread->data)
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int PresetsList::selection_changed()
+{
+       window->title_text->update(
+               thread->data->get(get_selection_number(0, 0))->get_text());
+       return 0;
+}
+
+int PresetsList::handle_event()
+{
+       window->set_done(0);
+       return 0;
+}
+
+
+
+
+
+
+
+
+
+
+PresetsText::PresetsText(PresetsThread *thread,
+       PresetsWindow *window,
+       int x,
+       int y,
+       int w)
+ : BC_TextBox(x, 
+       y, 
+       w, 
+       1, 
+       "")
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int PresetsText::handle_event()
+{
+       return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+PresetsDelete::PresetsDelete(PresetsThread *thread,
+       PresetsWindow *window,
+       int x,
+       int y)
+ : BC_GenericButton(x, y, _("Delete"))
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int PresetsDelete::handle_event()
+{
+       thread->delete_preset(window->title_text->get_text());
+       return 1;
+}
+
+
+
+
+
+
+
+PresetsSave::PresetsSave(PresetsThread *thread,
+       PresetsWindow *window,
+       int x,
+       int y)
+: BC_GenericButton(x, y, _("Save"))
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int PresetsSave::handle_event()
+{
+       thread->save_preset(window->title_text->get_text());
+       return 1;
+}
+
+
+
+
+
+
+
+
+PresetsApply::PresetsApply(PresetsThread *thread,
+       PresetsWindow *window,
+       int x,
+       int y)
+ : BC_GenericButton(x, y, _("Apply"))
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int PresetsApply::handle_event()
+{
+       thread->apply_preset(window->title_text->get_text());
+       return 1;
+}
+
+
+
+PresetsOK::PresetsOK(PresetsThread *thread,
+       PresetsWindow *window)
+ : BC_OKButton(window)
+{
+       this->thread = thread;
+       this->window = window;
+}
+
+int PresetsOK::keypress_event()
+{
+       if(get_keypress() == RETURN)
+       {
+printf("PresetsOK::keypress_event %d\n", __LINE__);
+               if(thread->presets_db->preset_exists(thread->plugin_title, 
+                       window->title_text->get_text()))
+               {
+printf("PresetsOK::keypress_event %d\n", __LINE__);
+                       window->set_done(0);
+                       return 1;
+               }
+               else
+               {
+printf("PresetsOK::keypress_event %d\n", __LINE__);
+                       thread->save_preset(window->title_text->get_text());
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+
+
+
+
+
+
+
+
+
+PresetsWindow::PresetsWindow(MWindow *mwindow,
+       PresetsThread *thread,
+       int x,
+       int y,
+       char *title_string)
+ : BC_Window(title_string, 
+       x,
+       y,
+       mwindow->session->presetdialog_w, 
+       mwindow->session->presetdialog_h, 
+       320, 
+       240,
+       1,
+       0,
+       1)
+{
+       this->mwindow = mwindow;
+       this->thread = thread;
+}
+
+void PresetsWindow::create_objects()
+{
+       Theme *theme = mwindow->theme;
+
+       lock_window("PresetsWindow::create_objects");
+       theme->get_presetdialog_sizes(this);
+       
+       add_subwindow(title1 = new BC_Title(theme->presets_list_x,
+               theme->presets_list_y - BC_Title::calculate_h(this, "P") - theme->widget_border,
+               _("Saved presets:")));
+       add_subwindow(list = new PresetsList(thread,
+               this,
+               theme->presets_list_x,
+               theme->presets_list_y,
+               theme->presets_list_w, 
+               theme->presets_list_h));
+       add_subwindow(title2 = new BC_Title(theme->presets_text_x,
+               theme->presets_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border,
+               _("Preset title:")));
+       add_subwindow(title_text = new PresetsText(thread,
+               this,
+               theme->presets_text_x,
+               theme->presets_text_y,
+               theme->presets_text_w));
+       add_subwindow(delete_button = new PresetsDelete(thread,
+               this,
+               theme->presets_delete_x,
+               theme->presets_delete_y));
+       add_subwindow(save_button = new PresetsSave(thread,
+               this,
+               theme->presets_save_x,
+               theme->presets_save_y));
+       add_subwindow(apply_button = new PresetsApply(thread,
+               this,
+               theme->presets_apply_x,
+               theme->presets_apply_y));
+
+       add_subwindow(new PresetsOK(thread, this));
+       add_subwindow(new BC_CancelButton(this));
+
+       show_window();
+       unlock_window();
+}
+
+int PresetsWindow::resize_event(int w, int h)
+{
+       Theme *theme = mwindow->theme;
+       mwindow->session->presetdialog_w = w;
+       mwindow->session->presetdialog_h = h;
+       theme->get_presetdialog_sizes(this);
+
+       title1->reposition_window(theme->presets_list_x,
+               theme->presets_list_y - BC_Title::calculate_h(this, "P") - theme->widget_border);
+       title2->reposition_window(theme->presets_text_x,
+               theme->presets_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border);
+       list->reposition_window(theme->presets_list_x,
+               theme->presets_list_y,
+               theme->presets_list_w, 
+               theme->presets_list_h);
+       title_text->reposition_window(theme->presets_text_x,
+               theme->presets_text_y,
+               theme->presets_text_w);
+       delete_button->reposition_window(theme->presets_delete_x,
+               theme->presets_delete_y);
+       save_button->reposition_window(theme->presets_save_x,
+               theme->presets_save_y);
+       apply_button->reposition_window(theme->presets_apply_x,
+               theme->presets_apply_y);
+       return 0;
+}
+
+
+
+
+
+
+#endif
+
diff --git a/cinelerra-5.1/cinelerra/presetsgui.h b/cinelerra-5.1/cinelerra/presetsgui.h
new file mode 100644 (file)
index 0000000..abd63e8
--- /dev/null
@@ -0,0 +1,170 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef PRESETSGUI_H
+#define PRESETSGUI_H
+
+
+// Presets for effects & transitions
+#if 0
+
+#include "bcdialog.h"
+#include "guicast.h"
+#include "mwindow.inc"
+#include "plugin.inc"
+#include "presets.inc"
+
+class PresetsWindow;
+
+
+
+
+
+class PresetsThread : public BC_DialogThread
+{
+public:
+       PresetsThread(MWindow *mwindow);
+       ~PresetsThread();
+
+       void calculate_list();
+       void start_window(Plugin *plugin);
+       BC_Window* new_gui();
+       void handle_done_event(int result);
+       void handle_close_event(int result);
+       void save_preset(char *title);
+       void delete_preset(char *title);
+       void apply_preset(char *title);
+
+       char window_title[BCTEXTLEN];
+       char plugin_title[BCTEXTLEN];
+       MWindow *mwindow;
+       Plugin *plugin;
+       ArrayList<BC_ListBoxItem*> *data;
+       PresetsDB *presets_db;
+};
+
+class PresetsList : public BC_ListBox
+{
+public:
+       PresetsList(PresetsThread *thread,
+               PresetsWindow *window,
+               int x,
+               int y,
+               int w, 
+               int h);
+       int selection_changed();
+       int handle_event();
+       PresetsThread *thread;
+       PresetsWindow *window;
+};
+
+class PresetsText : public BC_TextBox
+{
+public:
+       PresetsText(PresetsThread *thread,
+               PresetsWindow *window,
+               int x,
+               int y,
+               int w);
+       int handle_event();
+       PresetsThread *thread;
+       PresetsWindow *window;
+};
+
+
+class PresetsDelete : public BC_GenericButton
+{
+public:
+       PresetsDelete(PresetsThread *thread,
+               PresetsWindow *window,
+               int x,
+               int y);
+       int handle_event();
+       PresetsThread *thread;
+       PresetsWindow *window;
+};
+
+class PresetsSave : public BC_GenericButton
+{
+public:
+       PresetsSave(PresetsThread *thread,
+               PresetsWindow *window,
+               int x,
+               int y);
+       int handle_event();
+       PresetsThread *thread;
+       PresetsWindow *window;
+};
+
+class PresetsApply : public BC_GenericButton
+{
+public:
+       PresetsApply(PresetsThread *thread,
+               PresetsWindow *window,
+               int x,
+               int y);
+       int handle_event();
+       PresetsThread *thread;
+       PresetsWindow *window;
+};
+
+class PresetsOK : public BC_OKButton
+{
+public:
+       PresetsOK(PresetsThread *thread,
+               PresetsWindow *window);
+       int keypress_event();
+       PresetsThread *thread;
+       PresetsWindow *window;
+};
+
+
+class PresetsWindow : public BC_Window
+{
+public:
+       PresetsWindow(MWindow *mwindow,
+               PresetsThread *thread,
+               int x,
+               int y,
+               char *title_string);
+
+       void create_objects();
+       int resize_event(int w, int h);
+
+       PresetsList *list;
+       PresetsText *title_text;
+       PresetsDelete *delete_button;
+       PresetsSave *save_button;
+       PresetsApply *apply_button;
+       BC_Title *title1;
+       BC_Title *title2;
+       MWindow *mwindow;
+       PresetsThread *thread;
+};
+
+
+
+#endif
+
+#endif
+
+
+
diff --git a/cinelerra-5.1/cinelerra/presetsgui.inc b/cinelerra-5.1/cinelerra/presetsgui.inc
new file mode 100644 (file)
index 0000000..688ec11
--- /dev/null
@@ -0,0 +1,33 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef PRESETSGUI_INC
+#define PRESETSGUI_INC
+
+
+class PresetsThread;
+class PresetsWindow;
+
+#endif
+
+
+
+
index 4cd0ae447824cf5dbd83393cd31685e49ad2c14e..3ea53a42ffa4a82da550707c819d252afc8c1ce1 100644 (file)
@@ -230,6 +230,8 @@ int Record::load_defaults()
        video_zoom = defaults->get("RECORD_VIDEO_Z", (float)1);
        picture->load_defaults();
        reverse_interlace = defaults->get("REVERSE_INTERLACE", 0);
+       do_cursor = defaults->get("RECORD_CURSOR", 0);
+       do_big_cursor = defaults->get("RECORD_BIG_CURSOR", 0);
        for( int i=0; i<MAXCHANNELS; ++i ) {
                sprintf(string, "RECORD_DCOFFSET_%d", i);
                dc_offset[i] = defaults->get(string, 0);
@@ -266,6 +268,8 @@ int Record::save_defaults()
        defaults->update("RECORD_VIDEO_Z", video_zoom);
        picture->save_defaults();
        defaults->update("REVERSE_INTERLACE", reverse_interlace);
+       defaults->update("RECORD_CURSOR", do_cursor);
+       defaults->update("RECORD_BIG_CURSOR", do_big_cursor);
        for( int i=0; i<MAXCHANNELS; ++i ) {
                sprintf(string, "RECORD_DCOFFSET_%d", i);
                defaults->update(string, dc_offset[i]);
@@ -401,7 +405,7 @@ void Record::run()
                        mwindow->undo->update_undo_before();
 // For pasting, clear the active region
                        if(load_mode == LOADMODE_PASTE)
-                               mwindow->clear(0);
+                               mwindow->clear(0, 1);
                        int loadmode = load_mode == LOADMODE_RESOURCESONLY ?
                                LOADMODE_ASSETSONLY : load_mode;
                        mwindow->paste_edls(&new_edls, loadmode, 0, -1,
@@ -437,9 +441,10 @@ void Record::run()
 void Record::stop(int wait)
 {
        stop_operation();
-       if( wait && running() )
+       if( record_gui )
                record_gui->set_done(1);
-       join();
+       if( wait )
+               join();
        window_lock->lock("Record::stop");
        delete record_thread;   record_thread = 0;
        delete record_monitor;  record_monitor = 0;
@@ -995,6 +1000,7 @@ void Record::open_video_input()
                master_channel->copy_usage(vdevice->channel);
                picture->copy_usage(vdevice->picture);
                vdevice->set_field_order(reverse_interlace);
+               vdevice->set_do_cursor(do_cursor, do_big_cursor);
                vdevice->set_adevice(adevice);
                if( adevice ) adevice->set_vdevice(vdevice);
                set_dev_channel(get_current_channel());
@@ -1207,11 +1213,15 @@ void Record::set_power_off(int value)
        record_gui->power_off->update(value);
 }
 
-int Record::set_video_picture()
+void Record::set_video_picture()
 {
        if( default_asset->video_data && vdevice )
                vdevice->set_picture(picture);
-       return 0;
+}
+
+void Record::set_do_cursor()
+{
+       vdevice->set_do_cursor(do_cursor, do_big_cursor);
 }
 
 void Record::set_translation(int x, int y)
index 423b4b09de07831e65994325406fa0ccc91720b6..d8fb0102cb2d5e9384ed3b813028abdea278837b 100644 (file)
@@ -147,7 +147,8 @@ public:
        void set_play_gain(double gain);
        void set_video_monitoring(int mode);
        void stop_operation();
-       int set_video_picture();
+       void set_video_picture();
+       void set_do_cursor();
 // Set screencapture translation
        void set_translation(int x, int y);
 
@@ -283,6 +284,9 @@ public:
        float video_zoom;
 // Reverse the interlace in the video window display only
        int reverse_interlace;
+// record the cursor for screencapture
+       int do_cursor;
+       int do_big_cursor;
 // Color model for uncompressed device interface
        int color_model;
 // Picture quality and parameters the device supports
index 00b257e9b930cb2e242c02ef132c97dcc2356a22..0b3810d861adb483028ae103f2ec09b9e3a60d0e 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -116,7 +116,6 @@ RecordGUI::RecordGUI(MWindow *mwindow, Record *record)
 
 RecordGUI::~RecordGUI()
 {
-TRACE("RecordGUI::~RecordGUI 1");
        delete status_thread;
        delete batch_source;
        delete batch_mode;
@@ -126,7 +125,6 @@ TRACE("RecordGUI::~RecordGUI 1");
        delete batch_start;
        delete batch_duration;
        delete load_mode;
-TRACE("RecordGUI::~RecordGUI 2");
 }
 
 
@@ -1612,5 +1610,3 @@ int RecordGUIResetTranslation::handle_event()
        return 1;
 }
 
-
-
index 40c18df15cd85dda129b9e7398374c5430fbb71d..4b506bd4a204d928a935b35c512923958264fc29 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c72317fb9be46168807e22250a8706c7d25260b6..b04587a7cb348a953a4f68879d9a09855a39b0ec 100644 (file)
@@ -79,55 +79,36 @@ void RecordMonitor::create_objects()
        mwindow->session->rwindow_fullscreen = 0;
 
        if( !record->default_asset->video_data )
-               min_w = MeterPanel::get_meters_width(
-                       mwindow->theme,
+               min_w = MeterPanel::get_meters_width(mwindow->theme,
                        record->default_asset->channels, 1);
 
-
-
-//SET_TRACE
        window = new RecordMonitorGUI(mwindow, record, this, min_w);
-//SET_TRACE
        window->create_objects();
-//SET_TRACE
 
        if( record->default_asset->video_data ) {
 // Configure the output for record monitoring
                VideoOutConfig config;
-//SET_TRACE
                device = new VideoDevice;
-//SET_TRACE
-
-
 
 // Override default device for X11 drivers
                if(mwindow->edl->session->playback_config->vconfig->driver ==
                        PLAYBACK_X11_XV) config.driver = PLAYBACK_X11_XV;
                config.x11_use_fields = 0;
-
-//SET_TRACE
-
                device->open_output(&config,
                        record->default_asset->frame_rate,
                        record->default_asset->width,
                        record->default_asset->height,
                        window->canvas, 0);
-//SET_TRACE
 
                scope_thread = new RecordScopeThread(mwindow, this);
 
-               if(mwindow->session->record_scope)
-               {
+               if(mwindow->session->record_scope) {
                        scope_thread->start();
                }
 
-
                thread = new RecordMonitorThread(mwindow, record, this);
-//SET_TRACE
                thread->start_playback();
-//SET_TRACE
        }
-//SET_TRACE
 
        Thread::start();
 }
@@ -273,6 +254,8 @@ RecordMonitorGUI::RecordMonitorGUI(MWindow *mwindow,
        reverse_interlace = 0;
        meters = 0;
        canvas = 0;
+       cursor_toggle = 0;
+       big_cursor_toggle = 0;
        current_operation = MONITOR_NONE;
        signal_status = 0;
 }
@@ -284,19 +267,15 @@ RecordMonitorGUI::~RecordMonitorGUI()
        delete signal_status;
 #endif
        delete canvas;
-       if( bitmap ) delete bitmap;
+       delete cursor_toggle;
+       delete big_cursor_toggle;
+       delete bitmap;
        if( channel_picker ) delete channel_picker;
 #ifdef HAVE_FIREWIRE
-       if( avc1394transport_thread )
-               delete avc1394transport_thread;
-       if( avc ) {
-               delete avc;
-       }
-       if( avc1394_transport ) {
-               delete avc1394_transport;
-       }
-       if( avc1394transport_title )
-               delete avc1394transport_title;
+       delete avc1394transport_thread;
+       delete avc;
+       delete avc1394_transport;
+       delete avc1394transport_title;
 #endif
        unlock_window();
 }
@@ -312,8 +291,9 @@ void RecordMonitorGUI::create_objects()
                        driver == VIDEO4LINUX2MPEG ||
                        driver == CAPTURE_JPEG_WEBCAM ||
                        driver == CAPTURE_YUYV_WEBCAM);
+       int do_cursor = driver == SCREENCAPTURE;
        int do_scopes = do_channel || driver == SCREENCAPTURE;
-       int do_interlace = (driver == VIDEO4LINUX2JPEG);
+       int do_interlace = driver == VIDEO4LINUX2JPEG;
        int background_done = 0;
        int do_audio = record->default_asset->audio_data;
        int do_video = record->default_asset->video_data;
@@ -399,13 +379,23 @@ void RecordMonitorGUI::create_objects()
                        x += reverse_interlace->get_w() + mwindow->theme->widget_border;
                }
 
-               if(do_scopes)
-               {
+               if( do_scopes ) {
                        scope_toggle = new ScopeEnable(mwindow, thread, x, y);
                        add_subwindow(scope_toggle);
                        x += scope_toggle->get_w() + mwindow->theme->widget_border;
                }
 
+               if( do_cursor ) {
+                       add_subwindow(cursor_toggle = new DoCursor(record,
+                               x, 
+                               y));
+                       x += cursor_toggle->get_w() + mwindow->theme->widget_border;
+                       add_subwindow(big_cursor_toggle = new DoBigCursor(record,
+                               x, 
+                               y));
+                       x += big_cursor_toggle->get_w() + mwindow->theme->widget_border;
+               }
+
                add_subwindow(monitor_menu = new BC_PopupMenu(0, 0, 0, "", 0));
                monitor_menu->add_item(new RecordMonitorFullsize(mwindow, this));
        }
@@ -469,10 +459,8 @@ int RecordMonitorGUI::button_release_event()
 
 int RecordMonitorGUI::cursor_motion_event()
 {
-//SET_TRACE
        if( canvas && canvas->get_canvas() ) {
                canvas->get_canvas()->unhide_cursor();
-//SET_TRACE
                return canvas->cursor_motion_event();
        }
        return 0;
@@ -588,11 +576,25 @@ int RecordMonitorGUI::resize_event(int w, int h)
        }
 #endif
 
-       if(channel_picker) channel_picker->reposition();
-       if(reverse_interlace) reverse_interlace->reposition_window(reverse_interlace->get_x(),
-               reverse_interlace->get_y());
-       if(canvas && do_video)
-       {
+       
+       if( channel_picker ) {
+               channel_picker->reposition();
+       }
+       if( reverse_interlace ) {
+               reverse_interlace->reposition_window(
+                       reverse_interlace->get_x(),
+                       reverse_interlace->get_y());
+       }
+       if( cursor_toggle ) {
+               cursor_toggle->reposition_window(
+                       cursor_toggle->get_x(),
+                       cursor_toggle->get_y());
+               big_cursor_toggle->reposition_window(
+                       big_cursor_toggle->get_x(),
+                       big_cursor_toggle->get_y());
+       }
+
+       if( canvas && do_video ) {
                canvas->reposition_window(0,
                        mwindow->theme->rmonitor_canvas_x,
                        mwindow->theme->rmonitor_canvas_y,
@@ -600,14 +602,14 @@ int RecordMonitorGUI::resize_event(int w, int h)
                        mwindow->theme->rmonitor_canvas_h);
        }
 
-       if(do_meters) {
+       if( do_meters ) {
                meters->reposition_window(mwindow->theme->rmonitor_meter_x,
                        mwindow->theme->rmonitor_meter_y,
                        do_video ? -1 : mwindow->theme->rmonitor_meter_w,
                        mwindow->theme->rmonitor_meter_h);
                meters->set_meters(record->default_asset->channels,1);
        }
-       else if(meters) {
+       else if( meters ) {
                meters->set_meters(0,0);
        }
 
@@ -665,6 +667,41 @@ int RecordMonitorGUI::create_bitmap()
        return 0;
 }
 
+
+DoCursor::DoCursor(Record *record, int x, int y)
+ : BC_CheckBox(x, y, record->do_cursor, _("Record cursor"))
+{
+       this->record = record;
+}
+
+DoCursor::~DoCursor()
+{
+}
+
+int DoCursor::handle_event()
+{
+       record->do_cursor = get_value();
+       return 0;
+}
+
+
+DoBigCursor::DoBigCursor(Record *record, int x, int y)
+ : BC_CheckBox(x, y, record->do_big_cursor, _("Big cursor"))
+{
+       this->record = record;
+}
+
+DoBigCursor::~DoBigCursor()
+{
+}
+
+int DoBigCursor::handle_event()
+{
+       record->do_big_cursor = get_value();
+       return 0;
+}
+
+
 void RecordMonitorGUI::enable_signal_status(int enable)
 {
 #ifdef HAVE_DVB
@@ -1079,7 +1116,9 @@ int RecordMonitorThread::render_frame()
 
 void RecordMonitorThread::new_output_frame()
 {
-       record_monitor->device->new_output_buffer(&output_frame, output_colormodel);
+       record_monitor->device->new_output_buffer(&output_frame, 
+               output_colormodel,
+               record->edl);
 }
 
 void RecordMonitorThread::
index ac3bd1d6a212f3149afee2e978eb8e2c0cee78e1..65bf732d078bfaa2bbcb4e34c5e48fffd53d7ccf 100644 (file)
@@ -86,6 +86,8 @@ public:
 
 class ReverseInterlace;
 class RecordMonitorCanvas;
+class DoCursor;
+class DoBigCursor;
 
 class RecordMonitorGUI : public BC_Window
 {
@@ -113,6 +115,8 @@ public:
 #endif
        RecordChannelPicker *channel_picker;
        ScopeEnable *scope_toggle;
+       DoCursor *cursor_toggle;
+       DoBigCursor *big_cursor_toggle;
        ReverseInterlace *reverse_interlace;
        int cursor_x_origin, cursor_y_origin;
        int translate_x_origin, translate_y_origin;
@@ -235,6 +239,24 @@ public:
        Record *record;
 };
 
+class DoCursor : public BC_CheckBox
+{
+public:
+       DoCursor(Record *record, int x, int y);
+       ~DoCursor();
+       int handle_event();
+       Record *record;
+};
+
+class DoBigCursor : public BC_CheckBox
+{
+public:
+       DoBigCursor(Record *record, int x, int y);
+       ~DoBigCursor();
+       int handle_event();
+       Record *record;
+};
+
 class ReverseInterlace : public BC_CheckBox
 {
 public:
index 6ff6182525c84b720a773f3b8241ede06b21bbaf..5851eb90995d279081e2e37d850703ab9ad3d0ac 100644 (file)
@@ -54,18 +54,21 @@ RecordPrefs::~RecordPrefs()
 
 void RecordPrefs::create_objects()
 {
-       int x, y, x2;
+       int x, y, x1, x2;
        char string[BCTEXTLEN];
        BC_Resources *resources = BC_WindowBase::get_resources();
        BC_Title *title;
+       BC_Title *title0, *title1, *title2, *title3;
+       BC_TextBox *textbox;
 
        x = mwindow->theme->preferencesoptions_x;
        y = mwindow->theme->preferencesoptions_y;
+       int margin = mwindow->theme->widget_border;
        int x0 = x, y0 = y;
 
        add_subwindow(title = new BC_Title(x, y, _("File Format:"),
                LARGEFONT, resources->text_default));
-       y += title->get_h() + 5;
+       y += title->get_h() + margin;
 
        recording_format = new FormatTools(mwindow, this,
                        pwindow->thread->edl->session->recording_format);
@@ -87,26 +90,24 @@ void RecordPrefs::create_objects()
        add_subwindow(realtime_toc);
 
 // Audio hardware
-       add_subwindow(new BC_Bar(5, y,  get_w() - 10));
-       y += 5;
+       add_subwindow(new BC_Bar(x, y,  get_w() - x * 2));
+       y += margin;
 
 
        add_subwindow(title = new BC_Title(x, y,
                _("Audio In"), LARGEFONT,
                resources->text_default));
 
-       y += title->get_h() + 5;
+       y += title->get_h() + margin;
 
        add_subwindow(new BC_Title(x, y, _("Record Driver:"),
                MEDIUMFONT, resources->text_default));
        audio_in_device = new ADevicePrefs(x + 110, y, pwindow, this, 0,
                pwindow->thread->edl->session->aconfig_in, MODERECORD);
        audio_in_device->initialize(1);
-       y += audio_in_device->get_h(1);
+       y += audio_in_device->get_h(1) + margin;
 
 
-       BC_TextBox *textbox;
-       BC_Title *title0, *title1, *title2, *title3;
        int pad = RecordWriteLength::calculate_h(this,
                MEDIUMFONT,
                1,
@@ -116,9 +117,9 @@ void RecordPrefs::create_objects()
        add_subwindow(title1 = new BC_Title(x, y + pad, _("Samples to write to disk:")));
        add_subwindow(title2 = new BC_Title(x, y + pad * 2, _("Sample rate for recording:")));
        add_subwindow(title3 = new BC_Title(x, y + pad * 3, _("Channels to record:")));
-       x2 = MAX(title0->get_w(), title1->get_w()) + mwindow->theme->widget_border;
-       x2 = MAX(x2, title2->get_w() + mwindow->theme->widget_border);
-       x2 = MAX(x2, title3->get_w() + mwindow->theme->widget_border);
+       x2 = MAX(title0->get_w(), title1->get_w()) + margin;
+       x2 = MAX(x2, title2->get_w() + margin);
+       x2 = MAX(x2, title3->get_w() + margin);
 
 
        sprintf(string, "%ld", (long)pwindow->thread->edl->session->record_fragment_size);
@@ -173,31 +174,36 @@ void RecordPrefs::create_objects()
 
 // Video hardware
        add_subwindow(new BC_Bar(5, y,  get_w() - 10));
-       y += 5;
+       y += margin;
 
-       add_subwindow(new BC_Title(x, y, _("Video In"), LARGEFONT,
+       add_subwindow(title1 = new BC_Title(x, y, _("Video In"), LARGEFONT,
                resources->text_default));
-       y += 25;
+       y += title1->get_h() + margin;
 
-       add_subwindow(new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT,
+       add_subwindow(title1 = new BC_Title(x, y, _("Record Driver:"), MEDIUMFONT,
                resources->text_default));
-       video_in_device = new VDevicePrefs(x + 110, y, pwindow, this, 0,
-               pwindow->thread->edl->session->vconfig_in, MODERECORD);
+       video_in_device = new VDevicePrefs(x + title1->get_w() + margin, y,
+               pwindow, this, 0, pwindow->thread->edl->session->vconfig_in, MODERECORD);
        video_in_device->initialize(1);
+       y += video_in_device->get_h() + margin;
 
-       y += 55;
+       add_subwindow(title1 = new BC_Title(x, y, _("Frames to record to disk at a time:")));
+       x1 = x + title1->get_w() + margin;
        sprintf(string, "%d", pwindow->thread->edl->session->video_write_length);
-       add_subwindow(textbox = new VideoWriteLength(pwindow, string, y));
-       add_subwindow(new CaptureLengthTumbler(pwindow, textbox, textbox->get_x() + textbox->get_w(), y));
-       add_subwindow(new BC_Title(x, y, _("Frames to record to disk at a time:")));
+       add_subwindow(textbox = new VideoWriteLength(pwindow, string, x1, y));
+       x1 += textbox->get_w() + margin;
+       add_subwindow(new CaptureLengthTumbler(pwindow, textbox, x1, y));
        y += 27;
+
+       add_subwindow(title1 = new BC_Title(x, y, _("Frames to buffer in device:")));
+       x1 = x + title1->get_w() + margin;
        sprintf(string, "%d", pwindow->thread->edl->session->vconfig_in->capture_length);
-       add_subwindow(textbox = new VideoCaptureLength(pwindow, string, y));
-       add_subwindow(new CaptureLengthTumbler(pwindow, textbox, textbox->get_x() + textbox->get_w(), y));
-       add_subwindow(new BC_Title(x, y, _("Frames to buffer in device:")));
+       add_subwindow(textbox = new VideoCaptureLength(pwindow, string, x1, y));
+       x1 += textbox->get_w() + margin;
+       add_subwindow(new CaptureLengthTumbler(pwindow, textbox, x1, y));
        y += 27;
 
-       int x1 = x;
+       x1 = x;
        add_subwindow(new BC_Title(x1, y, _("Positioning:")));
        x1 += 100;
        add_subwindow(textbox = new BC_TextBox(x1, y, 200, 1, ""));
@@ -212,23 +218,24 @@ void RecordPrefs::create_objects()
        y += 35;
 
        BC_TextBox *w_text, *h_text;
-       add_subwindow(new BC_Title(x, y, _("Size of captured frame:")));
-       x += 170;
+       add_subwindow(title1 = new BC_Title(x, y, _("Size of captured frame:")));
+       x += title1->get_w() + margin;
        add_subwindow(w_text = new RecordW(pwindow, x, y));
-       x += w_text->get_w() + 2;
-       add_subwindow(new BC_Title(x, y, "x"));
-       x += 10;
+       x += w_text->get_w() + margin;
+       add_subwindow(title1 = new BC_Title(x, y, "x"));
+       x += title1->get_w() + margin;
        add_subwindow(h_text = new RecordH(pwindow, x, y));
-       x += h_text->get_w();
-       add_subwindow(new FrameSizePulldown(mwindow->theme,
+       x += h_text->get_w() + margin;
+       FrameSizePulldown *tumbler;
+       add_subwindow(tumbler = new FrameSizePulldown(mwindow->theme, 
                w_text, h_text, x, y));
+       y += tumbler->get_h() + margin;
 
-       y += 30;
-       x = 5;
-       add_subwindow(new BC_Title(x, y, _("Frame rate for recording:")));
-       x += 180;
+       x = mwindow->theme->preferencesoptions_x;
+       add_subwindow(title1 = new BC_Title(x, y, _("Frame rate for recording:")));
+       x += title1->get_w() + margin;
        add_subwindow(textbox = new RecordFrameRate(pwindow, x, y));
-       x += 75;
+       x += textbox->get_w() + margin;
        add_subwindow(new FrameRatePulldown(mwindow, textbox, x, y));
 
 }
@@ -377,7 +384,7 @@ int RecordH::handle_event()
 }
 
 RecordFrameRate::RecordFrameRate(PreferencesWindow *pwindow, int x, int y)
- : BC_TextBox(x, y, 70, 1, pwindow->thread->edl->session->vconfig_in->in_framerate)
+ : BC_TextBox(x, y, 140, 1, pwindow->thread->edl->session->vconfig_in->in_framerate)
 {
        this->pwindow = pwindow;
 }
@@ -420,8 +427,8 @@ int RecordGain::handle_event()
 
 
 
-VideoWriteLength::VideoWriteLength(PreferencesWindow *pwindow, char *text, int y)
- : BC_TextBox(260, y, 100, 1, text)
+VideoWriteLength::VideoWriteLength(PreferencesWindow *pwindow, char *text, int x, int y)
+ : BC_TextBox(x, y, 100, 1, text)
 {
        this->pwindow = pwindow;
 }
@@ -433,8 +440,8 @@ int VideoWriteLength::handle_event()
 }
 
 
-VideoCaptureLength::VideoCaptureLength(PreferencesWindow *pwindow, char *text, int y)
- : BC_TextBox(260, y, 100, 1, text)
+VideoCaptureLength::VideoCaptureLength(PreferencesWindow *pwindow, char *text, int x, int y)
+ : BC_TextBox(x, y, 100, 1, text)
 {
        this->pwindow = pwindow;
 }
index e8dbd4378d4ae155b9435dd0f8da84658e5b6af7..81f6fe88ff5c4029e93fe2e5a7edf55010afaca0 100644 (file)
@@ -138,7 +138,7 @@ public:
 class VideoWriteLength : public BC_TextBox
 {
 public:
-       VideoWriteLength(PreferencesWindow *pwindow, char *text, int y);
+       VideoWriteLength(PreferencesWindow *pwindow, char *text, int x, int y);
        int handle_event();
        PreferencesWindow *pwindow;
 };
@@ -146,7 +146,7 @@ public:
 class VideoCaptureLength : public BC_TextBox
 {
 public:
-       VideoCaptureLength(PreferencesWindow *pwindow, char *text, int y);
+       VideoCaptureLength(PreferencesWindow *pwindow, char *text, int x, int y);
        int handle_event();
        PreferencesWindow *pwindow;
 };
index 7004d45447ce9a5805239389f59dc2b51164ef96..65f50b1e8ded9334e65e0d9872df8725e6c3c8cf 100644 (file)
@@ -21,7 +21,7 @@
 
 
 #include "bctheme.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "language.h"
 #include "mainsession.h"
 #include "mutex.h"
index 2abd343a564fddb34cf6f68bf1b928b24a3f3884..91b5971b3e58e9e99f7fef6938a77d18f8d5f65c 100644 (file)
@@ -196,6 +196,7 @@ void RecordVideo::run()
                VideoDevice *vdevice = record->vdevice;
                VFrame *capture_frame = get_buffer();
                vdevice->set_field_order(record->reverse_interlace);
+               record->set_do_cursor();
 // Capture a frame
                grab_result = read_buffer(capture_frame);
                if( done ) break;
index 9f24048fab2b1275bf518edb14b48c2fab208727..1452c0e06dbf753b39a6abf00f81cc350db0ecf2 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b668e9788830d49db74d963a34d9846e219e9d8d..1fa93d9c215b5658565ddc1401ad17729fd43d29 100644 (file)
@@ -1,5 +1,5 @@
 
-#include "colors.h"
+#include "bccolors.h"
 #include "mainsession.h"
 #include "mwindow.h"
 #include "mwindowgui.h"
index 085384ae9b8ad3f2b165062f349897ff53acb7b3..702ffbd4028074d56362efbc0b87f7334efe6128 100644 (file)
@@ -970,7 +970,7 @@ if(debug) printf("Render::render %d\n", __LINE__);
                ArrayList<Indexable*> *assets = render->packages->get_asset_list();
 if(debug) printf("Render::render %d\n", __LINE__);
                if(render->load_mode == LOADMODE_PASTE)
-                       mwindow->clear(0);
+                       mwindow->clear(0, 1);
 if(debug) printf("Render::render %d\n", __LINE__);
                mwindow->load_assets(assets, -1, render->load_mode, 0, 0,
                        mwindow->edl->session->labels_follow_edits,
index 936bd4d5ef5755b377a3e2c203e5beb4dd4a787c..8b3bc74a9a062552e05969ba48289ef4476752dd 100644 (file)
@@ -130,7 +130,7 @@ int Save::save_before_quit()
 }
 
 SaveAs::SaveAs(MWindow *mwindow)
- : BC_MenuItem(_("Save as..."), ""), Thread()
+ : BC_MenuItem(_("Save as..."), "Shift-S", 'S'), Thread()
 {
        this->mwindow = mwindow;
        quit_now = 0;
index fb3c01980491b9119197de8d4fb6488a7a3b2a9b..56dd5171319b96c809f6eacf76fcca9835b356a9 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include "bcsignals.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "clip.h"
 #include "cursors.h"
 #include "language.h"
index 7963fa34bb233b8ffbc261b0b9280748eff547a1..8e22161869f5a5b910519cb01459ae33da28325b 100644 (file)
@@ -1,7 +1,7 @@
 #ifdef HAVE_DVB
 
 #include "bctitle.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "devicedvbinput.h"
 #include "fonts.h"
 #include "signalstatus.h"
index 8d06c956db11e744cca0d6c0643a470eb866ba27..929eb7eca96297682a603d683d6a48611cac22b5 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "bcwindow.h"
 #include "bcsignals.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "thread.h"
 
index 20f8b36b886301020b19243196a03e73e2320308..bddba8783277c220524e45b5d42fdb5577a5ef93 100644 (file)
@@ -22,7 +22,7 @@
 #include "awindowgui.h"
 #include "bcsignals.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "cwindowgui.h"
 #include "edl.h"
 #include "edlsession.h"
@@ -85,6 +85,7 @@ Theme::Theme()
        play_h = 22;
        title_h = 23;
        clock_bg_color = BLACK;
+       clock_fg_color = GREEN;
        assetedit_color = YELLOW;
        const char *cp = getenv("BC_USE_COMMERCIALS");
        use_commercials = !cp ? 0 : atoi(cp);
@@ -264,43 +265,20 @@ void Theme::build_menus()
 
        frame_sizes.append(new BC_ListBoxItem("128x96"));
        frame_sizes.append(new BC_ListBoxItem("160x120"));
-       frame_sizes.append(new BC_ListBoxItem("176x144"));
-       frame_sizes.append(new BC_ListBoxItem("240x180"));
-       frame_sizes.append(new BC_ListBoxItem("320x200"));
        frame_sizes.append(new BC_ListBoxItem("320x240"));
-       frame_sizes.append(new BC_ListBoxItem("352x288"));
        frame_sizes.append(new BC_ListBoxItem("360x240"));
        frame_sizes.append(new BC_ListBoxItem("400x300"));
-       frame_sizes.append(new BC_ListBoxItem("424x318"));
-       frame_sizes.append(new BC_ListBoxItem("512x384"));
-       frame_sizes.append(new BC_ListBoxItem("640x350"));
+       frame_sizes.append(new BC_ListBoxItem("640x400"));
        frame_sizes.append(new BC_ListBoxItem("640x480"));
-       frame_sizes.append(new BC_ListBoxItem("704x576"));
        frame_sizes.append(new BC_ListBoxItem("720x480"));
-       frame_sizes.append(new BC_ListBoxItem("720x576"));
        frame_sizes.append(new BC_ListBoxItem("800x600"));
-       frame_sizes.append(new BC_ListBoxItem("852x480"));
-       frame_sizes.append(new BC_ListBoxItem("852x480"));
-       frame_sizes.append(new BC_ListBoxItem("960x540"));
-       frame_sizes.append(new BC_ListBoxItem("960x1080"));
        frame_sizes.append(new BC_ListBoxItem("1024x768"));
        frame_sizes.append(new BC_ListBoxItem("1280x720"));
        frame_sizes.append(new BC_ListBoxItem("1280x1024"));
-       frame_sizes.append(new BC_ListBoxItem("1368x768"));
-       frame_sizes.append(new BC_ListBoxItem("1408x1152"));
-       frame_sizes.append(new BC_ListBoxItem("1600x1024"));
        frame_sizes.append(new BC_ListBoxItem("1600x1200"));
        frame_sizes.append(new BC_ListBoxItem("1920x1080"));
-       frame_sizes.append(new BC_ListBoxItem("1920x1088"));
-       frame_sizes.append(new BC_ListBoxItem("1920x1200"));
-       frame_sizes.append(new BC_ListBoxItem("2048x1536"));
-       frame_sizes.append(new BC_ListBoxItem("2560x1600"));
-       frame_sizes.append(new BC_ListBoxItem("2560x2048"));
-       frame_sizes.append(new BC_ListBoxItem("3200x2048"));
-       frame_sizes.append(new BC_ListBoxItem("3840x2400"));
-       frame_sizes.append(new BC_ListBoxItem("5120x4096"));
-       frame_sizes.append(new BC_ListBoxItem("6400x4096"));
-       frame_sizes.append(new BC_ListBoxItem("7680x4800"));
+       frame_sizes.append(new BC_ListBoxItem("3840x2160"));
+       frame_sizes.append(new BC_ListBoxItem("4096x1720"));
 
        sample_rates.append(new BC_ListBoxItem("8000"));
        sample_rates.append(new BC_ListBoxItem("16000"));
@@ -311,6 +289,7 @@ void Theme::build_menus()
        sample_rates.append(new BC_ListBoxItem("96000"));
        sample_rates.append(new BC_ListBoxItem("192000"));
 
+       frame_rates.append(new BC_ListBoxItem("0.25"));
        frame_rates.append(new BC_ListBoxItem("1"));
        frame_rates.append(new BC_ListBoxItem("5"));
        frame_rates.append(new BC_ListBoxItem("10"));
@@ -324,6 +303,9 @@ void Theme::build_menus()
        frame_rates.append(new BC_ListBoxItem("50"));
        frame_rates.append(new BC_ListBoxItem("59.94"));
        frame_rates.append(new BC_ListBoxItem("60"));
+       frame_rates.append(new BC_ListBoxItem("100"));
+       frame_rates.append(new BC_ListBoxItem("120"));
+       frame_rates.append(new BC_ListBoxItem("1000"));
 
        char string[BCTEXTLEN];
        for(int i = 1; i < 17; i++)
@@ -592,9 +574,9 @@ void Theme::get_mwindow_sizes(MWindowGUI *gui, int w, int h)
        mbuttons_y = gui->menu_h() + 1;
        mbuttons_w = gui->menu_w();
        mbuttons_h = get_image("mbutton_bg")->get_h();
-       mclock_x = 10;
-       mclock_y = mbuttons_y - 1 + mbuttons_h + widget_border;
-       mclock_w = get_image("clock_bg")->get_w() - 40;
+       mclock_x = window_border - 5;
+       mclock_y = mbuttons_y - 1 + mbuttons_h;
+       mclock_w = get_image("clock_bg")->get_w() - 20;
        mclock_h = get_image("clock_bg")->get_h();
        mtimebar_x = get_image("patchbay_bg")->get_w();
        mtimebar_y = mbuttons_y - 1 + mbuttons_h;
@@ -1175,40 +1157,106 @@ void Theme::get_plugindialog_sizes()
 
 void Theme::get_keyframedialog_sizes(KeyFrameWindow *gui)
 {
-       int x = widget_border;
-       int y = window_border +
-               BC_Title::calculate_h(gui, "P", LARGEFONT) +
+       int x = window_border;
+       int y = window_border + 
+               BC_Title::calculate_h(gui, "P", LARGEFONT) + 
+               widget_border;
+
+       presets_list_x = x;
+       presets_list_y = y;
+#ifdef EDIT_KEYFRAME
+       presets_list_w = mwindow->session->keyframedialog_w / 2 - 
+               widget_border - 
+               window_border;
+#else
+       presets_list_w = mwindow->session->keyframedialog_w - 
+               presets_list_x -
+               window_border;
+#endif
+       presets_list_h = mwindow->session->keyframedialog_h - 
+               BC_OKButton::calculate_h() - 
+               presets_list_y -
+               widget_border -
+               widget_border -
+               BC_Title::calculate_h(gui, "P") - 
+               widget_border -
+               BC_TextBox::calculate_h(gui, 
+                       MEDIUMFONT, 
+                       1, 
+                       1) -
+               widget_border -
+               (BC_GenericButton::calculate_h() + widget_border) * 3 - 
+               window_border;
+       y += presets_list_h + widget_border + widget_border + BC_Title::calculate_h(gui, "P");
+       presets_text_x = x;
+       presets_text_y = y;
+       presets_text_w = presets_list_w;
+       y += BC_TextBox::calculate_h(gui, 
+               MEDIUMFONT, 
+               1, 
+               1) + widget_border;
+
+       presets_delete_x = presets_text_x;
+       presets_delete_y = y;
+       y += BC_GenericButton::calculate_h() + widget_border;
+
+       presets_save_x = presets_text_x;
+       presets_save_y = y;
+       y += BC_GenericButton::calculate_h() + widget_border;
+
+       presets_apply_x = presets_text_x;
+       presets_apply_y = y;
+       y += BC_GenericButton::calculate_h();
+
+#ifdef EDIT_KEYFRAME
+       x = mwindow->session->keyframedialog_w / 2 + widget_border;
+       y = window_border + 
+               BC_Title::calculate_h(gui, "P", LARGEFONT) + 
                widget_border;
 
        keyframe_list_x = x;
        keyframe_list_y = y;
-       keyframe_list_w = mwindow->session->keyframedialog_w - widget_border * 2;
-       keyframe_list_h = mwindow->session->keyframedialog_h - widget_border -
-               widget_border - keyframe_list_y - BC_Title::calculate_h(gui, "P") -
-               widget_border - BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1) -
-               widget_border - BC_Title::calculate_h(gui, "P") -
-               widget_border - BC_OKButton::calculate_h() -
+       keyframe_list_w = mwindow->session->keyframedialog_w / 2 - 
+               widget_border - 
+               window_border;
+       keyframe_list_h = mwindow->session->keyframedialog_h - 
+               keyframe_list_y -
+               widget_border -
+               widget_border -
+               BC_Title::calculate_h(gui, "P") -
+               widget_border - 
+               BC_TextBox::calculate_h(gui,
+                       MEDIUMFONT,
+                       1,
+                       1) -
+               widget_border - 
+               BC_Title::calculate_h(gui, "P") -
+               widget_border -
+               BC_OKButton::calculate_h() - 
                window_border;
 //     keyframe_text_x = keyframe_list_x + keyframe_list_w + widget_border;
 //     keyframe_text_y = y;
 //     keyframe_text_w = mwindow->session->keyframedialog_w - keyframe_text_x - window_border;
-//     y += BC_TextBox::calculate_h(gui,
-//             MEDIUMFONT,
-//             1,
+//     y += BC_TextBox::calculate_h(gui, 
+//             MEDIUMFONT, 
+//             1, 
 //             1) + widget_border;
-//
+// 
 
        y += keyframe_list_h + BC_Title::calculate_h(gui, "P") + widget_border + widget_border;
        keyframe_value_x = keyframe_list_x;
        keyframe_value_y = y;
        keyframe_value_w = keyframe_list_w;
-       y += BC_TextBox::calculate_h(gui,
-               MEDIUMFONT,
-               1,
+       y += BC_TextBox::calculate_h(gui, 
+               MEDIUMFONT, 
+               1, 
                1) + widget_border;
 
        keyframe_all_x = keyframe_value_x;
        keyframe_all_y = y;
+
+#endif
+
 }
 
 
index 06cb17a7fbacacdbfcf2ca4b8e1b6d5988150a11..009f396f5574ce2cd6a2f449a156b2a75052e468 100644 (file)
@@ -237,6 +237,12 @@ public:
        int plugindialog_sharedattach_x, plugindialog_sharedattach_y;
        int plugindialog_moduleattach_x, plugindialog_moduleattach_y;
 
+       int presets_list_x, presets_list_y, presets_list_w, presets_list_h;
+       int presets_text_x, presets_text_y, presets_text_w;
+       int presets_delete_x, presets_delete_y;
+       int presets_save_x, presets_save_y;
+       int presets_apply_x, presets_apply_y;
+
        int keyframe_list_x, keyframe_list_y, keyframe_list_w, keyframe_list_h;
        int keyframe_text_x, keyframe_text_y, keyframe_text_w, keyframe_text_h;
        int keyframe_value_x, keyframe_value_y, keyframe_value_w, keyframe_value_h;
@@ -287,6 +293,7 @@ public:
        int window_border;
        int widget_border;
        int clock_bg_color;
+       int clock_fg_color;
        int use_commercials;
 
 // Bitmaps
index ae7d10491daa4149a71f7221b278d13b625e4b94..f3852cf90e5bab5308e9383aeb29324dbb061a15 100644 (file)
@@ -1150,17 +1150,9 @@ int Track::copy_assets(double start,
 }
 
 
-
-
-
-int Track::clear(double start,
-       double end,
-       int edit_edits,
-       int edit_labels,
-       int edit_plugins,
-       int edit_autos,
-       int convert_units,
-       Edits *trim_edits)
+int Track::clear(double start, double end,
+       int edit_edits, int edit_labels, int edit_plugins,
+       int edit_autos, int convert_units, Edits *trim_edits)
 {
 // Edits::move_auto calls this routine after the units are converted to the track
 // format.
index 740dea55b294ca7e6aa0c1024b1f92fd78e09898..feff8a858d5df154b48f02d64a89c4ee68c0e56d 100644 (file)
@@ -26,7 +26,7 @@
 #include "bcsignals.h"
 #include "bctimer.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "cplayback.h"
 #include "cursors.h"
 #include "cwindowgui.h"
@@ -4431,7 +4431,7 @@ int TrackCanvas::do_tracks(int cursor_x, int cursor_y, int button_press)
                int64_t track_x, track_y, track_w, track_h;
                track_dimensions(track, track_x, track_y, track_w, track_h);
 
-               if(button_press && get_buttonpress() == 3 &&
+               if(button_press && get_buttonpress() == RIGHT_BUTTON &&
                        cursor_y >= track_y && cursor_y < track_y + track_h) {
                        gui->edit_menu->update(track, 0);
                        gui->edit_menu->activate_menu();
index 971a005f215f730e82672f9f85685fdcaa4ef0ea..9fdf4f63fd66d4df71f2ea04d151971f09979c9a 100644 (file)
@@ -61,10 +61,10 @@ int Tracks::clear(double start, double end, int clear_plugins, int edit_autos)
                                end,
                                1, // edits
                                1, // labels
-                               clear_plugins,
+                               clear_plugins, // edit_plugins
                                edit_autos,
-                               1,
-                               0);
+                               1, // convert_units
+                               0); // trim_edits
                }
        }
        return 0;
index 70df4e741a6d449dc0edd0bf092a952315545cab..0197fa4df2c00c767566361b1ccee627634f62c4 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "floatauto.h"
index c61387c95981705b5d597b991c4bb307526169f3..8f3872e71d02421198ec019b778abcb0ea11bd12 100644 (file)
@@ -234,7 +234,8 @@ int VDevice1394::read_buffer(VFrame *frame)
 
 
 void VDevice1394::new_output_buffer(VFrame **output,
-       int colormodel)
+       int colormodel,
+       EDL *edl)
 {
        if(user_frame)
        {
index 9ca35612eb5f6cd23cb840fb02a9825f49d8c7f4..14927e4bbd70377f1851c7e62d9fff8411518d9c 100644 (file)
@@ -53,7 +53,7 @@ public:
        void initialize();
        int can_copy_from(Asset *asset, int output_w, int output_h);
 //     int stop_sharing();
-       void new_output_buffer(VFrame **output, int colormodel);
+       void new_output_buffer(VFrame **output, int colormodel, EDL *edl);
        void encrypt(unsigned char *output, unsigned char *data, int data_size);
 
 private:
index ba29bea4afd526d7014e7ee740751daf54c64aff..4b388f53b0aa2764da2a398bce3d26fb060d3458 100644 (file)
@@ -45,7 +45,7 @@ public:
        virtual int create_channeldb(ArrayList<Channel*> *channeldb) { return 1; };
        virtual int read_buffer(VFrame *frame) { return 1; };
        virtual int write_buffer(VFrame *output, EDL *edl) { return 1; };
-       virtual void new_output_buffer(VFrame **output, int colormodel) {};
+       virtual void new_output_buffer(VFrame **output, int colormodel, EDL *edl) {};
        virtual ArrayList<int>* get_render_strategies() { return 0; };
        virtual int get_shared_data(unsigned char *data, long size) { return 0; };
        virtual int stop_sharing() { return 0; };
index beada6050ff70d34815a5576f7475d96860097a0..d20c0587b02098513e0cf222fe0b03750dd6e9a7 100644 (file)
@@ -22,6 +22,7 @@
 #include "bcsignals.h"
 #include "channeldb.h"
 #include "channelpicker.h"
+#include "clip.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "formattools.h"
@@ -37,6 +38,7 @@
 #include "preferencesthread.h"
 #include "recordconfig.h"
 #include "recordprefs.h"
+#include "theme.h"
 #include <string.h>
 
 
@@ -94,6 +96,7 @@ void VDevicePrefs::reset_objects()
        firewire_path = 0;
        fields_title = 0;
        device_fields = 0;
+       use_direct_x11 = 0;
 
        channel_picker = 0;
 }
@@ -181,6 +184,7 @@ int VDevicePrefs::delete_objects()
        delete dvb_adapter_device;
        delete follow_video_config;
        delete dvb_adapter_title;
+       delete use_direct_x11;
 
        delete port_title;
 
@@ -198,6 +202,13 @@ int VDevicePrefs::delete_objects()
        return 0;
 }
 
+int VDevicePrefs::get_h()
+{
+       int margin = pwindow->mwindow->theme->widget_border;
+       return BC_Title::calculate_h(dialog, "X", MEDIUMFONT) + margin +
+               BC_TextBox::calculate_h(dialog, MEDIUMFONT, 1, 1);
+}
+
 void VDevicePrefs::create_dvb_objs()
 {
        int x1 = x + menu->get_w() + 30;
@@ -332,7 +343,7 @@ int VDevicePrefs::create_v4l2jpeg_objs()
        char *output_char = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_device[0];
        dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
        dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
-       x1 += max(device_title->get_w(),device_text->get_w()) + 5;
+       x1 += bmax(device_title->get_w(),device_text->get_w()) + 5;
        int *output_int = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_fields;
        fields_title = new BC_Title(x1, y, _("Fields:"), MEDIUMFONT, resources->text_default);
        dialog->add_subwindow(fields_title);
@@ -373,7 +384,6 @@ int VDevicePrefs::create_x11_objs()
 {
        char *output_char;
        BC_Resources *resources = BC_WindowBase::get_resources();
-       int x1 = x + menu->get_w() + 5;
        output_char = out_config->x11_host;
        const char *x11_display;
        switch( pwindow->thread->current_dialog ) {
@@ -385,9 +395,21 @@ int VDevicePrefs::create_x11_objs()
                x11_display = _("Default B Display:");  break;
                break;
        }
-       dialog->add_subwindow(device_title = new BC_Title(x1, y, x11_display,
+       int x1 = menu->get_x() + menu->get_w() + 10;
+       int y1 = menu->get_y();
+       if( driver == PLAYBACK_X11 ) y1 -= 10;
+       dialog->add_subwindow(device_title = new BC_Title(x1, y1+4, x11_display,
                        MEDIUMFONT, resources->text_default));
-       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+       int x2 = x1 + device_title->get_w() + 10, dy = device_title->get_h();
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x2, y1, output_char));
+       if( driver == PLAYBACK_X11 ) {
+               int y2 = device_text->get_h();
+               if( dy < y2 ) dy = y2;
+               y1 += dy + 5;
+               use_direct_x11 = new BC_CheckBox(x1, y1,
+                       &out_config->use_direct_x11, _("use direct x11 render if possible"));
+               dialog->add_subwindow(use_direct_x11);
+       }
        return 0;
 }
 
index 06c1fa84f52170c8313981b2ecdbaf5ef06eae96..c29d932535434533598d3cbf0e3e527d74f92c9e 100644 (file)
@@ -61,7 +61,7 @@ public:
        int initialize(int creation /* = 0 */);
        int delete_objects();
        void reset_objects();
-       static int max(int a,int b) { return a>b ? a : b; }
+       int get_h();
 
        PreferencesWindow *pwindow;
        PreferencesDialog *dialog;
@@ -84,6 +84,7 @@ private:
        BC_Title *device_title;
        BC_Title *port_title;
        BC_CheckBox *follow_video_config;
+       BC_CheckBox *use_direct_x11;
        BC_Title *channel_title;
        BC_Title *output_title;
        BC_Title *syt_title;
index 31873e6a4c1b79d7687cc8231f27798baf5e64c5..793047ac184c065e6a053f2a76cff5bec546af71 100644 (file)
@@ -1,35 +1,37 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
+ * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
+ * 
  */
 
 #include "assets.h"
-#include "auto.h"
+#include "autos.h"
 #include "bccapture.h"
+#include "bccmodels.h"
 #include "bcsignals.h"
 #include "canvas.h"
-#include "bccmodels.h"
 #include "edl.h"
 #include "edlsession.h"
-#include "maskautos.h"
+#include "file.h"
 #include "maskauto.h"
+#include "maskautos.h"
 #include "mwindow.h"
+#include "mwindowgui.h"
 #include "playback3d.h"
 #include "playbackconfig.h"
 #include "preferences.h"
@@ -75,34 +77,66 @@ int VDeviceX11::reset_parameters()
        capture_bitmap = 0;
        color_model_selected = 0;
        is_cleared = 0;
+
+       for( int i = 0; i < SCREENCAP_BORDERS; i++ ) {
+               screencap_border[i] = 0;
+       }
        return 0;
 }
 
 int VDeviceX11::open_input()
 {
 //printf("VDeviceX11::open_input 1\n");
-       capture_bitmap = new BC_Capture(device->in_config->w,
+       capture_bitmap = new BC_Capture(device->in_config->w, 
                device->in_config->h,
                device->in_config->screencapture_display);
 //printf("VDeviceX11::open_input 2\n");
 
+// create overlay
+       device->mwindow->gui->lock_window("VDeviceX11::close_all");
+
+       screencap_border[0] = new BC_Popup(device->mwindow->gui, 
+                       device->input_x - SCREENCAP_PIXELS, device->input_y - SCREENCAP_PIXELS,
+                       device->in_config->w + SCREENCAP_PIXELS * 2, SCREENCAP_PIXELS,
+                       SCREENCAP_COLOR, 1);
+       screencap_border[1] = new BC_Popup(device->mwindow->gui, 
+                       device->input_x - SCREENCAP_PIXELS, device->input_y,
+                       SCREENCAP_PIXELS, device->in_config->h,
+                       SCREENCAP_COLOR, 1);
+       screencap_border[2] = new BC_Popup(device->mwindow->gui, 
+                       device->input_x - SCREENCAP_PIXELS, device->input_y + device->in_config->h,
+                       device->in_config->w + SCREENCAP_PIXELS * 2, SCREENCAP_PIXELS,
+                       SCREENCAP_COLOR, 1);
+       screencap_border[3] = new BC_Popup(device->mwindow->gui, 
+                       device->input_x + device->in_config->w, device->input_y,
+                       SCREENCAP_PIXELS, device->in_config->h,
+                       SCREENCAP_COLOR, 1);
+
+       for( int i=0; i<SCREENCAP_BORDERS; ++i ) {
+               BC_Popup *box = screencap_border[i];
+               box->set_bg_color(SCREENCAP_COLOR);
+               box->clear_box(0, 0, box->get_w(), box->get_h());
+               box->flash(0);
+               box->show_window();
+       }
+
+       device->mwindow->gui->unlock_window();
+
        return 0;
 }
 
 int VDeviceX11::open_output()
 {
-       if(output)
-       {
+       if( output ) {
                output->lock_canvas("VDeviceX11::open_output");
                output->get_canvas()->lock_window("VDeviceX11::open_output");
-               if(!device->single_frame)
+               if( !device->single_frame )
                        output->start_video();
                else
                        output->start_single();
                output->get_canvas()->unlock_window();
 
 // Enable opengl in the first routine that needs it, to reduce the complexity.
-
                output->unlock_canvas();
        }
        return 0;
@@ -111,16 +145,14 @@ int VDeviceX11::open_output()
 
 int VDeviceX11::output_visible()
 {
-       if(!output) return 0;
+       if( !output ) return 0;
 
        output->lock_canvas("VDeviceX11::output_visible");
-       if(output->get_canvas()->get_hidden())
-       {
+       if( output->get_canvas()->get_hidden() ) {
                output->unlock_canvas();
-               return 0;
+               return 0; 
        }
-       else
-       {
+       else {
                output->unlock_canvas();
                return 1;
        }
@@ -129,46 +161,27 @@ int VDeviceX11::output_visible()
 
 int VDeviceX11::close_all()
 {
-       if(output)
-       {
+       if( output ) {
                output->lock_canvas("VDeviceX11::close_all 1");
                output->get_canvas()->lock_window("VDeviceX11::close_all 1");
        }
 
-       if(output && output_frame)
-       {
+       if( output && output_frame ) {
                output->update_refresh(device, output_frame);
                if( device->single_frame )
                        output->draw_refresh();
        }
 
+       delete bitmap;          bitmap = 0;
+       delete output_frame;    output_frame = 0;
+       delete capture_bitmap;  capture_bitmap = 0;
 
-
-
-       if(bitmap)
-       {
-               delete bitmap;
-               bitmap = 0;
-       }
-
-       if(output_frame)
-       {
-               delete output_frame;
-               output_frame = 0;
-       }
-
-       if(capture_bitmap) delete capture_bitmap;
-
-       if(output)
-       {
-
+       if( output ) {
 // Update the status bug
-               if(!device->single_frame)
-               {
+               if( !device->single_frame ) {
                        output->stop_video();
                }
-               else
-               {
+               else {
                        output->stop_single();
                }
 
@@ -176,78 +189,100 @@ int VDeviceX11::close_all()
                output->unlock_canvas();
        }
 
-
+       if( device->mwindow ) {
+               device->mwindow->gui->lock_window("VDeviceX11::close_all");
+               for( int i=0; i<SCREENCAP_BORDERS; ++i ) {
+                       delete screencap_border[i];
+                       screencap_border[i] = 0;
+               }
+               device->mwindow->gui->unlock_window();
+       }
+       
        reset_parameters();
+
        return 0;
 }
 
 int VDeviceX11::read_buffer(VFrame *frame)
 {
-       capture_bitmap->capture_frame(frame, device->input_x, device->input_y);
+//printf("VDeviceX11::read_buffer %d colormodel=%d\n", __LINE__, frame->get_color_model());
+       device->mwindow->gui->lock_window("VDeviceX11::close_all");
+
+       screencap_border[0]->reposition_window(device->input_x - SCREENCAP_PIXELS,
+                       device->input_y - SCREENCAP_PIXELS);
+       screencap_border[1]->reposition_window(device->input_x - SCREENCAP_PIXELS,
+                       device->input_y);
+       screencap_border[2]->reposition_window(device->input_x - SCREENCAP_PIXELS,
+                       device->input_y + device->in_config->h);
+       screencap_border[3]->reposition_window(device->input_x + device->in_config->w,
+                       device->input_y);
+       device->mwindow->gui->flush();
+       device->mwindow->gui->unlock_window();
+
+
+       capture_bitmap->capture_frame(frame, 
+               device->input_x, device->input_y, device->do_cursor);
        return 0;
 }
 
 
 int VDeviceX11::get_best_colormodel(Asset *asset)
 {
-       return BC_RGB888;
+       return File::get_best_colormodel(asset, SCREENCAPTURE);
+//     return BC_RGB888;
 }
 
 
-int VDeviceX11::get_best_colormodel(int colormodel)
+int VDeviceX11::get_display_colormodel(int file_colormodel)
 {
        int result = -1;
 
-       if(device->out_config->driver == PLAYBACK_X11_GL)
-       {
-               if(colormodel == BC_RGB888 ||
-                       colormodel == BC_RGBA8888 ||
-                       colormodel == BC_YUV888 ||
-                       colormodel == BC_YUVA8888 ||
-                       colormodel == BC_RGB_FLOAT ||
-                       colormodel == BC_RGBA_FLOAT)
-               {
-                       return colormodel;
+       if( device->out_config->driver == PLAYBACK_X11_GL ) {
+               if( file_colormodel == BC_RGB888 ||
+                       file_colormodel == BC_RGBA8888 ||
+                       file_colormodel == BC_YUV888 ||
+                       file_colormodel == BC_YUVA8888 ||
+                       file_colormodel == BC_RGB_FLOAT ||
+                       file_colormodel == BC_RGBA_FLOAT ) {
+                       return file_colormodel;
                }
+               
                return BC_RGB888;
        }
 
-       if(!device->single_frame)
-       {
-               switch(colormodel)
-               {
-                       case BC_YUV420P:
-                       case BC_YUV422P:
-                       case BC_YUV422:
-                               result = colormodel;
-                               break;
+       if( !device->single_frame ) {
+               switch( file_colormodel ) {
+               case BC_YUV420P:
+               case BC_YUV422P:
+               case BC_YUV422:
+                       result = file_colormodel;
+                       break;
                }
        }
 
 // 2 more colormodels are supported by OpenGL
-       if(device->out_config->driver == PLAYBACK_X11_GL)
-       {
-               if(colormodel == BC_RGB_FLOAT ||
-                       colormodel == BC_RGBA_FLOAT)
-                       result = colormodel;
+       if( device->out_config->driver == PLAYBACK_X11_GL ) {
+               if( file_colormodel == BC_RGB_FLOAT ||
+                   file_colormodel == BC_RGBA_FLOAT )
+                       result = file_colormodel;
        }
 
-       if(result < 0)
-       {
-               switch(colormodel)
-               {
-                       case BC_RGB888:
-                       case BC_RGBA8888:
-                       case BC_YUV888:
-                       case BC_YUVA8888:
-                               result = colormodel;
-                               break;
-
-                       default:
-                               output->lock_canvas("VDeviceX11::get_best_colormodel");
-                               result = output->get_canvas()->get_color_model();
-                               output->unlock_canvas();
-                               break;
+       if( result < 0 ) {
+               switch( file_colormodel ) {
+               case BC_RGB888:
+               case BC_RGBA8888:
+               case BC_YUV888:
+               case BC_YUVA8888:
+               case BC_RGB_FLOAT:
+               case BC_RGBA_FLOAT:
+                       result = file_colormodel;
+                       break;
+
+               default:
+                       output->lock_canvas("VDeviceX11::get_display_colormodel");
+                       result = output->get_canvas()->get_color_model();
+                       output->unlock_canvas();
+                       break;
                }
        }
 
@@ -255,110 +290,177 @@ int VDeviceX11::get_best_colormodel(int colormodel)
 }
 
 
-void VDeviceX11::new_output_buffer(VFrame **result, int colormodel)
+void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *edl)
 {
-//printf("VDeviceX11::new_output_buffer 1\n");
+// printf("VDeviceX11::new_output_buffer %d hardware_scaling=%d\n",
+// __LINE__, bitmap ? bitmap->hardware_scaling() : 0);
        output->lock_canvas("VDeviceX11::new_output_buffer");
        output->get_canvas()->lock_window("VDeviceX11::new_output_buffer 1");
 
 // Get the best colormodel the display can handle.
-       int best_colormodel = get_best_colormodel(colormodel);
+       int display_colormodel = get_display_colormodel(file_colormodel);
 
+//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n",
+// __LINE__, file_colormodel, display_colormodel);
 // Only create OpenGL Pbuffer and texture.
        if( device->out_config->driver == PLAYBACK_X11_GL ) {
 // Create bitmap for initial load into texture.
 // Not necessary to do through Playback3D.....yet
                if( !output_frame ) {
-                       output_frame = new VFrame(0, -1,
-                               device->out_w, device->out_h, colormodel, -1);
-//BUFFER2(output_frame->get_rows()[0], "VDeviceX11::new_output_buffer 1");
+                       output_frame = new VFrame(device->out_w, device->out_h, file_colormodel);
                }
 
                window_id = output->get_canvas()->get_id();
                output_frame->set_opengl_state(VFrame::RAM);
        }
        else {
+               output->get_transfers(edl, 
+                       output_x1, output_y1, output_x2, output_y2, 
+                       canvas_x1, canvas_y1, canvas_x2, canvas_y2,
+// Canvas may be a different size than the temporary bitmap for pure software
+                       -1, -1);
+               canvas_w = canvas_x2 - canvas_x1;
+               canvas_h = canvas_y2 - canvas_y1;
+// can the direct frame be used?
+               int direct_supported = 
+                       device->out_config->use_direct_x11 &&
+                       !output->xscroll && !output->yscroll &&
+                       output_x1 == 0 && output_x2 == device->out_w &&
+                       output_y1 == 0 && output_y2 == device->out_h;
+
+// file wants direct frame but we need a temp
+               if( !direct_supported && file_colormodel == BC_BGR8888 )
+                       file_colormodel = BC_RGB888;
+
 // Conform existing bitmap to new colormodel and output size
                if( bitmap ) {
+// printf("VDeviceX11::new_output_buffer %d bitmap=%dx%d canvas=%dx%d canvas=%dx%d\n",
+// __LINE__, bitmap->get_w(), bitmap->get_h(), canvas_w, canvas_h,);
+                       int size_change = (
+                               bitmap->get_w() != canvas_w ||
+                               bitmap->get_h() != canvas_h );
+
 // Restart if output size changed or output colormodel changed.
 // May have to recreate if transferring between windowed and fullscreen.
-                       if( !color_model_selected || ( !bitmap->hardware_scaling() &&
-                               (bitmap->get_w() != output->get_canvas()->get_w() ||
-                                bitmap->get_h() != output->get_canvas()->get_h()) ) ||
-                           colormodel != output_frame->get_color_model() ) {
-                               int size_change =
-                                       bitmap->get_w() != output->get_canvas()->get_w() ||
-                                       bitmap->get_h() != output->get_canvas()->get_h();
-//printf("VDeviceX11::new_output_buffer %d\n", __LINE__);
+                       if( !color_model_selected ||
+                           file_colormodel != output_frame->get_color_model() ||
+                           (!bitmap->hardware_scaling() && size_change) ) {
+//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d prev "
+// "file_colormodel=%d bitmap=%p output_frame=%p\n", __LINE__,
+// file_colormodel, output_frame->get_color_model(), bitmap, output_frame);
                                delete bitmap;        bitmap = 0;
                                delete output_frame;  output_frame = 0;
-
-// Blank only if size changed
+// Clear borders if size changed
                                if( size_change ) {
+//printf("VDeviceX11::new_output_buffer %d w=%d h=%d "
+// "canvas_x1=%d canvas_y1=%d canvas_x2=%d canvas_y2=%d\n",
+// __LINE__, // (int)output->w, (int)output->h,
+// (int)canvas_x1, (int)canvas_y1, (int)canvas_x2, (int)canvas_y2);
                                        output->get_canvas()->set_color(BLACK);
-                                       output->get_canvas()->draw_box(0, 0, output->w, output->h);
-                                       output->get_canvas()->flash();
+
+                                       if( canvas_y1 > 0 ) {
+                                               output->get_canvas()->draw_box(0, 0, output->w, canvas_y1);
+                                               output->get_canvas()->flash(0, 0, output->w, canvas_y1);
+                                       }
+
+                                       if( canvas_y2 < output->h ) {
+                                               output->get_canvas()->draw_box(0, canvas_y2, output->w, output->h - canvas_y2);
+                                               output->get_canvas()->flash(0, canvas_y2, output->w, output->h - canvas_y2);
+                                       }
+
+                                       if( canvas_x1 > 0 ) {
+                                               output->get_canvas()->draw_box(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1);
+                                               output->get_canvas()->flash(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1);
+                                       }
+
+                                       if( canvas_x2 < output->w ) {
+                                               output->get_canvas()->draw_box(canvas_x2, canvas_y1,
+                                                       output->w - canvas_x2, canvas_y2 - canvas_y1);
+                                               output->get_canvas()->flash(canvas_x2, canvas_y1,
+                                                       output->w - canvas_x2, canvas_y2 - canvas_y1);
+                                       }
                                }
                        }
                }
 
 // Create new bitmap
                if( !bitmap ) {
-// Try hardware accelerated
+                       int use_direct = 0;
                        bitmap_type = BITMAP_TEMP;
-                       switch( best_colormodel ) {
+//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n", 
+// __LINE__, file_colormodel, display_colormodel);
+
+// Try hardware accelerated
+                       switch( display_colormodel ) {
+// blit from the codec directly to the window, using the standard X11 color model.
+// Must scale in the codec.  No cropping
+                       case BC_BGR8888:
+                               if( direct_supported ) {
+                                       bitmap_type = BITMAP_PRIMARY;
+                                       use_direct = 1;
+                               }
+                               break;
+
                        case BC_YUV420P:
                                if( device->out_config->driver == PLAYBACK_X11_XV &&
-                                   output->get_canvas()->accel_available(best_colormodel, 0) &&
+                                   output->get_canvas()->accel_available(display_colormodel, 0) &&
                                    !output->use_scrollbars )
                                        bitmap_type = BITMAP_PRIMARY;
                                break;
 
                        case BC_YUV422P:
                                if( device->out_config->driver == PLAYBACK_X11_XV &&
-                                   output->get_canvas()->accel_available(best_colormodel, 0) &&
+                                   output->get_canvas()->accel_available(display_colormodel, 0) &&
                                    !output->use_scrollbars )
                                        bitmap_type = BITMAP_PRIMARY;
                                else if( device->out_config->driver == PLAYBACK_X11_XV &&
                                    output->get_canvas()->accel_available(BC_YUV422, 0) ) {
-                                       bitmap = new BC_Bitmap(output->get_canvas(),
+                                       bitmap = new BC_Bitmap(output->get_canvas(), 
                                                device->out_w, device->out_h, BC_YUV422, 1);
                                }
                                break;
 
                        case BC_YUV422:
                                if( device->out_config->driver == PLAYBACK_X11_XV &&
-                                   output->get_canvas()->accel_available(best_colormodel, 0) &&
-                                   !output->use_scrollbars )
+                                   output->get_canvas()->accel_available(display_colormodel, 0) &&
+                                   !output->use_scrollbars ) {
                                        bitmap_type = BITMAP_PRIMARY;
+                               }
                                else if( device->out_config->driver == PLAYBACK_X11_XV &&
                                    output->get_canvas()->accel_available(BC_YUV422P, 0) ) {
-                                       bitmap = new BC_Bitmap(output->get_canvas(),
+                                       bitmap = new BC_Bitmap(output->get_canvas(), 
                                                device->out_w, device->out_h, BC_YUV422P, 1);
                                }
                                break;
                        }
                        if( bitmap_type == BITMAP_PRIMARY ) {
+                               int bitmap_w = use_direct ? canvas_w : device->out_w;
+                               int bitmap_h = use_direct ? canvas_h : device->out_h;
                                bitmap = new BC_Bitmap(output->get_canvas(),
-                                       device->out_w, device->out_h, best_colormodel, 1);
+                                       bitmap_w, bitmap_h,  display_colormodel, -1);
                                output_frame = new VFrame(bitmap,
-                                       device->out_w, device->out_h, best_colormodel, -1);
+                                       bitmap_w, bitmap_h, display_colormodel, -1);
                        }
-                       else {
-// Try default colormodel
-                               best_colormodel = output->get_canvas()->get_color_model();
-                               bitmap = new BC_Bitmap(output->get_canvas(),
-                                       output->get_canvas()->get_w(), output->get_canvas()->get_h(),
-                                       best_colormodel, 1);
-// Intermediate frame
-                               output_frame = new VFrame(0, -1,
-                                       device->out_w, device->out_h, colormodel, -1);
+// Make an intermediate frame
+                       if( !bitmap ) {
+                               display_colormodel = output->get_canvas()->get_color_model();
+// printf("VDeviceX11::new_output_buffer %d creating temp display_colormodel=%d "
+// "file_colormodel=%d %dx%d %dx%d %dx%d\n", __LINE__,
+// display_colormodel, file_colormodel, device->out_w, device->out_h,
+// output->get_canvas()->get_w(), output->get_canvas()->get_h(), canvas_w, canvas_h);
+                               bitmap = new BC_Bitmap(output->get_canvas(), 
+                                       canvas_w, canvas_h, display_colormodel, 1);
+                               bitmap_type = BITMAP_TEMP;
                        }
 
+                       if( bitmap_type == BITMAP_TEMP ) {
+// Intermediate frame
+//printf("VDeviceX11::new_output_buffer %d creating output_frame\n", __LINE__);
+                               output_frame = new VFrame(device->out_w, device->out_h, file_colormodel);
+                       }
                        color_model_selected = 1;
                }
                else if( bitmap_type == BITMAP_PRIMARY ) {
-// Update the ring buffer
                        output_frame->set_memory(bitmap);
                }
        }
@@ -374,14 +476,14 @@ void VDeviceX11::new_output_buffer(VFrame **result, int colormodel)
 int VDeviceX11::start_playback()
 {
 // Record window is initialized when its monitor starts.
-       if(!device->single_frame)
+       if( !device->single_frame )
                output->start_video();
        return 0;
 }
 
 int VDeviceX11::stop_playback()
 {
-       if(!device->single_frame)
+       if( !device->single_frame )
                output->stop_video();
 // Record window goes back to monitoring
 // get the last frame played and store it in the video_out
@@ -390,59 +492,52 @@ int VDeviceX11::stop_playback()
 
 int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
 {
-// The reason for not drawing single frame is that it is _always_ drawn
-// when drawing draw_refresh in cwindowgui and vwindowgui
-       if( device->single_frame )
-               return 0;
-
        output->lock_canvas("VDeviceX11::write_buffer");
        output->get_canvas()->lock_window("VDeviceX11::write_buffer 1");
-
-// Canvas may be a different size than the temporary bitmap for pure software
-       int xfr_w, xfr_h;
-       if(bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) {
-               xfr_w = bitmap->get_w();
-               xfr_h = bitmap->get_h();
-       }
-       else
-               xfr_w = xfr_h = -1;
-
-//printf("VDeviceX11::write_buffer %d %d\n", __LINE__, output->get_canvas()->get_video_on());
-       output->get_transfers(edl, output_x1, output_y1, output_x2, output_y2,
-               canvas_x1, canvas_y1, canvas_x2, canvas_y2, xfr_w, xfr_h);
-
-// Convert colormodel
-#if 0
+//     if( device->out_config->driver == PLAYBACK_X11_GL &&
+//         output_frame->get_color_model() != BC_RGB888 ) {
 // this is handled by overlay call in virtualvnode, using flatten alpha
 // invoked when is_nested = -1 is passed to vdevicex11->overlay(...)
-       if(device->out_config->driver == PLAYBACK_X11_GL &&
-           output_frame->get_color_model() != BC_RGB888) {
-               int cmodel = BC_RGB888;
-               output->get_canvas()->unlock_window();
-               output->unlock_canvas();
-               output->mwindow->playback_3d->convert_cmodel(output, output_frame, cmodel);
-               output_frame->reallocate(0,-1,0,0,0,output_frame->get_w(),output_frame->get_h(),cmodel,-1);
-               output->lock_canvas("VDeviceX11::write_buffer 3");
-               output->get_canvas()->lock_window("VDeviceX11::write_buffer 3");
-       }
-       else
-#endif
+//     }
+
+// printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n", 
+// __LINE__, 
+// output->get_canvas()->get_video_on(),
+// bitmap_type);
+
+//     int use_bitmap_extents = 0;
+//     canvas_w = -1;  canvas_h = -1;
+// // Canvas may be a different size than the temporary bitmap for pure software
+//     if( bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling() ) {
+//             canvas_w = bitmap->get_w();
+//             canvas_h = bitmap->get_h();
+//     }
+// 
+//     output->get_transfers(edl, 
+//             output_x1, output_y1, output_x2, output_y2, 
+//             canvas_x1, canvas_y1, canvas_x2, canvas_y2,
+//             canvas_w, canvas_h);
+
+// Convert colormodel
        if( bitmap_type == BITMAP_TEMP ) {
 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
-//  output->w, output->h, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h );
+//   output->w, output->h, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h);
 // fflush(stdout);
-//printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels);
+
+// printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels);
+// printf("VDeviceX11::write_buffer %d input color_model=%d output color_model=%d\n", 
+// __LINE__, output_channels->get_color_model(), bitmap->get_color_model());
                if( bitmap->hardware_scaling() ) {
-                       BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(),
-                               0, 0, 0, output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
+                       BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0,
+                               output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
                                0, 0, output_channels->get_w(), output_channels->get_h(),
                                0, 0, bitmap->get_w(), bitmap->get_h(),
                                output_channels->get_color_model(), bitmap->get_color_model(),
                                0, output_channels->get_w(), bitmap->get_w());
                }
                else {
-                       BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(),
-                               0, 0, 0, output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
+                       BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0,
+                               output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
                                (int)output_x1, (int)output_y1, (int)(output_x2 - output_x1), (int)(output_y2 - output_y1),
                                0, 0, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
                                output_channels->get_color_model(), bitmap->get_color_model(),
@@ -451,44 +546,69 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
        }
 
 //printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
-//for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128;
-//printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type,
-//  bitmap->get_color_model(), output->get_color_model());
-//fflush(stdout);
-//printf("VDeviceX11::write_buffer 2 %d %d, %f %f %f %f -> %f %f %f %f\n",
-// output->w, output->h, output_x1, output_y1, output_x2, output_y2,
+//for( i = 0; i < 1000; i += 4 ) bitmap->get_data()[i] = 128;
+//printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type, 
+//     bitmap->get_color_model(), 
+//     output->get_color_model());fflush(stdout);
+
+// printf("VDeviceX11::write_buffer %d %dx%d %f %f %f %f -> %f %f %f %f\n",
+// __LINE__, // output->w, output->h,
+// output_x1, output_y1, output_x2, output_y2,
 // canvas_x1, canvas_y1, canvas_x2, canvas_y2);
 
 // Cause X server to display it
        if( device->out_config->driver == PLAYBACK_X11_GL ) {
 // Output is drawn in close_all if no video.
                if( output->get_canvas()->get_video_on() ) {
+                       canvas_w = -1;  canvas_h = -1;
+// Canvas may be a different size than the temporary bitmap for pure software
+                       if( bitmap_type == BITMAP_TEMP && 
+                               !bitmap->hardware_scaling() ) {
+                               canvas_w = bitmap->get_w();
+                               canvas_h = bitmap->get_h();
+                       }
+
+                       output->get_transfers(edl, 
+                               output_x1, output_y1, output_x2, output_y2, 
+                               canvas_x1, canvas_y1, canvas_x2, canvas_y2,
+                               canvas_w, canvas_h);
+
+//printf("VDeviceX11::write_buffer %d\n", __LINE__);
 // Draw output frame directly.  Not used for compositing.
                        output->get_canvas()->unlock_window();
                        output->unlock_canvas();
-                       output->mwindow->playback_3d->write_buffer(output,
-                               output_frame, output_x1, output_y1, output_x2, output_y2,
-                               canvas_x1, canvas_y1, canvas_x2, canvas_y2, is_cleared);
+                       output->mwindow->playback_3d->write_buffer(output, output_frame,
+                               output_x1, output_y1, output_x2, output_y2,
+                               canvas_x1, canvas_y1, canvas_x2, canvas_y2,
+                               is_cleared);
                        is_cleared = 0;
                        output->lock_canvas("VDeviceX11::write_buffer 2");
                        output->get_canvas()->lock_window("VDeviceX11::write_buffer 2");
                }
        }
-       else if( bitmap->hardware_scaling() ) {
+       else
+       if( bitmap->hardware_scaling() ) {
                output->get_canvas()->draw_bitmap(bitmap, !device->single_frame,
                        (int)canvas_x1, (int)canvas_y1,
                        (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
                        (int)output_x1, (int)output_y1,
-                       (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), 0);
+                       (int)(output_x2 - output_x1), (int)(output_y2 - output_y1),
+                       0);
        }
        else {
+//printf("VDeviceX11::write_buffer %d x=%d y=%d w=%d h=%d\n", 
+// __LINE__, (int)canvas_x1, (int)canvas_y1,
+// output->get_canvas()->get_w(), output->get_canvas()->get_h());
+
                output->get_canvas()->draw_bitmap(bitmap, !device->single_frame,
                        (int)canvas_x1, (int)canvas_y1,
-                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0, 0,
-                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0);
+                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
+                       0, 0, 
+                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
+                       0);
+//printf("VDeviceX11::write_buffer %d bitmap=%p\n", __LINE__, bitmap);
        }
 
-
        output->get_canvas()->unlock_window();
        output->unlock_canvas();
        return 0;
@@ -513,17 +633,17 @@ void VDeviceX11::clear_input(VFrame *frame)
 void VDeviceX11::convert_cmodel(VFrame *output, int dst_cmodel)
 {
        this->output->mwindow->playback_3d->convert_cmodel(this->output,
-               output,
+               output, 
                dst_cmodel);
 }
 
 void VDeviceX11::do_camera(VFrame *output, VFrame *input,
-       float in_x1, float in_y1, float in_x2, float in_y2,
+       float in_x1, float in_y1, float in_x2, float in_y2, 
        float out_x1, float out_y1, float out_x2, float out_y2)
 {
-       this->output->mwindow->playback_3d->do_camera(
-               this->output, output, input,
-               in_x1, in_y1, in_x2, in_y2,
+       this->output->mwindow->playback_3d->do_camera(this->output, 
+               output, input,
+               in_x1, in_y1, in_x2, in_y2, 
                out_x1, out_y1, out_x2, out_y2);
 }
 
@@ -541,52 +661,45 @@ bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_se
        return keyframe->disable_opengl_masking ? 0 : 1;
 }
 
-void VDeviceX11::do_mask(VFrame *output_temp,
-       int64_t start_position_project, MaskAutos *keyframe_set,
-       MaskAuto *keyframe, MaskAuto *default_auto)
+void VDeviceX11::do_mask(VFrame *output_temp, int64_t start_position_project,
+               MaskAutos *keyframe_set, MaskAuto *keyframe, MaskAuto *default_auto)
 {
-       this->output->mwindow->playback_3d->do_mask(output,
-               output_temp, start_position_project,
-               keyframe_set, keyframe, default_auto);
+       this->output->mwindow->playback_3d->do_mask(output, output_temp,
+               start_position_project, keyframe_set, keyframe, default_auto);
 }
 
-void VDeviceX11::overlay(VFrame *output_frame, VFrame *input,
+void VDeviceX11::overlay(VFrame *output_frame, VFrame *input, 
 // This is the transfer from track to output frame
-               float in_x1, float in_y1, float in_x2, float in_y2,
-               float out_x1, float out_y1, float out_x2, float out_y2,
-               float alpha /*0-1*/, int mode, EDL *edl, int is_nested)
+               float in_x1, float in_y1, float in_x2, float in_y2, 
+               float out_x1, float out_y1, float out_x2, float out_y2, 
+               float alpha,        // 0 - 1
+               int mode, EDL *edl, int is_nested)
 {
        int interpolation_type = edl->session->interpolation_type;
 
 // printf("VDeviceX11::overlay 1:\n"
 // "in_x1=%f in_y1=%f in_x2=%f in_y2=%f\n"
 // "out_x1=%f out_y1=%f out_x2=%f out_y2=%f\n",
-// in_x1, in_y1, in_x2, in_y2,
-// out_x1, out_y1, out_x2, out_y2);
+// in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2);
 // Convert node coords to canvas coords in here
 
 // If single frame playback or nested EDL, use full sized PBuffer as output.
-       if(device->single_frame || is_nested > 0)
-       {
+       if( device->single_frame || is_nested > 0 ) {
                output->mwindow->playback_3d->overlay(output, input,
-                       in_x1, in_y1, in_x2, in_y2,
-                       out_x1, out_y1, out_x2, out_y2,
-                       alpha, mode, interpolation_type,
-                       output_frame, is_nested);
-// printf("VDeviceX11::overlay 1 %p %d %d %d\n",
-// output_frame,
-// output_frame->get_w(),
-// output_frame->get_h(),
+                       in_x1, in_y1, in_x2, in_y2, 
+                       out_x1, out_y1, out_x2, out_y2, alpha, // 0 - 1
+                       mode, interpolation_type, output_frame, is_nested);
+// printf("VDeviceX11::overlay 1 %p %d %d %d\n", 
+// output_frame, output_frame->get_w(), output_frame->get_h(),
 // output_frame->get_opengl_state());
        }
-       else
-       {
+       else {
                output->lock_canvas("VDeviceX11::overlay");
                output->get_canvas()->lock_window("VDeviceX11::overlay");
 
 // This is the transfer from output frame to canvas
-               output->get_transfers(edl,
-                       output_x1, output_y1, output_x2, output_y2,
+               output->get_transfers(edl, 
+                       output_x1, output_y1, output_x2, output_y2, 
                        canvas_x1, canvas_y1, canvas_x2, canvas_y2,
                        -1, -1);
 
@@ -608,40 +721,35 @@ void VDeviceX11::overlay(VFrame *output_frame, VFrame *input,
                float track_y2 = (float)(output_y2 - out_y2) / track_yscale + in_y2;
 
 // Clamp canvas coords to track boundary
-               if(track_x1 < 0)
-               {
+               if( track_x1 < 0 ) {
                        float difference = -track_x1;
                        track_x1 += difference;
                        canvas_x1 += difference * track_xscale * canvas_xscale;
                }
-               if(track_y1 < 0)
-               {
+               if( track_y1 < 0 ) {
                        float difference = -track_y1;
                        track_y1 += difference;
                        canvas_y1 += difference * track_yscale * canvas_yscale;
                }
 
-               if(track_x2 > input->get_w())
-               {
+               if( track_x2 > input->get_w() ) {
                        float difference = track_x2 - input->get_w();
                        track_x2 -= difference;
                        canvas_x2 -= difference * track_xscale * canvas_xscale;
                }
-               if(track_y2 > input->get_h())
-               {
+               if( track_y2 > input->get_h() ) {
                        float difference = track_y2 - input->get_h();
                        track_y2 -= difference;
                        canvas_y2 -= difference * track_yscale * canvas_yscale;
                }
 
 // Overlay directly from track buffer to canvas, skipping output buffer
-               if(track_x2 > track_x1 && track_y2 > track_y1 &&
-                       canvas_x2 > canvas_x1 && canvas_y2 > canvas_y1)
-               {
+               if( track_x2 > track_x1 && track_y2 > track_y1 &&
+                       canvas_x2 > canvas_x1 && canvas_y2 > canvas_y1 ) {
                        output->mwindow->playback_3d->overlay(output, input,
-                               track_x1, track_y1, track_x2, track_y2,
-                               canvas_x1, canvas_y1, canvas_x2, canvas_y2,
-                               alpha, mode, interpolation_type, 0, is_nested);
+                               track_x1, track_y1, track_x2, track_y2, 
+                               canvas_x1, canvas_y1, canvas_x2, canvas_y2, alpha, // 0 - 1
+                               mode, interpolation_type, 0, is_nested);
                }
        }
 }
index 7f001a70c61d409c2726fe3c388a866b44baf69a..afc21edb27db2aac2f53b9f5431a0e88ef3ead0d 100644 (file)
@@ -47,7 +47,7 @@ public:
        int read_buffer(VFrame *frame);
        int reset_parameters();
 // User always gets the colormodel requested
-       void new_output_buffer(VFrame **output, int colormodel);
+       void new_output_buffer(VFrame **output, int colormodel, EDL *edl);
 
        int open_output();
        int start_playback();
@@ -130,7 +130,13 @@ private:
 // is passed to this to create the VFrame to which the output is rendered.
 // For OpenGL, it creates the array of row pointers used to upload the video
 // frame to the texture, the texture, and the PBuffer.
-       int get_best_colormodel(int colormodel);
+       int get_display_colormodel(int file_colormodel);
+
+// windows which overlay the screencap area
+#define SCREENCAP_BORDERS 4
+#define SCREENCAP_PIXELS 5
+#define SCREENCAP_COLOR GREEN
+       BC_Popup *screencap_border[SCREENCAP_BORDERS];
 
 // Bitmap to be written to device
        BC_Bitmap *bitmap;
@@ -150,12 +156,14 @@ private:
        int texture_h;
        int color_model;
        int color_model_selected;
-// Transfer coordinates from the output frame to the canvas
-// for last frame rendered.
+// Transfer coordinates from the output frame to the canvas.
+// Calculated in new_output_buffer & retained for write_buffer
 // These stick the last frame to the display.
 // Must be floats to support OpenGL
        float output_x1, output_y1, output_x2, output_y2;
        float canvas_x1, canvas_y1, canvas_x2, canvas_y2;
+// rounded integer dimensions
+       int canvas_w, canvas_h;
 // Screen capture
        BC_Capture *capture_bitmap;
 // Set when OpenGL rendering has cleared the frame buffer before write_buffer
index fbad636f2b34f2bafadff09b6b881472026cd1ba..e8de98ca9862c70759c74203a61cefe0112504a7 100644 (file)
@@ -190,6 +190,8 @@ int VideoDevice::initialize()
        single_frame = 0;
        channel_changed = 0;
        picture_changed = 0;
+       odd_field_first = 0;
+       do_cursor = 0;
        return 0;
 }
 
@@ -492,6 +494,21 @@ int VideoDevice::set_field_order(int odd_field_first)
        return 0;
 }
 
+void VideoDevice::set_do_cursor(int do_cursor, int do_big_cursor)
+{
+       int cursor_scale = 0;
+       if(do_cursor)
+       {
+               cursor_scale = 1;
+               if(do_big_cursor)
+               {
+                       cursor_scale = 2;
+               }
+       }
+
+       this->do_cursor = cursor_scale;
+}
+
 int VideoDevice::set_channel(Channel *channel)
 {
        int result = 0;
@@ -697,10 +714,10 @@ void VideoDevice::goose_input()
        if(input_base) input_base->goose_input();
 }
 
-void VideoDevice::new_output_buffer(VFrame **output, int colormodel)
+void VideoDevice::new_output_buffer(VFrame **output, int colormodel, EDL *edl)
 {
        if(!output_base) return;
-       output_base->new_output_buffer(output, colormodel);
+       output_base->new_output_buffer(output, colormodel, edl);
 }
 
 
index f9334aff576061b886b0ff1ddf835cbc068e0247..61f566574cd7d0f45ed205c15996b8ac01e4ce8f 100644 (file)
@@ -144,6 +144,7 @@ public:
        void set_quality(int quality);
 // Change field order
        int set_field_order(int odd_field_first);
+       void set_do_cursor(int do_cursor, int do_big_cursor);
 // Set frames to clear after translation change.
        int set_latency_counter(int value);
 // Values from -100 to 100
@@ -177,7 +178,7 @@ public:
        int interrupt_playback();
 // Get output buffer for playback using colormodel.
 // colormodel argument should be as close to best_colormodel as possible
-       void new_output_buffer(VFrame **output, int colormodel);
+       void new_output_buffer(VFrame **output, int colormodel, EDL *edl);
        int wait_for_startup();
        int wait_for_completion();
        int output_visible();     // Whether the output is visible or not.
@@ -263,6 +264,7 @@ public:
 // All the input sources on the device
        ArrayList<Channel*> input_sources;
        int odd_field_first;
+       int do_cursor;
 // Quality for the JPEG compressor
        int quality;
 // Single frame mode for playback
index 02e047e64163f3fa115b094c204193db9e881055..0c8e1b7fdec53176caf4bb0f0288f17ecf4f15e3 100644 (file)
@@ -230,11 +230,8 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
        {
                File *file = 0;
 
-               if(debug) printf("VModule::import_frame %d cache=%p\n",
-                       __LINE__,
-                       get_cache());
-               if(current_edit->asset)
-               {
+//printf("VModule::import_frame %d cache=%p\n", __LINE__, get_cache());
+               if( current_edit->asset ) {
                        get_cache()->age();
                        file = get_cache()->check_out(current_edit->asset,
                                get_edl());
@@ -307,18 +304,19 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
 
                        int use_cache = renderengine &&
                                renderengine->command->single_frame();
-                       int use_asynchronous = !use_cache && renderengine &&
+//                     int use_asynchronous = !use_cache &&
+//                             renderengine &&
 // Try to make rendering go faster.
 // But converts some formats to YUV420, which may degrade input format.
-//                             renderengine->command->realtime &&
-                               renderengine->get_edl()->session->video_asynchronous;
+////                           renderengine->command->realtime &&
+//                             renderengine->get_edl()->session->video_asynchronous;
 
                        if(file)
                        {
                                if(debug) printf("VModule::import_frame %d\n", __LINE__);
-                               if(use_asynchronous)
-                                       file->start_video_decode_thread();
-                               else
+//                             if(use_asynchronous)
+//                                     file->start_video_decode_thread();
+//                             else
                                        file->stop_video_thread();
 
                                int64_t normalized_position = Units::to_int64(position *
@@ -445,7 +443,7 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
                                !EQUIV(in_w, asset_w) ||
                                !EQUIV(in_h, asset_h))
                        {
-                               if(debug) printf("VModule::import_frame %d file -> temp -> output\n", __LINE__);
+//printf("VModule::import_frame %d file -> temp -> output\n", __LINE__);
 
 
 
@@ -725,7 +723,13 @@ output->get_opengl_state(),
                                                get_edl()->session->interpolation_type);
                                }
                                result = 1;
+                               
                                output->copy_stacks((*input));
+                               
+                               
+//printf("VModule::import_frame %d\n", __LINE__); 
+//(*input)->dump_params();
+//output->dump_params();
                        }
                        else
 // file -> output
@@ -880,6 +884,11 @@ current_cmodel);
                        }
                        result = 1;
                }
+
+//             printf("VModule::import_frame %d cache=%p\n", 
+//                     __LINE__,
+//                     get_cache());
+
        }
        else
 // Source is silence
index c59c3fec0be0c4d185f71f6bb4b64c2e0c78c350..f46a4096b95f8b3750725b7411b04467f9954946 100644 (file)
@@ -133,10 +133,10 @@ int VRender::process_buffer(int64_t input_position,
        int use_brender = 0;
        int result = 0;
        int use_cache = renderengine->command->single_frame();
-       int use_asynchronous =
-               renderengine->command->realtime &&
-               renderengine->get_edl()->session->video_every_frame &&
-               renderengine->get_edl()->session->video_asynchronous;
+//     int use_asynchronous = 
+//             renderengine->command->realtime && 
+//             renderengine->get_edl()->session->video_every_frame &&
+//             renderengine->get_edl()->session->video_asynchronous;
        const int debug = 0;
 
 // Determine the rendering strategy for this frame.
@@ -151,7 +151,9 @@ int VRender::process_buffer(int64_t input_position,
 // Get output buffer from device
        if(renderengine->command->realtime && !renderengine->is_nested)
        {
-               renderengine->video->new_output_buffer(&video_out, colormodel);
+               renderengine->video->new_output_buffer(&video_out, 
+                       colormodel, 
+                       renderengine->get_edl());
        }
 
        if(debug) printf("VRender::process_buffer %d video_out=%p\n", __LINE__, video_out);
@@ -177,9 +179,9 @@ int VRender::process_buffer(int64_t input_position,
                                        corrected_position--;
 
 // Cache single frames only
-                               if(use_asynchronous)
-                                       file->start_video_decode_thread();
-                               else
+//                             if(use_asynchronous)
+//                                     file->start_video_decode_thread();
+//                             else
                                        file->stop_video_thread();
                                if(use_cache) file->set_cache_frames(1);
                                int64_t normalized_position = (int64_t)(corrected_position *
@@ -206,7 +208,8 @@ int VRender::process_buffer(int64_t input_position,
                                renderengine->get_vcache(),
                                1,
                                use_cache,
-                               use_asynchronous);
+                               0);
+//                             use_asynchronous);
                        if(debug) printf("VRender::process_buffer %d\n", __LINE__);
                }
 
@@ -267,8 +270,7 @@ int VRender::get_colormodel(VEdit *playable_edit,
                                current_position,
                                renderengine->command->get_direction());
                }
-// ffmpeg files are side effected by color_model, affects colorspace,color_range
-               if( asset && asset->format != FILE_FFMPEG )
+               if( asset )
                {
                        file = renderengine->get_vcache()->check_out(asset,
                                renderengine->get_edl());
@@ -276,8 +278,12 @@ int VRender::get_colormodel(VEdit *playable_edit,
                        if(file)
                        {
                                colormodel = file->get_best_colormodel(driver);
+//printf("VRender::get_colormodel %d driver=%d colormodel=%d\n", __LINE__, driver, colormodel);
                                renderengine->get_vcache()->check_in(asset);
                        }
+// ffmpeg files are side effected by color_model, affects colorspace,color_range
+//                     if( asset->format == FILE_FFMPEG && !BC_CModels::is_yuv(colormodel) )
+//                             colormodel = BC_BGR8888;
                }
        }
 
index 9d54bc7dab7e7b9b26d68a6884312ba3839dd51c..3ec19dfd5a05879e00e1c2002f6f8dea5fd93b07 100644 (file)
@@ -397,6 +397,7 @@ CHECK_LIB([XINERAMA], [Xinerama], [XineramaQueryExtension])
 CHECK_HEADERS([XINERAMA], [Xinerama headers], [X11/extensions/Xinerama.h])
 CHECK_LIB([XV], [Xv], [XvQueryExtension])
 CHECK_HEADERS([XV], [Xlib Xv extention], [X11/Xlib.h X11/extensions/Xvlib.h])
+CHECK_LIB([XFIXES], [Xfixes], [XFixesQueryVersion])
 CHECK_LIB([BZ2], [bz2], [BZ2_bzDecompress])
 CHECK_LIB([FONTCONFIG], [fontconfig], [FcInit])
 CHECK_LIB([FREETYPE], [freetype], [FT_Init_FreeType])
index 98dbcaed3dc66e7bd704f63dcd69c8164a7eb62d..fc4e1a56282b92eacde11effbbae2740834d0560 100644 (file)
@@ -2,4 +2,3 @@
 loglevel=fatal
 formatprobesize=5000000
 scan_all_pmts=1
-threads=auto
index efc7f15c1bbc6e06861b7a42b1808b1c2a7ef358..2fa43288724faacb1431a4f67554cef4c30aae83 100644 (file)
@@ -16,6 +16,7 @@ OBJS = \
        $(OBJDIR)/bcbitmap.o \
        $(OBJDIR)/bcbutton.o \
        $(OBJDIR)/bccapture.o \
+       $(OBJDIR)/bccolors.o \
        $(OBJDIR)/bccmodels.o \
        $(OBJDIR)/bccounter.o \
        $(OBJDIR)/bcclipboard.o \
index 7d1e37a2cc406fd35f3d60c8830d841bef474643..221248b9107046a65fe73adef1f857c7ad97c9d4 100644 (file)
@@ -32,7 +32,7 @@
 #include "bcwindowbase.inc"
 #include "bcbitmap.inc"
 #include "bccmodels.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "condition.h"
 #include "linklist.h"
 #include "mutex.h"
index 6a8b863b1f3d5318f577fe17abb259d69a86af4e..6d0c4349da01c57e8e03f8884865e35c7ea0307e 100644 (file)
@@ -23,7 +23,7 @@
 #include "bcpixmap.h"
 #include "bcresources.h"
 #include "bcsignals.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "keys.h"
 #include "language.h"
index 993cfe14fbc3279ee1cbf7c08943608416d5e441..e955a52730b03ed51f80c60dd21c5baa722cb1fc 100644 (file)
 #include "bcresources.h"
 #include "bcwindowbase.h"
 #include "bccmodels.h"
+#include "bccolors.h"
+#include "clip.h"
 #include "language.h"
 #include "vframe.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <X11/Xutil.h>
-
-
-
-
+#include <X11/extensions/Xfixes.h>
 
 // Byte orders:
 // 24 bpp packed:         bgr
@@ -59,11 +58,10 @@ BC_Capture::~BC_Capture()
 int BC_Capture::init_window(const char *display_path)
 {
        int bits_per_pixel;
-       if(display_path && display_path[0] == 0) display_path = NULL;
-       if((display = XOpenDisplay(display_path)) == NULL)
-       {
+       if( display_path && display_path[0] == 0 ) display_path = NULL;
+       if( (display = XOpenDisplay(display_path)) == NULL ) {
                printf(_("cannot connect to X server.\n"));
-               if(getenv("DISPLAY") == NULL)
+               if( getenv("DISPLAY") == NULL )
                printf(_("'DISPLAY' environment variable not set.\n"));
                exit(-1);
                return 1;
@@ -93,8 +91,7 @@ int BC_Capture::init_window(const char *display_path)
 
 // test shared memory
 // This doesn't ensure the X Server is on the local host
-    if(use_shm && !XShmQueryExtension(display))
-    {
+    if( use_shm && !XShmQueryExtension(display) ) {
         use_shm = 0;
     }
        return 0;
@@ -104,14 +101,12 @@ int BC_Capture::init_window(const char *display_path)
 int BC_Capture::allocate_data()
 {
 // try shared memory
-       if(!display) return 1;
-    if(use_shm)
-       {
+       if( !display ) return 1;
+    if( use_shm ) {
            ximage = XShmCreateImage(display, vis, default_depth, ZPixmap, (char*)NULL, &shm_info, w, h);
 
                shm_info.shmid = shmget(IPC_PRIVATE, h * ximage->bytes_per_line, IPC_CREAT | 0600);
-               if(shm_info.shmid == -1)
-               {
+               if( shm_info.shmid == -1 ) {
                        perror("BC_Capture::allocate_data shmget");
                        abort();
                }
@@ -124,16 +119,14 @@ int BC_Capture::allocate_data()
                BC_Resources::error = 0;
                XShmAttach(display, &shm_info);
        XSync(display, False);
-               if(BC_Resources::error)
-               {
+               if( BC_Resources::error ) {
                        XDestroyImage(ximage);
                        shmdt(shm_info.shmaddr);
                        use_shm = 0;
                }
        }
 
-       if(!use_shm)
-       {
+       if( !use_shm ) {
 // need to use bytes_per_line for some X servers
                data = 0;
                ximage = XCreateImage(display, vis, default_depth, ZPixmap, 0, (char*)data, w, h, 8, 0);
@@ -144,8 +137,7 @@ int BC_Capture::allocate_data()
        }
 
        row_data = new unsigned char*[h];
-       for(int i = 0; i < h; i++)
-       {
+       for( int i = 0; i < h; i++ ) {
                row_data[i] = &data[i * ximage->bytes_per_line];
        }
 // This differs from the depth parameter of the top_level.
@@ -155,17 +147,14 @@ int BC_Capture::allocate_data()
 
 int BC_Capture::delete_data()
 {
-       if(!display) return 1;
-       if(data)
-       {
-               if(use_shm)
-               {
+       if( !display ) return 1;
+       if( data ) {
+               if( use_shm ) {
                        XShmDetach(display, &shm_info);
                        XDestroyImage(ximage);
                        shmdt(shm_info.shmaddr);
                }
-               else
-               {
+               else {
                        XDestroyImage(ximage);
                }
 
@@ -181,31 +170,22 @@ int BC_Capture::get_w() { return w; }
 int BC_Capture::get_h() { return h; }
 
 // Capture a frame from the screen
-#define CAPTURE_FRAME_HEAD \
-       for(int i = 0; i < h; i++) \
-       { \
-               unsigned char *input_row = row_data[i]; \
-               unsigned char *output_row = (unsigned char*)frame->get_rows()[i]; \
-               for(int j = 0; j < w; j++) \
-               {
-
-#define CAPTURE_FRAME_TAIL \
-               } \
-       }
+#define RGB_TO_YUV(y, u, v, r, g, b) { \
+ YUV::yuv.rgb_to_yuv_8(r, g, b, y, u, v); \
+ bclamp(y, 0,0xff); bclamp(u, 0,0xff); bclamp(v, 0,0xff); }
 
-
-
-int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1)
+int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1, 
+       int do_cursor) // the scale of the cursor if nonzero
 {
-       if(!display) return 1;
-       if(x1 < 0) x1 = 0;
-       if(y1 < 0) y1 = 0;
-       if(x1 > get_top_w() - w) x1 = get_top_w() - w;
-       if(y1 > get_top_h() - h) y1 = get_top_h() - h;
+       if( !display ) return 1;
+       if( x1 < 0 ) x1 = 0;
+       if( y1 < 0 ) y1 = 0;
+       if( x1 > get_top_w() - w ) x1 = get_top_w() - w;
+       if( y1 > get_top_h() - h ) y1 = get_top_h() - h;
 
 
 // Read the raw data
-       if(use_shm)
+       if( use_shm )
                XShmGetImage(display, rootwin, ximage, x1, y1, 0xffffffff);
        else
                XGetSubImage(display, rootwin, x1, y1, w, h, 0xffffffff, ZPixmap, ximage, 0, 0);
@@ -216,6 +196,72 @@ int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1)
                frame->get_w(), frame->get_h(),
                bitmap_color_model, frame->get_color_model(),
                0, frame->get_w(), w);
+       
+       if( do_cursor ) {
+               XFixesCursorImage *cursor;
+               cursor = XFixesGetCursorImage(display);
+               if( cursor ) {
+//printf("BC_Capture::capture_frame %d cursor=%p colormodel=%d\n", 
+// __LINE__, cursor, frame->get_color_model());
+                       int scale = do_cursor;
+                       int cursor_x = cursor->x - x1 - cursor->xhot * scale;
+                       int cursor_y = cursor->y - y1 - cursor->yhot * scale;
+                       int w = frame->get_w();
+                       int h = frame->get_h();
+                       for( int i = 0; i < cursor->height; i++ ) {
+                               for( int yscale = 0; yscale < scale; yscale++ ) {
+                                       if( cursor_y + i * scale + yscale >= 0 && 
+                                               cursor_y + i * scale + yscale < h ) {
+                                               unsigned char *src = (unsigned char*)(cursor->pixels + 
+                                                       i * cursor->width);
+                                               int dst_y = cursor_y + i * scale + yscale;
+                                               int dst_x = cursor_x;
+                                               for( int j = 0; j < cursor->width; j++ ) {
+                                                       for( int xscale = 0; xscale < scale ; xscale++ ) {
+                                                               if( cursor_x + j * scale + xscale >= 0 && 
+                                                                       cursor_x + j * scale + xscale < w ) {
+                                                                       int a = src[3];
+                                                                       int invert_a = 0xff - a;
+                                                                       int r = src[2];
+                                                                       int g = src[1];
+                                                                       int b = src[0];
+                                                                       switch( frame->get_color_model() ) {
+                                                                       case BC_RGB888: {
+                                                                               unsigned char *dst = frame->get_rows()[dst_y] +
+                                                                                       dst_x * 3;
+                                                                               dst[0] = (r * a + dst[0] * invert_a) / 0xff;
+                                                                               dst[1] = (g * a + dst[1] * invert_a) / 0xff;
+                                                                               dst[2] = (b * a + dst[2] * invert_a) / 0xff;
+                                                                               break; }
+
+                                                                       case BC_YUV420P: {
+                                                                               unsigned char *dst_y_ = frame->get_y() + 
+                                                                                       dst_y * w + dst_x;
+                                                                               unsigned char *dst_u = frame->get_u() + 
+                                                                                       (dst_y / 2) * (w / 2) + (dst_x / 2);
+                                                                               unsigned char *dst_v = frame->get_v() + 
+                                                                                       (dst_y / 2) * (w / 2) + (dst_x / 2);
+                                                                               int y, u, v;
+                                                                               RGB_TO_YUV(y, u, v, r, g, b);
+                                                                                       
+                                                                               *dst_y_ = (y * a + *dst_y_ * invert_a) / 0xff;
+                                                                               *dst_u = (u * a + *dst_u * invert_a) / 0xff;
+                                                                               *dst_v = (v * a + *dst_v * invert_a) / 0xff;
+                                                                               break; }
+                                                                       }
+                                                               }
+                                                               dst_x++;
+                                                       }
+                                                       src += sizeof(long);
+                                               }
+                                       }
+                               }
+                       }
+
+// This frees cursor->pixels
+                       XFree(cursor);
+               }
+       }
 
        return 0;
 }
index e0f098b9d728686dfa6ce5f3a3841ad6cf0c0869..787fb4a6455fb94d429235b780580ff598604621 100644 (file)
@@ -39,7 +39,8 @@ public:
 
        int init_window(const char *display_path);
 // x1 and y1 are automatically adjusted if out of bounds
-       int capture_frame(VFrame *frame, int &x1, int &y1);
+       int capture_frame(VFrame *frame, int &x1, int &y1, 
+               int do_cursor=0); // the scale of the cursor if nonzero
        int get_w();
        int get_h();
 
index 57b595f4e30234ef9d44be201a007fe5dd218f85..63b7d8c3b8b7d7671db9fc904945e7cee341b861 100644 (file)
@@ -128,7 +128,6 @@ public:
                        int in_x, int in_y, int in_w, int in_h, int in_rowspan,
                int bg_color);
 
-       static void init_yuv();
        static int bc_to_x(int color_model);
        static void bcxfer_stop_slicers();
 };
similarity index 99%
rename from cinelerra-5.1/cinelerra/cicolors.C
rename to cinelerra-5.1/guicast/bccolors.C
index 2dba6f87eb127812aed34164f88c1a8c021d3494..48dcb02aa5acd649c69591311bb056d5b712bf03 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include "cicolors.h"
+#include "bccolors.h"
 
 #include <stdio.h>
 
similarity index 81%
rename from cinelerra-5.1/cinelerra/cicolors.h
rename to cinelerra-5.1/guicast/bccolors.h
index 1ab7ab452c7a24d600ee3028724cebe6e2fe14c5..c91aba9fc405b97f061b3fc35b1cad5916161316 100644 (file)
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef CICOLORS_H
-#define CICOLORS_H
+#ifndef __BCCOLORS_H__
+#define __BCCOLORS_H__
 
 // Duplicate filename in guicast
 
@@ -193,18 +193,6 @@ private:
 };
 
 
-
-
-
-
-
-
-
-
-
-
-
-
 class HSV
 {
 public:
@@ -224,4 +212,51 @@ public:
 };
 
 
+// standard colors
+#define BLACK               0x000000
+#define WHITE               0xFFFFFF
+
+#define LTBLUE              0x9090FF
+#define BLUE                0x0000FF
+#define DKBLUE              0x000090
+
+#define LTPINK              0xFFC0C0
+#define PINK                0xFF8080
+#define RED                 0xFF0000
+
+#define LTGREEN             0xC0FFC0
+#define GREEN               0x00FF00
+#define DKGREEN             0x009000
+
+#define YELLOW              0xFFFF00
+#define LTYELLOW            0xFFFFA0
+#define MEYELLOW            0xFFFF00
+#define MDYELLOW            0xFFFFD2
+#define DKYELLOW            0xFFFFB4
+
+#define LTCYAN              0x00CBCB
+#define MECYAN              0x009696
+#define MDCYAN              0x007E7E
+#define DKCYAN              0x004949
+
+#define LTPURPLE            0xFFC0FF
+#define MEPURPLE            0xFF00FF
+#define MDPURPLE            0xC000C0
+#define DKPURPLE            0xA000A0
+
+#define LTGREY              0xE0E0E0
+#define MEGREY              0xAFAFAF
+#define DMGREY              0x999999
+#define MDGREY              0x7D7D7D
+#define DKGREY              0x4B4B4B
+
+#define BLOND               0xb4b487
+#define SLBLUE              0x6040c0
+
+#define MNGREY              0xe6e6e6
+#define FGGREY              0xe3e3e3
+#define MNBLUE              0x003cff
+#define ORANGE              0xffdd76
+#define FTGREY              0xbcbcbc
+
 #endif
index 021a87fc8cb82aae3edc8662093adc9264ad0312..212956b83a9050a76496559cfb22e9264f4fb064 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 1997-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 394daac60607dd1bf6e82274408076b8fd0be071..ac15f666e4d8b139414bda2703d63ee86fff6d61 100644 (file)
@@ -4505,43 +4505,39 @@ void BC_ListBox::draw_title(int number)
                        image_number = 2;
        }
 
-       int column_offset = get_column_offset(number) - xposition + LISTBOX_BORDER;
-       int column_width = get_column_width(number, 1);
        gui->draw_3segmenth(get_column_offset(number) - xposition + LISTBOX_BORDER,
                LISTBOX_BORDER,
                get_column_width(number, 1) + get_resources()->listbox_title_overlap,
                column_bg[image_number]);
 
-// Column title sort order
-       if(number == sort_column)
-       {
-               BC_Pixmap *src;
-               if(sort_order == SORT_ASCENDING)
-                       src = column_sort_dn;
-               else
-                       src = column_sort_up;
+       int title_x = -xposition + get_column_offset(number) + 
+               LISTBOX_MARGIN + LISTBOX_BORDER;
+       title_x += get_resources()->listbox_title_margin;
 
-               int x = column_offset +
-                       column_width -
-                       LISTBOX_BORDER;
-               if(x > items_w) x = items_w;
-               x -= 5 + src->get_w();
+       gui->set_color(get_resources()->listbox_title_color);
+       gui->draw_text(title_x, 
+               LISTBOX_MARGIN + LISTBOX_BORDER + get_text_ascent(MEDIUMFONT), 
+               column_titles[number]);
+
+// Column sort order
+       if(number == sort_column) {
+               BC_Pixmap *src = sort_order == SORT_ASCENDING ?
+                       column_sort_dn : column_sort_up;
+
+//             int column_offset = get_column_offset(number) - xposition + LISTBOX_BORDER;
+//             int column_width = get_column_width(number, 1);
+//             int toggle_x = column_offset + column_width - LISTBOX_BORDER;
+//             if( toggle_x > items_w ) toggle_x = items_w;
+//             toggle_x -= 5 + src->get_w();
+
+               int x = title_x + 
+                       get_text_width(MEDIUMFONT, column_titles[number]) +
+                       LISTBOX_MARGIN;
+               
                gui->draw_pixmap(src,
                        x,
                        title_h / 2 - src->get_h() / 2 + LISTBOX_BORDER);
        }
-
-
-       int x = -xposition +
-               get_column_offset(number) +
-               LISTBOX_MARGIN +
-               LISTBOX_BORDER;
-       x += get_resources()->listbox_title_margin;
-
-       gui->set_color(get_resources()->listbox_title_color);
-       gui->draw_text(x,
-               LISTBOX_MARGIN + LISTBOX_BORDER + get_text_ascent(MEDIUMFONT),
-               _(column_titles[number]));
 }
 
 int BC_ListBox::draw_titles(int flash)
index e0654105acf39b007dae887f99372a3d8723c5a9..8d42508047682efc035c12280cea6b39d0f1bdec 100644 (file)
@@ -27,7 +27,7 @@
 #include "bcscrollbar.h"
 #include "bcsubwindow.h"
 #include "bctoggle.h"
-#include "colors.h"
+#include "bccolors.h"
 
 #define BCPOPUPLISTBOX_W 25
 #define BCPOPUPLISTBOX_H 25
index 4ec0e475c16a6b539ed58ca7d1e5ed4b71818e74..bb9bc126d6851d8d553347e4fa1d419bd39a5367 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "arraylist.h"
 #include "bcpixmap.inc"
-#include "colors.h"
+#include "bccolors.h"
 #include "vframe.h"
 
 
index 135a7d445f2ec5eacd0778b117b857913af47f56..908567ec592184381a3f141758a7833bc75ac0a1 100644 (file)
@@ -27,7 +27,7 @@
 #include "bcpopupmenu.h"
 #include "bcresources.h"
 #include "bcsignals.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "keys.h"
 #include <string.h>
index c516622a947d7995d273711e2162c3ebb43f42d5..f51a46d636af1957eeded6d8360d87f08e621842 100644 (file)
@@ -28,7 +28,7 @@
 #include "bcresources.h"
 #include "bcsignals.h"
 #include "bcwindowbase.h"
-#include "colors.h"
+#include "bccolors.h"
 
 #include <string.h>
 
index 3728c0b645c3ceb982d1dffaa575cc83d0c93891..5b40a05cbedb696935940be7f2d62861f76a4447 100644 (file)
@@ -50,7 +50,7 @@ public:
        void set_hotkey_text(const char *text);
        int set_shift(int value = 1);
        int set_alt(int value = 1);
-       void set_ctrl(int value);
+       void set_ctrl(int value = 1);
 
        int deactivate_submenus(BC_MenuPopup *exclude);
        int activate_submenu();
index 22a420a905e395133327e96c3af7635152dc9e60..6ece16f2952418fceceb3586c0213c3f85a16e21 100644 (file)
@@ -24,7 +24,7 @@
 #include "bcpixmap.h"
 #include "bcresources.h"
 #include "bcwindow.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "vframe.h"
 #include <string.h>
index e35925f43c38ac6017a39494d5d5863730accb67..d8bce87265d3cf6622c480adee4e538053dda272 100644 (file)
@@ -24,7 +24,7 @@
 #include "bcpopup.h"
 #include "bcresources.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "rotateframe.h"
 #include "units.h"
index 8421a6bf46ef675f8a8ae11cbd173b1f976a022c..4d3144b59996a545cb9c3f80fd5d046cd8e496a5 100644 (file)
@@ -26,7 +26,7 @@
 #include "bcpopupmenu.h"
 #include "bcresources.h"
 #include "bcsignals.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include <string.h>
 #include "vframe.h"
index e934fc537d4a161ed5753ac31eadeb4b6430617b..60807911b501ed6e628f6d3bb8a2046e40db43a6 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "bcpot.h"
 #include "bcresources.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "keys.h"
 #include "units.h"
 #include "vframe.h"
index 7cca92b94edf95c870e77a5ef660ba79e3afab9f..100ef766a381adb92402c02335c9fd82fbe72053 100644 (file)
@@ -25,7 +25,7 @@
 #define PROGRESS_UP 0
 #define PROGRESS_HI 1
 
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "bcprogress.h"
 #include "bcpixmap.h"
index 4ae705adb645f301368b2176fee49d9e2e8b91a6..e932af59411abeee197a8b2e7d415f4bb649d28b 100644 (file)
@@ -27,7 +27,7 @@
 #include "bcsignals.h"
 #include "bcsynchronous.h"
 #include "bcwindowbase.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "bccmodels.h"
 #include "cstrdup.h"
 #include "fonts.h"
@@ -72,10 +72,14 @@ static const char *def_big_font =
   "-*-bitstream charter-bold-r-normal-*-*-0-%d-%d-p-0-iso8859-1"; // 160
 static const char *def_big_font2 =
   "-*-nimbus sans l-bold-r-normal-*-*-0-%d-%d-p-0-iso8859-1";     // 160
+static const char *def_clock_font = "-*-helvetica-bold-r-normal-*-%d-*";      // 16
+static const char *def_clock_font2 = "-*-helvetica-bold-r-normal-*-%d-*";     // 18
 static const char *def_small_fontset =  "-*-helvetica-medium-r-normal-*-%d-*";// 10
 static const char *def_medium_fontset = "-*-helvetica-bold-r-normal-*-%d-*";  // 14
 static const char *def_large_fontset =  "-*-helvetica-bold-r-normal-*-%d-*";  // 18
 static const char *def_big_fontset =    "-*-helvetica-bold-r-normal-*-%d-*";  // 24
+static const char *def_clock_fontset = "-*-helvetica-bold-r-normal-*-%d-*";   // 16
+
 static const char *def_small_font_xft = "Sans:pixelsize=%.4f";           // 10.6667
 static const char *def_small_b_font_xft = "Sans:bold:pixelsize=%.4f";    // 10.6667
 static const char *def_medium_font_xft = "Sans:pixelsize=%.4f";          // 13.3333
@@ -84,6 +88,7 @@ static const char *def_large_font_xft = "Sans:pixelsize=%.4f";           // 21.3
 static const char *def_large_b_font_xft = "Sans:bold:pixelsize=%.4f";    // 21.3333
 static const char *def_big_font_xft = "Sans:pixelsize=37.3333";          // 37.3333
 static const char *def_big_b_font_xft = "Sans:bold:pixelsize=37.33333";  // 37.3333
+static const char *def_clock_font_xft = "Sans:pixelsize=16";             // 16
 
 #define default_font_xft2 "-microsoft-verdana-*-*-*-*-*-*-*-*-*-*-*-*"
 
@@ -95,10 +100,13 @@ const char* BC_Resources::large_font = 0;
 const char* BC_Resources::large_font2 = 0;
 const char* BC_Resources::big_font = 0;
 const char* BC_Resources::big_font2 = 0;
+const char* BC_Resources::clock_font = 0;
+const char* BC_Resources::clock_font2 = 0;
 const char* BC_Resources::small_fontset = 0;
 const char* BC_Resources::medium_fontset = 0;
 const char* BC_Resources::large_fontset = 0;
 const char* BC_Resources::big_fontset = 0;
+const char* BC_Resources::clock_fontset = 0;
 const char* BC_Resources::small_font_xft = 0;
 const char* BC_Resources::small_font_xft2 = 0;
 const char* BC_Resources::small_b_font_xft = 0;
@@ -111,6 +119,8 @@ const char* BC_Resources::large_b_font_xft = 0;
 const char* BC_Resources::big_font_xft = 0;
 const char* BC_Resources::big_font_xft2 = 0;
 const char* BC_Resources::big_b_font_xft = 0;
+const char* BC_Resources::clock_font_xft = 0;
+const char* BC_Resources::clock_font_xft2 = 0;
 
 #define def_font(v, s...) do { sprintf(string,def_##v,s); v = cstrdup(string); } while(0)
 #define set_font(v, s) do { sprintf(string, "%s", s); v = cstrdup(string); } while(0)
@@ -125,11 +135,14 @@ void BC_Resources::init_font_defs(double scale)
        def_font(large_font,       iround(scale*18));
        def_font(large_font2,      iround(scale*20));
        def_font(big_font,         iround(scale*160), iround(scale*160));
-       def_font(big_font2,        iround(scale*160), iround(scale*160));
+       def_font(big_font2,        iround(scale*16), iround(scale*16));
+       def_font(clock_font,       iround(scale*16), iround(scale*16));
+       def_font(clock_font2,      iround(scale*16), iround(scale*16));
        def_font(small_fontset,    iround(scale*10));
        def_font(medium_fontset,   iround(scale*14));
        def_font(large_fontset,    iround(scale*18));
        def_font(big_fontset,      iround(scale*24));
+       def_font(clock_fontset,    iround(scale*16));
        def_font(small_font_xft,   (scale*10.6667));
        def_font(small_b_font_xft, (scale*10.6667));
        def_font(medium_font_xft,  (scale*13.3333));
@@ -138,11 +151,13 @@ void BC_Resources::init_font_defs(double scale)
        def_font(large_b_font_xft, (scale*21.3333));
        def_font(big_font_xft,     (scale*37.3333));
        def_font(big_b_font_xft,   (scale*37.3333));
+       def_font(clock_font_xft,   (scale*16));
 
        set_font(small_font_xft2,  default_font_xft2);
        set_font(medium_font_xft2, default_font_xft2);
        set_font(large_font_xft2,  default_font_xft2);
        set_font(big_font_xft2,    default_font_xft2);
+       set_font(clock_font_xft2,  default_font_xft2);
 }
 void BC_Resources::finit_font_defs()
 {
@@ -154,10 +169,13 @@ void BC_Resources::finit_font_defs()
        delete [] large_font2;
        delete [] big_font;
        delete [] big_font2;
+       delete [] clock_font;
+       delete [] clock_font2;
        delete [] small_fontset;
        delete [] medium_fontset;
        delete [] large_fontset;
        delete [] big_fontset;
+       delete [] clock_fontset;
        delete [] small_font_xft;
        delete [] small_b_font_xft;
        delete [] medium_font_xft;
@@ -166,11 +184,13 @@ void BC_Resources::finit_font_defs()
        delete [] large_b_font_xft;
        delete [] big_font_xft;
        delete [] big_b_font_xft;
+       delete [] clock_font_xft;
 
        delete [] small_font_xft2;
        delete [] medium_font_xft2;
        delete [] large_font_xft2;
        delete [] big_font_xft2;
+       delete [] clock_font_xft2;
 }
 
 
index 8ff046490d423555a99fecd7489af29f1a6e8728..d5c9a069f83ebaeccf797c09e0d778e2ef49d0af 100644 (file)
@@ -306,31 +306,31 @@ public:
        double font_scale, icon_scale;
 
 // fonts
-       static const char *small_font;
-       static const char *medium_font;
-       static const char *large_font;
-       static const char *big_font;
-// Backup of fonts in case the first choices don't exist
-       static const char *small_font2;
-       static const char *medium_font2;
-       static const char *large_font2;
-       static const char *big_font2;
+       static const char *small_font, *small_font2;
+       static const char *medium_font, *medium_font2;
+       static const char *large_font, *large_font2;
+       static const char *big_font, *big_font2;
+       static const char *clock_font, *clock_font2;
 
        static const char *small_fontset;
        static const char *medium_fontset;
        static const char *large_fontset;
        static const char *big_fontset;
+       static const char *clock_fontset;
 
        static const char *small_font_xft, *small_b_font_xft;
        static const char *medium_font_xft, *medium_b_font_xft;
        static const char *large_font_xft, *large_b_font_xft;
        static const char *big_font_xft, *big_b_font_xft;
+       static const char *clock_font_xft, *clock_b_font_xft;
 
 // Backup of fonts in case the first choices don't exist
        static const char *small_font_xft2;
        static const char *medium_font_xft2;
        static const char *large_font_xft2;
        static const char *big_font_xft2;
+       static const char *clock_font_xft2;
+
        void init_font_defs(double scale);
        void finit_font_defs();
 
index bc2e4f990305b37beaba07f4c6bab180ba7ccef9..389cacf8bf4b5e97f8117f8e19a3969dbc180334 100644 (file)
@@ -23,7 +23,7 @@
 #include "bcresources.h"
 #include "bcscrollbar.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "vframe.h"
 
 #include <string.h>
index 79283d291467c51120377e5b1b11b1ed9d521076..7a60a1f44ee423a3c953b92d71cb0ffd8949803d 100644 (file)
@@ -22,7 +22,7 @@
 #include "bcpixmap.h"
 #include "bcresources.h"
 #include "bcslider.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "keys.h"
 #include "units.h"
index 5d1257eb82cb44e949ca24c406b43684d278b1df..bdbe6040e51cf63939c1e1a1464c567ceccf941c 100644 (file)
 #include "bcsignals.h"
 #include "bctextbox.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include <ctype.h>
 #include "cursors.h"
 #include "filesystem.h"
 #include "keys.h"
+#include "language.h"
 #include <math.h>
 #include "bctimer.h"
 #include "vframe.h"
@@ -133,6 +134,7 @@ BC_TextBox::~BC_TextBox()
        delete suggestions_popup;
        suggestions->remove_all_objects();
        delete suggestions;
+       delete menu;
        delete [] wtext;
        if( size > 0 )
                delete [] text;
@@ -175,6 +177,7 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size)
        separators = 0;
        xscroll = 0;
        yscroll = 0;
+       menu = 0;
        dirty = 1;
        selection_active = 0;
        return 0;
@@ -247,6 +250,7 @@ int BC_TextBox::text_update(const wchar_t *wcp, int wsz, char *tcp, int tsz)
 
 int BC_TextBox::initialize()
 {
+
        if (!skip_cursor)
                skip_cursor = new Timer;
        skip_cursor->update();
@@ -288,6 +292,10 @@ int BC_TextBox::initialize()
        draw(0);
        set_cursor(IBEAM_CURSOR, 0, 0);
        show_window(0);
+
+       add_subwindow(menu = new BC_TextMenu(this));
+       menu->create_objects();
+
        return 0;
 }
 
@@ -779,12 +787,10 @@ int BC_TextBox::button_press_event()
        const int debug = 0;
 
        if(!enabled) return 0;
-       if(get_buttonpress() != WHEEL_UP &&
-               get_buttonpress() != WHEEL_DOWN &&
-               get_buttonpress() != LEFT_BUTTON &&
-               get_buttonpress() != MIDDLE_BUTTON) return 0;
-
-
+//     if(get_buttonpress() != WHEEL_UP &&
+//             get_buttonpress() != WHEEL_DOWN &&
+//             get_buttonpress() != LEFT_BUTTON &&
+//             get_buttonpress() != MIDDLE_BUTTON) return 0;
 
        if(debug) printf("BC_TextBox::button_press_event %d\n", __LINE__);
 
@@ -822,6 +828,11 @@ int BC_TextBox::button_press_event()
                        update_scroll = 1;
                }
                else
+               if(get_buttonpress() == RIGHT_BUTTON)
+               {
+                       menu->activate_menu();
+               }
+               else
                {
 
                cursor_letter = get_cursor_letter(top_level->cursor_x, top_level->cursor_y);
@@ -1608,29 +1619,15 @@ int BC_TextBox::keypress_event()
                        if( ctrl_down() ) {
                                switch( get_keypress() ) {
                                case 'c': case 'C': {
-                                       if(highlight_letter1 != highlight_letter2) {
-                                               copy_selection(SECONDARY_SELECTION);
-                                               result = 1;
-                                       }
+                                       result = copy(0);
                                        break; }
                                case 'v': case 'V': {
-                                       paste_selection(SECONDARY_SELECTION);
-                                       find_ibeam(1);
-                                       if(keypress_draw) draw(1);
+                                       result = paste(0);
                                        dispatch_event = 1;
-                                       result = 1;
                                        break; }
                                case 'x': case 'X': {
-                                       if(highlight_letter1 != highlight_letter2) {
-                                               copy_selection(SECONDARY_SELECTION);
-                                               delete_selection(highlight_letter1, highlight_letter2, wtext_len);
-                                               highlight_letter2 = ibeam_letter = highlight_letter1;
-                                       }
-
-                                       find_ibeam(1);
-                                       if(keypress_draw) draw(1);
+                                       result = cut(0);
                                        dispatch_event = 1;
-                                       result = 1;
                                        break; }
                                case 'u': case 'U': {
                                        if( shift_down() ) {
@@ -1661,6 +1658,53 @@ int BC_TextBox::keypress_event()
 }
 
 
+int BC_TextBox::cut(int do_update)
+{
+       if( highlight_letter1 != highlight_letter2 ) {
+               int wtext_len = wtext_update();
+               copy_selection(SECONDARY_SELECTION);
+               delete_selection(highlight_letter1, highlight_letter2, wtext_len);
+               highlight_letter2 = ibeam_letter = highlight_letter1;
+       }
+
+       find_ibeam(1);
+       if( keypress_draw )
+               draw(1);
+       
+       if( do_update ) {
+               skip_cursor->update();
+               handle_event();
+       }
+       return 1;
+}
+
+int BC_TextBox::copy(int do_update)
+{
+       int result = 0;
+       if( highlight_letter1 != highlight_letter2 ) {
+               copy_selection(SECONDARY_SELECTION);
+               result = 1;
+               if( do_update ) {
+                       skip_cursor->update();
+               }
+       }
+       return result;
+}
+
+int BC_TextBox::paste(int do_update)
+{
+       paste_selection(SECONDARY_SELECTION);
+       find_ibeam(1);
+       if( keypress_draw )
+               draw(1);
+       if( do_update ) {
+               skip_cursor->update();
+               handle_event();
+       }
+       return 1;
+}
+
+
 int BC_TextBox::uses_text()
 {
        return 1;
@@ -2843,6 +2887,66 @@ void BC_TumbleTextBox::set_boundaries(float min, float max)
        tumbler->set_boundaries(min, max);
 }
 
+
+
+BC_TextMenu::BC_TextMenu(BC_TextBox *textbox)
+ : BC_PopupMenu(0, 0, 0, "", 0)
+{
+       this->textbox = textbox;
+}
+
+BC_TextMenu::~BC_TextMenu()
+{
+}
+
+void BC_TextMenu::create_objects()
+{
+       add_item(new BC_TextMenuCut(this));
+       add_item(new BC_TextMenuCopy(this));
+       add_item(new BC_TextMenuPaste(this));
+}
+
+
+BC_TextMenuCut::BC_TextMenuCut(BC_TextMenu *menu) 
+ : BC_MenuItem(_("Cut"))
+{
+       this->menu = menu;
+}
+
+int BC_TextMenuCut::handle_event()
+{
+       menu->textbox->cut(1);
+       
+       return 0;
+}
+
+
+BC_TextMenuCopy::BC_TextMenuCopy(BC_TextMenu *menu) 
+ : BC_MenuItem(_("Copy"))
+{
+       this->menu = menu;
+}
+
+int BC_TextMenuCopy::handle_event()
+{
+       menu->textbox->copy(1);
+       return 0;
+}
+
+
+BC_TextMenuPaste::BC_TextMenuPaste(BC_TextMenu *menu) 
+ : BC_MenuItem(_("Paste"))
+{
+       this->menu = menu;
+}
+
+int BC_TextMenuPaste::handle_event()
+{
+       menu->textbox->paste(1);
+       return 0;
+}
+
+
 void BC_TumbleTextBox::set_tooltip(const char *text)
 {
        textbox->set_tooltip(text);
index 89d7743254ec045e225519c5f1c17530d2cccfab..e461767eafd76bbe90e2c93677605ec8eb29ee11 100644 (file)
@@ -23,6 +23,8 @@
 #define BCTEXTBOX_H
 
 #include "bclistbox.h"
+#include "bcmenuitem.h"
+#include "bcpopupmenu.h"
 #include "bcsubwindow.h"
 #include "bctumble.h"
 #include "fonts.h"
@@ -39,7 +41,7 @@ class BC_TextBoxSuggestions;
 class BC_ScrollTextBoxXScroll;
 class BC_ScrollTextBoxYScroll;
 class BC_ScrollTextBoxText;
-
+class BC_TextMenu;
 
 class BC_TextBox : public BC_SubWindow
 {
@@ -118,6 +120,10 @@ public:
 
        int reposition_window(int x, int y, int w = -1, int rows = -1);
        int uses_text();
+       int cut(int do_update);
+       int copy(int do_update);
+       int paste(int do_update);
+       
        static int calculate_h(BC_WindowBase *gui, int font, int has_border, int rows);
        static int calculate_row_h(int rows, BC_WindowBase *parent_window, int has_border = 1, int font = MEDIUMFONT);
        static int pixels_to_rows(BC_WindowBase *window, int font, int pixels);
@@ -157,6 +163,7 @@ public:
        BC_ScrollTextBoxYScroll *yscroll;
 private:
        int reset_parameters(int rows, int has_border, int font, int size);
+       BC_TextMenu *menu;
        void draw(int flush);
        void draw_border();
        void draw_cursor();
@@ -463,4 +470,40 @@ public:
 };
 
 
+class BC_TextMenu : public BC_PopupMenu
+{
+public:
+       BC_TextMenu(BC_TextBox *textbox);
+       ~BC_TextMenu();
+       
+       void create_objects();
+       
+       BC_TextBox *textbox;
+};
+
+class BC_TextMenuCut : public BC_MenuItem
+{
+public:
+       BC_TextMenuCut(BC_TextMenu *menu);
+       int handle_event();
+       BC_TextMenu *menu;
+};
+
+class BC_TextMenuCopy : public BC_MenuItem
+{
+public:
+       BC_TextMenuCopy(BC_TextMenu *menu);
+       int handle_event();
+       BC_TextMenu *menu;
+};
+
+class BC_TextMenuPaste : public BC_MenuItem
+{
+public:
+       BC_TextMenuPaste(BC_TextMenu *menu);
+       int handle_event();
+       BC_TextMenu *menu;
+};
+
+
 #endif
index 3a54c728de5349a4852c62bcb672c3c2d5404e0e..adb59f24e3703cfecaea2828d76d4cf41386994c 100644 (file)
@@ -23,7 +23,7 @@
 #define BCTITLE_H
 
 #include "bcsubwindow.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 
 class BC_Title : public BC_SubWindow
index 1155467374b09dd3b8cfcf8cebca7f39e81c115f..67af31ec4888534dd4b2c6332389b212e377938a 100644 (file)
 #include "bcsignals.h"
 #include "bctoggle.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "cursors.h"
 #include "fonts.h"
 #include "vframe.h"
 
 #include <string.h>
 
-BC_Toggle::BC_Toggle(int x, int y,
-               VFrame **data,
-               int value,
-               const char *caption,
-               int bottom_justify,
-               int font,
-               int color)
+BC_Toggle::BC_Toggle(int x, int y, VFrame **data, int value,
+               const char *caption, int bottom_justify, int font, int color)
  : BC_SubWindow(x, y, 0, 0, -1)
 {
        this->data = data;
-       for(int i = 0; i < TOGGLE_IMAGES; i++)
-               images[i] = 0;
+       for( int i=0; i<TOGGLE_IMAGES; ++i ) images[i] = 0;
        bg_image = 0;
        status = value ? BC_Toggle::TOGGLE_CHECKED : BC_Toggle::TOGGLE_UP;
        this->value = value;
        strcpy(this->caption, caption);
        this->bottom_justify = bottom_justify;
        this->font = font;
-       if(color >= 0)
-               this->color = color;
-       else
-               this->color = get_resources()->default_text_color;
+       this->color = color >= 0 ? color : get_resources()->default_text_color;
        select_drag = 0;
        enabled = 1;
        underline = -1;
@@ -62,7 +53,7 @@ BC_Toggle::BC_Toggle(int x, int y,
 
 BC_Toggle::~BC_Toggle()
 {
-       for(int i = 0; i < TOGGLE_IMAGES; i++) if(images[i]) delete images[i];
+       for( int i=0; i<TOGGLE_IMAGES; ++i ) delete images[i];
        delete bg_image;
 }
 
@@ -71,18 +62,9 @@ int BC_Toggle::initialize()
 {
 // Get the image
        set_images(data);
-       calculate_extents(this,
-               data,
-               bottom_justify,
-               &text_line,
-               &w,
-               &h,
-               &toggle_x,
-               &toggle_y,
-               &text_x,
-               &text_y,
-               &text_w,
-               &text_h,
+       calculate_extents(this, data, bottom_justify,
+               &text_line, &w, &h, &toggle_x, &toggle_y,
+               &text_x, &text_y, &text_w, &text_h,
                has_caption() ? caption : 0,
                font);
 
@@ -97,19 +79,10 @@ int BC_Toggle::initialize()
 
 
 void BC_Toggle::calculate_extents(BC_WindowBase *gui,
-       VFrame **images,
-       int bottom_justify,
-       int *text_line,
-       int *w,
-       int *h,
-       int *toggle_x,
-       int *toggle_y,
-       int *text_x,
-       int *text_y,
-       int *text_w,
-       int *text_h,
-       const char *caption,
-       int font)
+       VFrame **images, int bottom_justify,
+       int *text_line, int *w, int *h, int *toggle_x, int *toggle_y,
+       int *text_x, int *text_y, int *text_w, int *text_h,
+       const char *caption, int font)
 {
        BC_Resources *resources = get_resources();
        VFrame *frame = images[0];
@@ -122,27 +95,23 @@ void BC_Toggle::calculate_extents(BC_WindowBase *gui,
        *text_w = 0;
        *text_h = 0;
 
-       if(caption)
-       {
+       if( caption ) {
                *text_w = gui->get_text_width(font, caption);
                *text_h = gui->get_text_height(font);
 
-               if(resources->toggle_highlight_bg)
-               {
+               if( resources->toggle_highlight_bg ) {
                        *text_w += resources->toggle_text_margin * 2;
                        *text_h = MAX(*text_h, resources->toggle_highlight_bg->get_h());
                }
 
-               if(*text_h > *h)
-               {
+               if( *text_h > *h ) {
                        *toggle_y = (*text_h - *h) >> 1;
                        *h = *text_h;
                }
                else
                        *text_y = (*h - *text_h) >> 1;
 
-               if(bottom_justify)
-               {
+               if( bottom_justify ) {
                        *text_y = *h - *text_h;
                        *text_line = *h - gui->get_text_descent(font);
                }
@@ -164,14 +133,12 @@ int BC_Toggle::set_images(VFrame **data)
 {
        delete bg_image;
        bg_image = 0;
-       for(int i = 0; i < TOGGLE_IMAGES; i++)
-       {
-               if(images[i]) delete images[i];
+       for( int i=0; i<TOGGLE_IMAGES; ++i ) {
+               delete images[i];
                images[i] = new BC_Pixmap(top_level, data[i], PIXMAP_ALPHA);
        }
        BC_Resources *resources = get_resources();
-       if(resources->toggle_highlight_bg)
-       {
+       if( resources->toggle_highlight_bg ) {
                bg_image = new BC_Pixmap(top_level,
                        resources->toggle_highlight_bg,
                        PIXMAP_ALPHA);
@@ -194,16 +161,13 @@ int BC_Toggle::draw_face(int flash, int flush)
 {
        BC_Resources *resources = get_resources();
        draw_top_background(parent_window, 0, 0, get_w(), get_h());
-       if(has_caption())
-       {
-               if(enabled &&
+       if( has_caption() ) {
+               if( enabled &&
                        (status == BC_Toggle::TOGGLE_UPHI ||
                                status == BC_Toggle::TOGGLE_DOWN ||
-                               status == BC_Toggle::TOGGLE_CHECKEDHI))
-               {
+                               status == BC_Toggle::TOGGLE_CHECKEDHI) ) {
 // Draw highlight image
-                       if(bg_image)
-                       {
+                       if( bg_image ) {
                                int x = text_x;
                                int y = text_line - get_text_ascent(font) / 2 -
                                                bg_image->get_h() / 2;
@@ -226,7 +190,7 @@ int BC_Toggle::draw_face(int flash, int flush)
                }
 
                set_opaque();
-               if(enabled)
+               if( enabled )
                        set_color(color);
                else
                        set_color(get_resources()->disabled_text_color);
@@ -236,8 +200,7 @@ int BC_Toggle::draw_face(int flash, int flush)
                        caption);
 
 // Draw underline
-               if(underline >= 0)
-               {
+               if( underline >= 0 ) {
                        int x = text_x + resources->toggle_text_margin;
                        int y = text_line + 1;
                        int x1 = get_text_width(current_font, caption, underline) + x;
@@ -248,21 +211,21 @@ int BC_Toggle::draw_face(int flash, int flush)
        }
 
        draw_pixmap(images[status]);
-       if(flash) this->flash(0);
-       if(flush) this->flush();
+       if( flash ) this->flash(0);
+       if( flush ) this->flush();
        return 0;
 }
 
 void BC_Toggle::enable()
 {
        enabled = 1;
-       if(parent_window) draw_face(1, 1);
+       if( parent_window ) draw_face(1, 1);
 }
 
 void BC_Toggle::disable()
 {
        enabled = 0;
-       if(parent_window) draw_face(1, 1);
+       if( parent_window ) draw_face(1, 1);
 }
 
 void BC_Toggle::set_status(int value)
@@ -273,10 +236,9 @@ void BC_Toggle::set_status(int value)
 
 int BC_Toggle::repeat_event(int64_t duration)
 {
-       if(tooltip_text && tooltip_text[0] != 0 &&
+       if( tooltip_text && tooltip_text[0] != 0 &&
                duration == top_level->get_resources()->tooltip_delay &&
-               (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_CHECKEDHI))
-       {
+               (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_CHECKEDHI) ) {
                show_tooltip();
                return 1;
        }
@@ -285,9 +247,8 @@ int BC_Toggle::repeat_event(int64_t duration)
 
 int BC_Toggle::cursor_enter_event()
 {
-       if(top_level->event_win == win && enabled)
-       {
-               if(top_level->button_down)
+       if( top_level->event_win == win && enabled ) {
+               if( top_level->button_down )
                        status = BC_Toggle::TOGGLE_DOWN;
                else
                        status = value ? BC_Toggle::TOGGLE_CHECKEDHI : BC_Toggle::TOGGLE_UPHI;
@@ -299,14 +260,12 @@ int BC_Toggle::cursor_enter_event()
 int BC_Toggle::cursor_leave_event()
 {
        hide_tooltip();
-       if(!value && status == BC_Toggle::TOGGLE_UPHI)
-       {
+       if( !value && status == BC_Toggle::TOGGLE_UPHI ) {
                status = BC_Toggle::TOGGLE_UP;
                draw_face(1, 1);
        }
        else
-       if(status == BC_Toggle::TOGGLE_CHECKEDHI)
-       {
+       if( status == BC_Toggle::TOGGLE_CHECKEDHI ) {
                status = BC_Toggle::TOGGLE_CHECKED;
                draw_face(1, 1);
        }
@@ -316,15 +275,13 @@ int BC_Toggle::cursor_leave_event()
 int BC_Toggle::button_press_event()
 {
        hide_tooltip();
-       if(top_level->event_win == win && get_buttonpress() == 1 && enabled)
-       {
+       if( top_level->event_win == win && get_buttonpress() == 1 && enabled ) {
                status = BC_Toggle::TOGGLE_DOWN;
 
 // Change value now for select drag mode.
 // Radial always goes to 1
-               if(select_drag)
-               {
-                       if(!is_radial)
+               if( select_drag ) {
+                       if( !is_radial )
                                value = !value;
                        else
                                value = 1;
@@ -344,12 +301,10 @@ int BC_Toggle::button_release_event()
        int result = 0;
        hide_tooltip();
 
-       if(top_level->event_win == win)
-       {
+       if( top_level->event_win == win ) {
 // Keep value regardless of status if drag mode.
-               if(select_drag)
-               {
-                       if(value)
+               if( select_drag ) {
+                       if( value )
                                status = BC_Toggle::TOGGLE_CHECKEDHI;
                        else
                                status = BC_Toggle::TOGGLE_UPHI;
@@ -357,16 +312,13 @@ int BC_Toggle::button_release_event()
                }
                else
 // Change value only if button down for default mode.
-               if(status == BC_Toggle::TOGGLE_DOWN)
-               {
+               if( status == BC_Toggle::TOGGLE_DOWN ) {
 // Radial always goes to 1.
-                       if(!value || is_radial)
-                       {
+                       if( !value || is_radial ) {
                                status = BC_Toggle::TOGGLE_CHECKEDHI;
                                value = 1;
                        }
-                       else
-                       {
+                       else {
                                status = BC_Toggle::TOGGLE_UPHI;
                                value = 0;
                        }
@@ -380,21 +332,18 @@ int BC_Toggle::button_release_event()
 
 int BC_Toggle::cursor_motion_event()
 {
-       if(top_level->button_down &&
+       if( top_level->button_down &&
                top_level->event_win == win &&
-               !cursor_inside())
-       {
-               if(status == BC_Toggle::TOGGLE_DOWN)
-               {
-                       if(value)
+               !cursor_inside() ) {
+               if( status == BC_Toggle::TOGGLE_DOWN ) {
+                       if( value )
                                status = BC_Toggle::TOGGLE_CHECKED;
                        else
                                status = BC_Toggle::TOGGLE_UP;
                        draw_face(1, 1);
                }
                else
-               if(status == BC_Toggle::TOGGLE_UPHI)
-               {
+               if( status == BC_Toggle::TOGGLE_UPHI ) {
                        status = BC_Toggle::TOGGLE_CHECKEDHI;
                        draw_face(1, 1);
                }
@@ -409,32 +358,29 @@ int BC_Toggle::get_value()
 
 int BC_Toggle::set_value(int value, int draw)
 {
-       if(value != this->value)
-       {
+       if( value != this->value ) {
                this->value = value;
-               if(value)
-               {
-                       switch(status)
-                       {
-                               case BC_Toggle::TOGGLE_UP:
-                                       status = BC_Toggle::TOGGLE_CHECKED;
-                                       break;
-                               case BC_Toggle::TOGGLE_UPHI:
-                                       status = BC_Toggle::TOGGLE_CHECKEDHI;
-                                       break;
+               if( value ) {
+                       switch( status ) {
+                       case BC_Toggle::TOGGLE_UP:
+                               status = BC_Toggle::TOGGLE_CHECKED;
+                               break;
+                       case BC_Toggle::TOGGLE_UPHI:
+                               status = BC_Toggle::TOGGLE_CHECKEDHI;
+                               break;
                        }
                }
-               else
-               switch(status)
-               {
+               else {
+                       switch( status ) {
                        case BC_Toggle::TOGGLE_CHECKED:
                                status = BC_Toggle::TOGGLE_UP;
                                break;
                        case BC_Toggle::TOGGLE_CHECKEDHI:
                                status = BC_Toggle::TOGGLE_UPHI;
                                break;
+                       }
                }
-               if(draw) draw_face(1, 1);
+               if( draw ) draw_face(1, 1);
        }
        return 0;
 }
@@ -456,56 +402,29 @@ int BC_Toggle::has_caption()
        return (caption != 0 && caption[0] != 0);
 }
 
-BC_Radial::BC_Radial(int x,
-       int y,
-       int value,
-       const char *caption,
-       int font,
-       int color)
- : BC_Toggle(x,
-       y,
+BC_Radial::BC_Radial(int x, int y, int value,
+       const char *caption, int font, int color)
+ : BC_Toggle(x, y,
        BC_WindowBase::get_resources()->radial_images,
-       value,
-       caption,
-       0,
-       font,
-       color)
+       value, caption, 0, font, color)
 {
        is_radial = 1;
 }
 
-BC_CheckBox::BC_CheckBox(int x,
-       int y,
-       int value,
-       const char *caption,
-       int font,
-       int color)
- : BC_Toggle(x,
-       y,
+BC_CheckBox::BC_CheckBox(int x, int y, int value,
+       const char *caption, int font, int color)
+ : BC_Toggle(x, y,
        BC_WindowBase::get_resources()->checkbox_images,
-       value,
-       caption,
-       0,
-       font,
-       color)
+       value, caption, 0, font, color)
 {
        this->value = 0;
 }
 
-BC_CheckBox::BC_CheckBox(int x,
-       int y,
-       int *value,
-       const char *caption,
-       int font,
-       int color)
- : BC_Toggle(x,
-       y,
+BC_CheckBox::BC_CheckBox(int x, int y, int *value,
+       const char *caption, int font, int color)
+ : BC_Toggle(x, y,
        BC_WindowBase::get_resources()->checkbox_images,
-       *value,
-       caption,
-       1,
-       font,
-       color)
+       *value, caption, 1, font, color)
 {
        this->value = value;
 }
@@ -529,20 +448,17 @@ int BC_CheckBox::handle_event()
        return 1;
 }
 
+int BC_CheckBox::calculate_h(BC_WindowBase *gui, int font)
+{
+       int w, h;
+       calculate_extents(gui, &w, &h, "X", font);
+       return h;
+}
 
 
-BC_Label::BC_Label(int x,
-       int y,
-       int value,
-       int font,
-       int color)
- : BC_Toggle(x,
-       y,
-       BC_WindowBase::get_resources()->label_images,
-       value,
-       "",
-       0,
-       font,
-       color)
+BC_Label::BC_Label(int x, int y, int value, int font, int color)
+ : BC_Toggle(x, y,
+       BC_WindowBase::get_resources()->label_images, value,
+       "", 0, font, color)
 {
 }
index 2fc321503c48a8af75a32e0d5987482fcc0e575a..609791302289ecf980b8842df0991a5e8b76b3b2 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "bcbitmap.inc"
 #include "bcsubwindow.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "vframe.inc"
 
@@ -143,6 +143,7 @@ public:
                int font = MEDIUMFONT,
                int color = -1);
        virtual int handle_event();
+       static int calculate_h(BC_WindowBase *gui, int font=MEDIUMFONT);
 
        static void calculate_extents(BC_WindowBase *gui, int *w, int *h,
                const char *caption="", int font=MEDIUMFONT);
index ec7507683bf04eef3136f014b3e88f169b4564b1..6599369e1b2276e71eac074dcbeb3154e938631c 100644 (file)
@@ -36,7 +36,7 @@
 #include "bcwindowbase.h"
 #include "bcwindowevents.h"
 #include "bccmodels.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "condition.h"
 #include "cursors.h"
 #include "bchash.h"
@@ -223,7 +223,12 @@ BC_WindowBase::~BC_WindowBase()
                }
                else
 #endif
+               {
+// _XftDisplayInfo needs a lock.
+                       get_resources()->create_window_lock->lock("BC_WindowBase::~BC_WindowBase");
                        XCloseDisplay(display);
+                       get_resources()->create_window_lock->unlock();
+               }
 // clipboard uses a different display connection
                clipboard->stop_clipboard();
                delete clipboard;
@@ -326,16 +331,24 @@ int BC_WindowBase::initialize()
 #ifdef HAVE_LIBXXF86VM
        vm_switched = 0;
 #endif
-       smallfont_xft = 0;
-       bold_largefont_xft = 0;
-       bold_mediumfont_xft = 0;
-       bold_smallfont_xft = 0;
        input_method = 0;
        input_context = 0;
 
+       smallfont = 0;
+       mediumfont = 0;
+       largefont = 0;
+       bigfont = 0;
+       clockfont = 0;
+
+       smallfont_xft = 0;
        mediumfont_xft = 0;
        largefont_xft = 0;
        bigfont_xft = 0;
+       clockfont_xft = 0;
+
+       bold_smallfont_xft = 0;
+       bold_mediumfont_xft = 0;
+       bold_largefont_xft = 0;
 #ifdef SINGLE_THREAD
        completion_lock = new Condition(0, "BC_WindowBase::completion_lock");
 #else
@@ -2298,6 +2311,10 @@ int BC_WindowBase::init_fonts()
                if( !(bigfont = XLoadQueryFont(display, _(resources.big_font2))) )
                        bigfont = XLoadQueryFont(display, "fixed");
 
+       if((clockfont = XLoadQueryFont(display, _(resources.clock_font))) == NULL)
+               if((clockfont = XLoadQueryFont(display, _(resources.clock_font2))) == NULL)
+                       clockfont = XLoadQueryFont(display, "fixed");
+
        init_xft();
        if(get_resources()->use_fontset)
        {
@@ -2316,8 +2333,11 @@ int BC_WindowBase::init_fonts()
                        largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
                bigfontset = XCreateFontSet(display, resources.big_fontset, &m, &n, &d);
                if( !bigfontset )
-                       largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
-               if(bigfontset && largefontset && mediumfontset && smallfontset) {
+                       bigfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
+               clockfontset = XCreateFontSet(display, resources.clock_fontset, &m, &n, &d);
+               if( !clockfontset )
+                       clockfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
+               if(clockfontset && bigfontset && largefontset && mediumfontset && smallfontset) {
                        curr_fontset = mediumfontset;
                        get_resources()->use_fontset = 1;
                }
@@ -2362,6 +2382,12 @@ void BC_WindowBase::init_xft()
                if(!(bigfont_xft =
                        XftFontOpenXlfd(display, screen, resources.big_font_xft2)))
                        bigfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+       if(!(clockfont_xft =
+               (resources.clock_font_xft[0] == '-' ?
+                       XftFontOpenXlfd(display, screen, resources.clock_font_xft) :
+                       XftFontOpenName(display, screen, resources.clock_font_xft))) )
+               clockfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+
 
        if(!(bold_smallfont_xft =
                (resources.small_b_font_xft[0] == '-' ?
@@ -2379,21 +2405,24 @@ void BC_WindowBase::init_xft()
                        XftFontOpenName(display, screen, resources.large_b_font_xft))) )
                bold_largefont_xft = XftFontOpenXlfd(display, screen, "fixed");
 
-// Extension failed to locate fonts
        if( !smallfont_xft || !mediumfont_xft || !largefont_xft || !bigfont_xft ||
-           !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ) {
+           !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ||
+           !clockfont_xft ) {
                printf("BC_WindowBase::init_fonts: no xft fonts found:"
-                       " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n",
+                       " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n",
                        resources.small_font_xft, smallfont_xft,
                        resources.medium_font_xft, mediumfont_xft,
                        resources.large_font_xft, largefont_xft,
                        resources.big_font_xft, bigfont_xft,
+                       resources.clock_font_xft, clockfont_xft,
                        resources.small_b_font_xft, bold_smallfont_xft,
                        resources.medium_b_font_xft, bold_mediumfont_xft,
                        resources.large_b_font_xft, bold_largefont_xft);
                get_resources()->use_xft = 0;
                exit(1);
        }
+// _XftDisplayInfo needs a lock.
+       XftDefaultHasRender(display);
 #endif // HAVE_XFT
 }
 
@@ -2744,6 +2773,7 @@ XFontStruct* BC_WindowBase::get_font_struct(int font)
                case MEDIUMFONT: return top_level->mediumfont; break;
                case LARGEFONT:  return top_level->largefont;  break;
                case BIGFONT:    return top_level->bigfont;    break;
+               case CLOCKFONT:  return top_level->clockfont;  break;
        }
        return 0;
 }
@@ -2759,6 +2789,7 @@ XFontSet BC_WindowBase::get_fontset(int font)
                        case MEDIUMFONT: fs = top_level->mediumfontset; break;
                        case LARGEFONT:  fs = top_level->largefontset; break;
                        case BIGFONT:    fs = top_level->bigfontset;   break;
+                       case CLOCKFONT: fs = top_level->clockfontset; break;
                }
        }
 
@@ -2773,6 +2804,7 @@ XftFont* BC_WindowBase::get_xft_struct(int font)
                case MEDIUMFONT:   return (XftFont*)top_level->mediumfont_xft;
                case LARGEFONT:    return (XftFont*)top_level->largefont_xft;
                case BIGFONT:      return (XftFont*)top_level->bigfont_xft;
+               case CLOCKFONT:    return (XftFont*)top_level->clockfont_xft;
                case MEDIUMFONT_3D: return (XftFont*)top_level->bold_mediumfont_xft;
                case SMALLFONT_3D:  return (XftFont*)top_level->bold_smallfont_xft;
                case LARGEFONT_3D:  return (XftFont*)top_level->bold_largefont_xft;
@@ -2783,13 +2815,6 @@ XftFont* BC_WindowBase::get_xft_struct(int font)
 #endif
 
 
-
-
-
-
-
-
-
 int BC_WindowBase::get_current_font()
 {
        return top_level->current_font;
@@ -2825,6 +2850,7 @@ void BC_WindowBase::set_fontset(int font)
                        case MEDIUMFONT: fs = top_level->mediumfontset; break;
                        case LARGEFONT:  fs = top_level->largefontset; break;
                        case BIGFONT:    fs = top_level->bigfontset;   break;
+                       case CLOCKFONT:  fs = top_level->clockfontset; break;
                }
        }
 
index 263fa657c864b978970fc57e1526f30d27e462a3..2c25dc1feb0bdf9fe3a255eee4f9afdbf11ec7a5 100644 (file)
@@ -743,19 +743,17 @@ private:
 
 
 // Font sets
-    XFontSet smallfontset, mediumfontset, largefontset, bigfontset, curr_fontset;
-
+       XFontSet smallfontset, mediumfontset, largefontset, bigfontset, clockfontset;
+       XFontSet curr_fontset;
 // Fonts
        int current_font;
-       XFontStruct *smallfont, *mediumfont, *largefont, *bigfont;
-
+       XFontStruct *smallfont, *mediumfont, *largefont, *bigfont, *clockfont;
 // Must be void so users don't need to include the wrong libpng version.
-       void *smallfont_xft, *mediumfont_xft, *largefont_xft, *bigfont_xft;
-
+       void *smallfont_xft, *mediumfont_xft, *largefont_xft, *bigfont_xft, *clockfont_xft;
+       void *bold_smallfont_xft, *bold_mediumfont_xft, *bold_largefont_xft;
 
        int line_width;
        int line_dashes;
-       void *bold_largefont_xft, *bold_mediumfont_xft, *bold_smallfont_xft;
        int64_t current_color;
 // Coordinate of drag start
        int drag_x, drag_y;
index cd28636f19c15e307c05627657cd01062e156341..6a8412dedc0c06c6a5afcdbdfc19b1fc02ae8ced 100644 (file)
@@ -28,7 +28,7 @@
 #include "bctimer.h"
 #include "bcwindowbase.h"
 #include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "cursors.h"
 #include "fonts.h"
 #include "vframe.h"
@@ -947,7 +947,7 @@ void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap,
 // Hide cursor if video enabled
        update_video_cursor();
 
-//printf("BC_WindowBase::draw_bitmap 1\n");
+//printf("BC_WindowBase::draw_bitmap %d dest_y=%d\n", __LINE__, dest_y);
        if(dest_w <= 0 || dest_h <= 0)
        {
 // Use hardware scaling to canvas dimensions if proper color model.
index f9ea98c27cd2eb88a9f60896aded397e7954ccf3..b5662aeb499c8988341dd1edc63c148fe44aa595 100644 (file)
@@ -25,8 +25,9 @@
 #define SMALLFONT  1
 #define MEDIUMFONT 2
 #define LARGEFONT  3
-#define MEDIUM_7SEGMENT 4
-#define BIGFONT 5
+#define BIGFONT    4
+#define CLOCKFONT  5
+#define MEDIUM_7SEGMENT 6 // no longer used
 
 // Specialized fonts not available in every widget
 #define BOLDFACE    0x8000
index fe3dffde40eceb5c84ae4747a689bd6b2070ad8a..62a37d93b999d2986882ddf5c2e2f4aecd7799fb 100644 (file)
@@ -55,7 +55,7 @@
 #include "bctoggle.h"
 #include "bctumble.h"
 #include "bcwindow.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "bctimer.h"
 #include "errorbox.h"
index a878a19d01c82179b02cb4f3eb5f58189b136510..23535cd167297fc7e1543be6946be88666d58661 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "bcwindow.h"
 #include "bcsignals.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 #include "thread.h"
 #include "vframe.h"
index fdd24ce02a35f85e8a6b46552961c9272a203057..2573e56b334af163db07d684965901fbf49c3248 100644 (file)
@@ -1050,6 +1050,18 @@ void VFrame::flip_horiz()
 
 int VFrame::copy_from(VFrame *frame)
 {
+       if(this->w != frame->get_w() ||
+               this->h != frame->get_h())
+       {
+               printf("VFrame::copy_from %d sizes differ src %dx%d != dst %dx%d\n",
+                       __LINE__,
+                       frame->get_w(),
+                       frame->get_h(),
+                       get_w(),
+                       get_h());
+               return 1;
+       }
+
        int w = MIN(this->w, frame->get_w());
        int h = MIN(this->h, frame->get_h());
        timestamp = frame->timestamp;
@@ -1660,6 +1672,7 @@ void VFrame::smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3)
        }
 }
 
+
 void VFrame::draw_rect(int x1, int y1, int x2, int y2)
 {
        draw_line(x1, y1, x2, y1);
@@ -1668,6 +1681,52 @@ void VFrame::draw_rect(int x1, int y1, int x2, int y2)
        draw_line(x1, y2 - 1, x1, y1 + 1);
 }
 
+
+void VFrame::draw_oval(int x1, int y1, int x2, int y2)
+{
+       int w = x2 - x1;
+       int h = y2 - y1;
+       int center_x = (x2 + x1) / 2;
+       int center_y = (y2 + y1) / 2;
+       int x_table[h / 2];
+
+//printf("VFrame::draw_oval %d %d %d %d %d\n", __LINE__, x1, y1, x2, y2);
+
+       for(int i = 0; i < h / 2; i++) {
+// A^2 = -(B^2) + C^2
+               x_table[i] = (int)(sqrt(-SQR(h / 2 - i) + SQR(h / 2)) * w / h);
+//printf("VFrame::draw_oval %d i=%d x=%d\n", __LINE__, i, x_table[i]);
+       }
+
+       for(int i = 0; i < h / 2 - 1; i++) {
+               int x3 = x_table[i];
+               int x4 = x_table[i + 1];
+
+               if(x4 > x3 + 1) {
+                       for(int j = x3; j < x4; j++) {
+                               draw_pixel(center_x + j, y1 + i);
+                               draw_pixel(center_x - j, y1 + i);
+                               draw_pixel(center_x + j, y2 - i - 1);
+                               draw_pixel(center_x - j, y2 - i - 1);
+                       }
+               }
+               else {
+                       draw_pixel(center_x + x3, y1 + i);
+                       draw_pixel(center_x - x3, y1 + i);
+                       draw_pixel(center_x + x3, y2 - i - 1);
+                       draw_pixel(center_x - x3, y2 - i - 1);
+               }
+       }
+       
+       draw_pixel(center_x, y1);
+       draw_pixel(center_x, y2 - 1);
+       draw_pixel(x1, center_y);
+       draw_pixel(x2 - 1, center_y);
+       draw_pixel(x1, center_y - 1);
+       draw_pixel(x2 - 1, center_y - 1);
+}
+
+
 void VFrame::draw_arrow(int x1, int y1, int x2, int y2, int sz)
 {
        double angle = atan((float)(y2 - y1) / (float)(x2 - x1));
index 44695ba7074c5053e24b746997b27df79eaa698b..951e0364b92869a55df2da2f957dbdb1fcdc323b 100644 (file)
@@ -354,6 +354,7 @@ public:
        void draw_arrow(int x1, int y1, int x2, int y2, int sz=10);
        void draw_x(int x1, int y1, int sz=2);
        void draw_t(int x1, int y1, int sz=2);
+       void draw_oval(int x1, int y1, int x2, int y2);
 
 // 3D scene graphs
 // Not integrated with shmem because that only affects codecs
index 9f8d93ccc105be9d65c69b57f2e5c2e471f53943..e9a71b154fae09ee47ef23992ce11d84d571d679 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "bctimer.h"
 #include "bcwindow.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "keys.h"
 #include "mutex.h"
 #include "condition.h"
index 9a663219292448862887789db3042a4f76636d23..39a72d7dbc7044afd3256217b77d65c063528af0 100644 (file)
@@ -23,7 +23,7 @@ colors := brightness bluebanana C41 color3way colorbalance huesaturation \
        gamma gradient histogram histogram_bezier threshold
 
 plugin_dirs += exotic
-exotic := aging burn dot holo oil edge
+exotic := aging burn dot holo oil edge spherecam
 
 plugin_dirs += audio_tools
 audio_tools := audioscope cdripper compressor dcoffset delayaudio \
index 52ae7b0e7c21048329581206bece571d4b1e93dc..6006e07b0060fb634731c21b55296f67a0b858e4 100644 (file)
@@ -18,7 +18,7 @@
  *
  */
 #include "c41.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "clip.h"
 #include "edlsession.h"
 #include "filexml.h"
index 745f88083c25bf71430d1ab062a0c97166325584..bf9b83673424e97788bcecbcb6e013b490cf2f03 100644 (file)
@@ -120,6 +120,7 @@ DIRS = $(OPENCV_OBJS) \
        shiftinterlace \
        slide \
        spectrogram \
+       spherecam \
        svg \
        swapchannels \
        swapframes \
index 484b6cc9e2bc00eb390ff8c541329827a02fd580..129748d5022578ff079500af575ec4ec85995756 100644 (file)
@@ -27,7 +27,7 @@
 #include "bchash.h"
 #include "filexml.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "samples.h"
 #include "theme.h"
 #include "transportque.inc"
index 366418f34cdb364c6747f3c6df134c5233d9b089..364d70381f088dd4cb3542593e6e10df5af7bc87 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "bchash.inc"
 #include "bctimer.inc"
-#include "colors.h"
+#include "bccolors.h"
 #include "guicast.h"
 #include "mutex.h"
 #include "pluginaclient.h"
index 2f3399d5676e1a8187599bf0232268fcdc60927d..5e7b41038d68df86ea348399e9039b3857dc20e4 100644 (file)
@@ -35,7 +35,7 @@
 #include "language.h"
 #include "loadbalance.h"
 #include "playback3d.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.h"
 #include "workarounds.h"
 
index f96cba93047b0281a0ed3ae384b7f5bdf4fd3d16..556b6232e6ee16718c251467e335686feb525bf4 100644 (file)
@@ -29,7 +29,7 @@ class BluebananaThread;
 #include "bluebananaconfig.h"
 #include "bluebananawindow.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 
 #define SELECT_LOOKUP_SIZE 1024
index 9e8f9fef24bad19a7d90713d820103f5a021bf12..35a8c2b73565f3dba256a4c781baceb4d070420d 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef BLUEBANANASLIDER_H
 #define BLUEBANANASLIDER_H
 
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "bluebanana.h"
 #include "bluebananawindow.h"
index 6f951a762a2e8811d4d6c0642b51467ea0c14242..b37c5a37ab9abeb82c22c4c1b07aa534868e14c7 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef BLUEBANANAWINDOW_H
 #define BLUEBANANAWINDOW_H
 
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "pluginserver.h"
 #include "mwindow.h"
index a8e255aca65e2680ebb341c8685fd3aa0ed158aa..a4eb7de0209b0807e635290b5174a9a339941d4c 100644 (file)
@@ -27,7 +27,7 @@ class BrightnessMain;
 
 #include "brightnesswindow.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 
 class BrightnessConfig
index 6878423aca406c4b93754c4439cda3687b4992ad..98261b20f293ca0c030cc288bd016a8571f6c765 100644 (file)
@@ -24,7 +24,7 @@
 #include "effecttv.h"
 #include "filexml.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "burn.h"
 #include "burnwindow.h"
 
index 402b40dcff912c7f34207215ab6ca060041b341f..22fbfc880506ddcf723508cb4d3f18cb4a5ac10b 100644 (file)
@@ -28,7 +28,7 @@ class BurnMain;
 #include "effecttv.inc"
 #include "loadbalance.h"
 #include "mutex.h"
-#include "cicolors.inc"
+#include "bccolors.inc"
 #include "pluginvclient.h"
 #include "burnwindow.h"
 #include <sys/types.h>
index 9d1926fc82ce83c66fde4233fe9860e8fcbcf73c..90934f3e9b27807a2990c2c7d06c0642f0f2834b 100644 (file)
@@ -30,7 +30,7 @@
 #include "language.h"
 #include "loadbalance.h"
 #include "playback3d.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
index 39ff594eb18d1f49036a7b99ffc8e2aeed9b1fcb..5558606b34953619fba1bb568ff7dd13bd24814c 100644 (file)
@@ -30,7 +30,7 @@
 #include "language.h"
 #include "loadbalance.h"
 #include "playback3d.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
index f11f6f70eebc22dc772db7c850e4afac7de59a84..d771acc0d3d804f605b56501db98d2eeeae903a5 100644 (file)
@@ -34,7 +34,7 @@ class Color3WayEngine;
 
 #include "color3waywindow.h"
 #include "condition.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "guicast.h"
 #include "loadbalance.h"
 #include "pluginvclient.h"
index c8a924edec66330af2992d7bbbabdf7cfd69f6c8..69b5923a26b9dd8b7d8c6f53cbae52660e0f3f09 100644 (file)
@@ -26,7 +26,7 @@ class ColorBalanceMain;
 
 #include "colorbalancewindow.h"
 #include "condition.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "guicast.h"
 #include "pluginvclient.h"
 #include "thread.h"
index 6b942d5d95d13bc4f52b069260db568adfe8791f..b3e7592bddcd655eaa5494cbf4697b01ebea9041 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "arraylist.h"
 #include "bccmodels.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "clip.h"
 #include "edlsession.h"
 #include "filexml.h"
index 9ad9850b8d9f90f7a570b9c55e88068d695528ec..118b7f38e8d31585a39c3594a48890061dc43235 100644 (file)
@@ -29,7 +29,7 @@
 #include "guicast.h"
 #include "language.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 
 
index 58f8cf00b5191ed4a6bf6291baa603e5dd1f9bd0..d8b426d06d85a8fe250db210c3cc068028c8062f 100644 (file)
@@ -25,7 +25,7 @@
 #include "bchash.h"
 #include "filexml.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "samples.h"
 #include "echo.h"
 #include "theme.h"
index 80787f40ae37e54f66449d786cd49e8c79413075..b0cf73dd9365d4464beb8d63da822bbee09e48c4 100644 (file)
@@ -25,7 +25,7 @@
 #include "bchash.h"
 #include "filexml.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "samples.h"
 #include "echocancel.h"
 #include "theme.h"
index 6348eb470f7e3ec617fb7c27d1d71ebaa79ec82c..737167e5c48aab20fd527e45301ecb98b5ac268c 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include "affine.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "clip.h"
 #include "filexml.h"
 #include "language.h"
index f0fd559d11391ac427e69f501e9e7ef91df2bec2..28d04fc5b71a8365ca368e4611861d21ec1a1fdc 100644 (file)
@@ -25,7 +25,7 @@
 #include "gamma.h"
 #include "bchash.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "../interpolate/aggregated.h"
 #include "playback3d.h"
 #include "workarounds.h"
index fe5881fc8d97ad5a04875fa62cffc81b10c467f1..21cef58701be8f73ba2c149d872fced294091e0f 100644 (file)
@@ -27,7 +27,7 @@ class GammaMain;
 
 #include "gammawindow.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "guicast.h"
 #include "pluginvclient.h"
 #include "thread.h"
index 736e975af0b156ae1536d8b12e2b66512bcfdcc9..4d68f945a9deafb06cc96e8d7383ef173e13508d 100644 (file)
@@ -37,7 +37,7 @@ class GradientServer;
 #include "guicast.h"
 #include "loadbalance.h"
 #include "overlayframe.inc"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "thread.h"
 #include "vframe.inc"
index 4acc0c7bab1cb7ebc2789dc2a648448c8ef05a9d..fd2cdc86b5f2d35a89eb67a90ea58f11c8858965 100644 (file)
@@ -36,7 +36,7 @@
 #include "language.h"
 #include "loadbalance.h"
 #include "playback3d.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.h"
 #include "workarounds.h"
 
index 6d5d8e28c55bbe11f708c360d5512460463bf058..317c1beb712c1877b573f1ca3d38e1043ea4cb4c 100644 (file)
@@ -27,7 +27,7 @@
 #include "histogramconfig.h"
 #include "histogramwindow.inc"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 
 
index 53ebceeb3f57b6a07adf338505f839e37acd0dce..23688b183a043b1f32c9487659857cc0dd8529be 100644 (file)
@@ -35,7 +35,7 @@
 #include "keyframe.h"
 #include "language.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.h"
 
 
index 935e1282195744b4615b558c10fb1b3830284c56..97f3152062c06e4ad20ff872adb35bc7048aec9a 100644 (file)
@@ -27,7 +27,7 @@
 #include "bistogramconfig.h"
 #include "bistogramwindow.inc"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 
 
index fb034b4d00e933d430f1b4f87b9bb2a9f7dda677..61a8c0d2a859271a0df91711135308a3c255d915 100644 (file)
@@ -26,7 +26,7 @@
 #include "holo.h"
 #include "holowindow.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 
 #include <stdint.h>
 #include <stdio.h>
index 668d2b5e4bff45a9a5f93a3de15d2237517f4f8d..37dbb0b10ad6bbd1d63415cbc33a1a37be74cca1 100644 (file)
@@ -30,7 +30,7 @@ class HoloEngine;
 #include "holowindow.h"
 #include "loadbalance.h"
 #include "mutex.h"
-#include "cicolors.inc"
+#include "bccolors.inc"
 #include "pluginvclient.h"
 
 #include <stdint.h>
index 58dca39c90e0472d1b9f8b28d8906cfb77d6132e..f7f04f24c130c9c6ee6f07b2a601f0066b20bd37 100644 (file)
@@ -26,7 +26,7 @@
 #include "guicast.h"
 #include "language.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "playback3d.h"
 #include "pluginvclient.h"
 #include "vframe.h"
index 4c130eca4893f0966318a5d75952d4a778b168be..64fa589b188d109aef4ed3e7b28520977a4a9d94 100644 (file)
@@ -167,7 +167,7 @@ InterpolatePixelsMain::~InterpolatePixelsMain()
        delete engine;
 }
 
-const char* InterpolatePixelsMain::plugin_title() { return _("Interpolate Pixels"); }
+const char* InterpolatePixelsMain::plugin_title() { return _("Interpolate Bayer"); }
 int InterpolatePixelsMain::is_realtime() { return 1; }
 
 
@@ -400,6 +400,13 @@ void InterpolatePixelsUnit::process_package(LoadPackage *package)
        float color_matrix[9];
        memcpy(color_matrix, server->color_matrix, sizeof(color_matrix));
 
+// printf("InterpolatePixelsUnit::process_package %d color_matrix=", __LINE__);
+// for(int i = 0; i < 9; i++)
+// {
+//     printf("%f ", color_matrix[i]);
+// }
+// printf("\n");
+
        y1 = MAX(y1, 1);
        y2 = MIN(y2, h - 1);
 
@@ -451,9 +458,14 @@ void InterpolatePixelsUnit::process_package(LoadPackage *package)
                                        b = current_row[BLUE];
                                }
 
-                               out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2];
-                               out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5];
-                               out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8];
+//                             out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2];
+//                             out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5];
+//                             out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8];
+
+                               out_row[0] = r;
+                               out_row[1] = g;
+                               out_row[2] = b;
+
                                prev_row += components;
                                current_row += components;
                                next_row += components;
@@ -486,9 +498,14 @@ void InterpolatePixelsUnit::process_package(LoadPackage *package)
                                        b = (prev_row[BLUE] + next_row[BLUE]) / 2;
                                }
 
-                               out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2];
-                               out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5];
-                               out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8];
+//                             out_row[0] = r * color_matrix[0] + g * color_matrix[1] + b * color_matrix[2];
+//                             out_row[1] = r * color_matrix[3] + g * color_matrix[4] + b * color_matrix[5];
+//                             out_row[2] = r * color_matrix[6] + g * color_matrix[7] + b * color_matrix[8];
+
+                               out_row[0] = r;
+                               out_row[1] = g;
+                               out_row[2] = b;
+
                                prev_row += components;
                                current_row += components;
                                next_row += components;
@@ -514,6 +531,10 @@ void InterpolatePixelsEngine::init_packages()
        char string[BCTEXTLEN];
        string[0] = 0;
        plugin->get_output()->get_params()->get("DCRAW_MATRIX", string);
+
+// printf("InterpolatePixelsEngine::init_packages %d\n", __LINE__);
+// plugin->get_output()->dump_params();
+
        sscanf(string,
                "%f %f %f %f %f %f %f %f %f",
                &color_matrix[0],
index 3b50feb2271a55ecd9bfce5302083df399a91b95..1993a6a0732cff52478fafc62d4923f22e9e1e7e 100644 (file)
@@ -3,10 +3,9 @@ include ../../plugin_defs
 OBJS = $(OBJDIR)/interpolatevideo.o \
        $(OBJDIR)/interpolatewindow.o \
        $(OBJDIR)/opticflow.o \
+       $(OBJDIR)/motioncache-hv.o \
        $(OBJDIR)/motionscan-hv.o
 
-CFLAGS += -DMotionScan=MotionHVScan
-
 PLUGIN = interpolatevideo
 
 include ../../plugin_config
@@ -15,4 +14,5 @@ include ../../plugin_config
 $(OBJDIR)/interpolatevideo.o: interpolatevideo.C
 $(OBJDIR)/interpolatewindow.o: interpolatewindow.C
 $(OBJDIR)/opticflow.o: opticflow.C
+$(OBJDIR)/motionscan-hv.o: motioncache-hv.C motioncache-hv.h
 $(OBJDIR)/motionscan-hv.o: motionscan-hv.C motionscan-hv.h
index 9e553ac3e70d5168b699836beb6070730db25990..6eab87b3140eac32af196c9e8000a8f167d38f19 100644 (file)
@@ -326,6 +326,11 @@ void InterpolateVideo::create_macroblocks()
 // Get macroblock size
        x_macroblocks = frames[0]->get_w() / config.macroblock_size;
        y_macroblocks = frames[0]->get_h() / config.macroblock_size;
+// printf("InterpolateVideo::create_macroblocks %d %d %d %d\n", 
+// __LINE__, 
+// config.macroblock_size,
+// x_macroblocks,
+// y_macroblocks);
 
        if(config.macroblock_size * x_macroblocks < frames[0]->get_w())
        {
diff --git a/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.C b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.C
new file mode 120000 (symlink)
index 0000000..5e5d9aa
--- /dev/null
@@ -0,0 +1 @@
+../motion-hv/motioncache-hv.C
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.h b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.h
new file mode 120000 (symlink)
index 0000000..d6ebb12
--- /dev/null
@@ -0,0 +1 @@
+../motion-hv/motioncache-hv.h
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.inc b/cinelerra-5.1/plugins/interpolatevideo/motioncache-hv.inc
new file mode 120000 (symlink)
index 0000000..d59d139
--- /dev/null
@@ -0,0 +1 @@
+../motion-hv/motioncache-hv.inc
\ No newline at end of file
index bf8a6762f1c50bff78b7e4421e9bf333459939ea..83414c07115f62db3c316d28634ed152f2de8444 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "clip.h"
 #include "interpolatevideo.h"
+#include "motioncache-hv.h"
 #include "motionscan-hv.h"
 #include "opticflow.h"
 
@@ -92,9 +93,11 @@ void OpticFlowUnit::process_package(LoadPackage *package)
        struct timeval start_time;
        gettimeofday(&start_time, 0);
 
-       if(!motion) motion = new MotionScan(1, 1);
+       if(!motion) motion = new MotionHVScan(1, 1);
 
        motion->set_test_match(0);
+       motion->set_cache(server->downsample_cache);
+       
 // printf("OpticFlowUnit::process_package %d %d %d\n",
 // __LINE__,
 // pkg->macroblock0,
@@ -103,6 +106,7 @@ void OpticFlowUnit::process_package(LoadPackage *package)
        for(int i = pkg->macroblock0; i < pkg->macroblock1; i++)
        {
                OpticFlowMacroblock *mb = plugin->macroblocks.get(i);
+//printf("OpticFlowUnit::process_package %d i=%d x=%d y=%d\n", __LINE__, i, mb->x, mb->y);
                motion->scan_frame(plugin->frames[0],
 // Frame after motion
                        plugin->frames[1],
@@ -112,10 +116,10 @@ void OpticFlowUnit::process_package(LoadPackage *package)
                        plugin->config.macroblock_size,
                        mb->x,
                        mb->y,
-                       MotionScan::TRACK_PREVIOUS,
-                       MotionScan::CALCULATE,
+                       MotionHVScan::TRACK_PREVIOUS,
+                       MotionHVScan::CALCULATE,
 // Get it to do the subpixel step
-                       MotionScan::STABILIZE,
+                       MotionHVScan::STABILIZE,
                        0,
                        0,
                        0,
@@ -127,6 +131,7 @@ void OpticFlowUnit::process_package(LoadPackage *package)
                        0,
                        0,
                        0);
+//printf("OpticFlowUnit::process_package 2\n", __LINE__);
 
 
                mb->dx = motion->dx_result;
@@ -157,21 +162,39 @@ OpticFlow::OpticFlow(InterpolateVideo *plugin,
        total_packages)
 {
        this->plugin = plugin;
+       downsample_cache = 0;
 }
 
 
 OpticFlow::~OpticFlow()
 {
+       if(downsample_cache)
+       {
+//printf("OpticFlow::~OpticFlow %d %p\n", __LINE__, downsample_cache);
+               delete downsample_cache;
+       }
 }
 
 void OpticFlow::init_packages()
 {
-//printf("OpticFlow::init_packages %d %d\n", __LINE__, get_total_packages());
+       if(!downsample_cache)
+       {
+               downsample_cache = new MotionHVCache();
+       }
+       
+       downsample_cache->clear();
+
        for(int i = 0; i < get_total_packages(); i++)
        {
                OpticFlowPackage *pkg = (OpticFlowPackage*)get_package(i);
                pkg->macroblock0 = plugin->total_macroblocks * i / get_total_packages();
                pkg->macroblock1 = plugin->total_macroblocks * (i + 1) / get_total_packages();
+// printf("OpticFlow::init_packages %d %d %d %d %d\n", 
+// __LINE__, 
+// plugin->total_macroblocks,
+// get_total_packages(),
+// pkg->macroblock0,
+// pkg->macroblock1);
        }
 }
 
index 6e611fc515a2f2382d4e12f9835ab35eaf8f1c31..5a0dbefb490f1d4fa0f301e6e41d58e7d900bcda 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "interpolatevideo.inc"
 #include "loadbalance.h"
+#include "motioncache-hv.inc"
 #include "motionscan-hv.inc"
 #include "opticflow.inc"
 
@@ -57,7 +58,7 @@ public:
        OpticFlowUnit(OpticFlow *server);
        ~OpticFlowUnit();
        void process_package(LoadPackage *package);
-       MotionScan *motion;
+       MotionHVScan *motion;
        OpticFlow *server;
 };
 
@@ -73,6 +74,7 @@ public:
        LoadClient* new_client();
        LoadPackage* new_package();
        InterpolateVideo *plugin;
+       MotionHVCache *downsample_cache;
 };
 
 
index 309776b3f2dcff7ebf90924956ef94141453c1ee..078f48f86a4eb30d25af6735c78b4a5b690a249f 100644 (file)
@@ -25,7 +25,7 @@
 #include "filexml.h"
 #include "guicast.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
index 5da0a4b16de46544b640c9fe4c08abbef7705ebd..60f2c8a990fa236fda51213c63da4b2850ccda86 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "bccmodels.h"
 #include "effecttv.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.h"
 
 #include <stdint.h>
index af8368f39a42e7f206699a64bfd01154703b14ef..473a4240f3be22751bba9e1366301c11659b5b0d 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef EFFECTTV_H
 #define EFFECTTV_H
 
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.inc"
 #include <stdint.h>
 
index 695fd5ee5bcf510a20b2fd5dfb810fbd458c1db4..b8c2ffbce9ec43f75782ede8e06d3a3474106b20 100644 (file)
@@ -2,6 +2,7 @@ include ../../plugin_defs
 
 OBJS := \
        $(OBJDIR)/motion-hv.o \
+       $(OBJDIR)/motioncache-hv.o \
        $(OBJDIR)/motionscan-hv.o \
        $(OBJDIR)/motionwindow-hv.o
 
@@ -10,5 +11,6 @@ PLUGIN = motion-hv
 include ../../plugin_config
 
 $(OBJDIR)/motion-hv.o: motion-hv.C
+$(OBJDIR)/motioncache-hv.o: motioncache-hv.C
 $(OBJDIR)/motionscan-hv.o: motionscan-hv.C
 $(OBJDIR)/motionwindow-hv.o: motionwindow-hv.C
index ea339d9217ca08bb8a4af74b14fb75db2182d2dd..b61c654a2d9aa9bbb98518b56124ee7f0e921ec9 100644 (file)
@@ -120,7 +120,8 @@ int MotionHVConfig::equivalent(MotionHVConfig &that)
                track_frame == that.track_frame &&
                bottom_is_master == that.bottom_is_master &&
                horizontal_only == that.horizontal_only &&
-               vertical_only == that.vertical_only;
+               vertical_only == that.vertical_only &&
+               tracking_type == that.tracking_type;
 }
 
 void MotionHVConfig::copy_from(MotionHVConfig &that)
diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C
new file mode 100644 (file)
index 0000000..98722de
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * CINELERRA
+ * Copyright (C) 2016 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+
+
+// store previously scaled images here for operations 
+// with multiple motion scans on the same frame.
+
+
+#include "bcsignals.h"
+#include "clip.h"
+#include "motioncache-hv.h"
+#include "mutex.h"
+#include <stdint.h>
+#include "vframe.h"
+
+
+MotionHVCacheItem::MotionHVCacheItem()
+{
+}
+
+MotionHVCacheItem::~MotionHVCacheItem()
+{
+//printf("MotionHVCacheItem::~MotionHVCacheItem %d image=%p\n", __LINE__, image);
+       if(image)
+       {
+               delete image;
+       }
+}
+
+
+
+MotionHVCache::MotionHVCache()
+{
+       lock = new Mutex("MotionHVCache::lock");
+}
+
+MotionHVCache::~MotionHVCache()
+{
+//printf("MotionHVCache::~MotionHVCache %d this=%p\n", __LINE__, this);
+
+       delete lock;
+       clear();
+}
+
+void MotionHVCache::clear()
+{
+       images.remove_all_objects();
+}
+
+
+
+#define DOWNSAMPLE(type, temp_type, components, max) \
+{ \
+       temp_type r; \
+       temp_type g; \
+       temp_type b; \
+       temp_type a; \
+       type **in_rows = (type**)src->get_rows(); \
+       type **out_rows = (type**)dst->get_rows(); \
+ \
+       for(int i = 0; i < h; i += downsample) \
+       { \
+               int y1 = MAX(i, 0); \
+               int y2 = MIN(i + downsample, h); \
+ \
+ \
+               for(int j = 0; \
+                       j < w; \
+                       j += downsample) \
+               { \
+                       int x1 = MAX(j, 0); \
+                       int x2 = MIN(j + downsample, w); \
+ \
+                       temp_type scale = (x2 - x1) * (y2 - y1); \
+                       if(x2 > x1 && y2 > y1) \
+                       { \
+ \
+/* Read in values */ \
+                               r = 0; \
+                               g = 0; \
+                               b = 0; \
+                               if(components == 4) a = 0; \
+ \
+                               for(int k = y1; k < y2; k++) \
+                               { \
+                                       type *row = in_rows[k] + x1 * components; \
+                                       for(int l = x1; l < x2; l++) \
+                                       { \
+                                               r += *row++; \
+                                               g += *row++; \
+                                               b += *row++; \
+                                               if(components == 4) a += *row++; \
+                                       } \
+                               } \
+ \
+/* Write average */ \
+                               r /= scale; \
+                               g /= scale; \
+                               b /= scale; \
+                               if(components == 4) a /= scale; \
+ \
+                               type *row = out_rows[y1 / downsample] + \
+                                       x1 / downsample * components; \
+                               *row++ = r; \
+                               *row++ = g; \
+                               *row++ = b; \
+                               if(components == 4) *row++ = a; \
+                       } \
+               } \
+/*printf("DOWNSAMPLE 3 %d\n", i);*/ \
+       } \
+}
+
+
+
+
+void MotionHVCache::downsample_frame(VFrame *dst, 
+       VFrame *src, 
+       int downsample)
+{
+       int h = src->get_h();
+       int w = src->get_w();
+
+//PRINT_TRACE
+//printf("downsample=%d w=%d h=%d dst=%d %d\n", downsample, w, h, dst->get_w(), dst->get_h());
+       switch(src->get_color_model())
+       {
+               case BC_RGB888:
+                       DOWNSAMPLE(uint8_t, int64_t, 3, 0xff)
+                       break;
+               case BC_RGB_FLOAT:
+                       DOWNSAMPLE(float, float, 3, 1.0)
+                       break;
+               case BC_RGBA8888:
+                       DOWNSAMPLE(uint8_t, int64_t, 4, 0xff)
+                       break;
+               case BC_RGBA_FLOAT:
+                       DOWNSAMPLE(float, float, 4, 1.0)
+                       break;
+               case BC_YUV888:
+                       DOWNSAMPLE(uint8_t, int64_t, 3, 0xff)
+                       break;
+               case BC_YUVA8888:
+                       DOWNSAMPLE(uint8_t, int64_t, 4, 0xff)
+                       break;
+       }
+//PRINT_TRACE
+}
+
+VFrame* MotionHVCache::get_image(int ratio, 
+       int is_previous,
+       int downsampled_w,
+       int downsampled_h,
+       VFrame *src)
+{
+       lock->lock("MotionHVCache::get_image 1");
+       
+       for(int i = 0; i < images.size(); i++)
+       {
+               if(images.get(i)->ratio == ratio &&
+                       images.get(i)->is_previous == is_previous)
+               {
+                       VFrame *result = images.get(i)->image;
+                       lock->unlock();
+                       return result;
+               }
+       }
+
+
+//PRINT_TRACE
+       VFrame *result = new VFrame();
+       result->set_use_shm(0);
+       result->reallocate(0, 
+               -1,
+               0,
+               0,
+               0,
+               downsampled_w + 1, 
+               downsampled_h + 1, 
+               src->get_color_model(), 
+               -1);
+       downsample_frame(result, 
+               src, 
+               ratio);
+       
+       
+       MotionHVCacheItem *item = new MotionHVCacheItem();
+       item->image = result;
+       item->is_previous = is_previous;
+       item->ratio = ratio;
+       images.append(item);
+
+       lock->unlock();
+       
+       return result;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.h b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.h
new file mode 100644 (file)
index 0000000..f8813ce
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * CINELERRA
+ * Copyright (C) 2016 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+
+#ifndef MOTIONCACHE_HV_H
+#define MOTIONCACHE_HV_H
+
+// store previously scaled intermediates here for operations 
+// with multiple motion scans on the same frame.
+
+#include "arraylist.h"
+#include "mutex.inc"
+#include "vframe.inc"
+
+class MotionHVCacheItem
+{
+public:
+       MotionHVCacheItem();
+       ~MotionHVCacheItem();
+
+       VFrame *image;
+       int ratio;
+       int is_previous;
+};
+
+
+class MotionHVCache
+{
+public:
+       MotionHVCache();
+       ~MotionHVCache();
+       
+       VFrame *get_image(int ratio, 
+               int is_previous,
+               int downsampled_w,
+               int downsampled_h,
+               VFrame *src);
+       
+       void clear();
+
+       void downsample_frame(VFrame *dst, 
+               VFrame *src, 
+               int downsample);
+
+       ArrayList<MotionHVCacheItem*> images;
+       Mutex *lock;
+};
+
+
+
+
+
+#endif
+
+
diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.inc b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.inc
new file mode 100644 (file)
index 0000000..4ff4636
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef MOTIONCACHE_HV_INC
+#define MOTIONCACHE_HV_INC
+
+class MotionHVCache;
+
+#endif
+
+
index db8617eaf301f7d30726a49bbc637b89194eecd4..6c4d6e07145176648560cfb5bb1112a92dd9b32f 100644 (file)
@@ -22,6 +22,7 @@
 #include "affine.h"
 #include "bcsignals.h"
 #include "clip.h"
+#include "motioncache-hv.h"
 #include "motionscan-hv.h"
 #include "mutex.h"
 #include "vframe.h"
@@ -208,23 +209,24 @@ total_clients, total_packages
 )
 {
        test_match = 1;
-       downsampled_previous = 0;
-       downsampled_current = 0;
        rotated_current = 0;
        rotater = 0;
+       downsample_cache = 0;
+       shared_downsample = 0;
 }
 
 MotionHVScan::~MotionHVScan()
 {
-       delete downsampled_previous;
-       delete downsampled_current;
-       if(rotated_current)
-       {
-               for(int i = 0; i < total_rotated; i++)
-               {
+       if(downsample_cache && !shared_downsample) {
+               delete downsample_cache;
+               downsample_cache = 0;
+               shared_downsample = 0;
+       }
+
+       if(rotated_current) {
+               for(int i = 0; i < total_rotated; i++) {
                        delete rotated_current[i];
                }
-
                delete [] rotated_current;
        }
        delete rotater;
@@ -366,107 +368,13 @@ void MotionHVScan::set_test_match(int value)
        this->test_match = value;
 }
 
-
-
-
-#define DOWNSAMPLE(type, temp_type, components, max) \
-{ \
-       temp_type r; \
-       temp_type g; \
-       temp_type b; \
-       temp_type a; \
-       type **in_rows = (type**)src->get_rows(); \
-       type **out_rows = (type**)dst->get_rows(); \
- \
-       for(int i = 0; i < h; i += downsample) \
-       { \
-               int y1 = MAX(i, 0); \
-               int y2 = MIN(i + downsample, h); \
- \
- \
-               for(int j = 0; \
-                       j < w; \
-                       j += downsample) \
-               { \
-                       int x1 = MAX(j, 0); \
-                       int x2 = MIN(j + downsample, w); \
- \
-                       temp_type scale = (x2 - x1) * (y2 - y1); \
-                       if(x2 > x1 && y2 > y1) \
-                       { \
- \
-/* Read in values */ \
-                               r = 0; \
-                               g = 0; \
-                               b = 0; \
-                               if(components == 4) a = 0; \
- \
-                               for(int k = y1; k < y2; k++) \
-                               { \
-                                       type *row = in_rows[k] + x1 * components; \
-                                       for(int l = x1; l < x2; l++) \
-                                       { \
-                                               r += *row++; \
-                                               g += *row++; \
-                                               b += *row++; \
-                                               if(components == 4) a += *row++; \
-                                       } \
-                               } \
- \
-/* Write average */ \
-                               r /= scale; \
-                               g /= scale; \
-                               b /= scale; \
-                               if(components == 4) a /= scale; \
- \
-                               type *row = out_rows[y1 / downsample] + \
-                                       x1 / downsample * components; \
-                               *row++ = r; \
-                               *row++ = g; \
-                               *row++ = b; \
-                               if(components == 4) *row++ = a; \
-                       } \
-               } \
-/*printf("DOWNSAMPLE 3 %d\n", i);*/ \
-       } \
-}
-
-
-
-
-void MotionHVScan::downsample_frame(VFrame *dst,
-       VFrame *src,
-       int downsample)
+void MotionHVScan::set_cache(MotionHVCache *cache)
 {
-       int h = src->get_h();
-       int w = src->get_w();
-
-//PRINT_TRACE
-//printf("downsample=%d w=%d h=%d dst=%d %d\n", downsample, w, h, dst->get_w(), dst->get_h());
-       switch(src->get_color_model())
-       {
-               case BC_RGB888:
-                       DOWNSAMPLE(uint8_t, int64_t, 3, 0xff)
-                       break;
-               case BC_RGB_FLOAT:
-                       DOWNSAMPLE(float, float, 3, 1.0)
-                       break;
-               case BC_RGBA8888:
-                       DOWNSAMPLE(uint8_t, int64_t, 4, 0xff)
-                       break;
-               case BC_RGBA_FLOAT:
-                       DOWNSAMPLE(float, float, 4, 1.0)
-                       break;
-               case BC_YUV888:
-                       DOWNSAMPLE(uint8_t, int64_t, 3, 0xff)
-                       break;
-               case BC_YUVA8888:
-                       DOWNSAMPLE(uint8_t, int64_t, 4, 0xff)
-                       break;
-       }
-//PRINT_TRACE
+       this->downsample_cache = cache;
+       shared_downsample = 1;
 }
 
+
 double MotionHVScan::step_to_angle(int step, double center)
 {
        if(step < angle_steps / 2)
@@ -557,51 +465,29 @@ void MotionHVScan::pixel_search(int &x_result, int &y_result, double &r_result)
 
        if(current_downsample > 1)
        {
-               if(!downsampled_previous ||
-                       downsampled_previous->get_w() != downsampled_prev_w ||
-                       downsampled_previous->get_h() != downsampled_prev_h)
+               if(!downsample_cache)
                {
-                       delete downsampled_previous;
-                       downsampled_previous = new VFrame();
-                       downsampled_previous->set_use_shm(0);
-                       downsampled_previous->reallocate(0,
-                               -1,
-                               0,
-                               0,
-                               0,
-                               downsampled_prev_w + 1,
-                               downsampled_prev_h + 1,
-                               previous_frame_arg->get_color_model(),
-                               -1);
+                       downsample_cache = new MotionHVCache();
+                       shared_downsample = 0;
                }
 
-               if(!downsampled_current ||
-                       downsampled_current->get_w() != downsampled_current_w ||
-                       downsampled_current->get_h() != downsampled_current_h)
+
+               if(!shared_downsample)
                {
-                       delete downsampled_current;
-                       downsampled_current = new VFrame();
-                       downsampled_current->set_use_shm(0);
-                       downsampled_current->reallocate(0,
-                               -1,
-                               0,
-                               0,
-                               0,
-                               downsampled_current_w + 1,
-                               downsampled_current_h + 1,
-                               current_frame_arg->get_color_model(),
-                               -1);
+                       downsample_cache->clear();
                }
 
+               previous_frame = downsample_cache->get_image(current_downsample, 
+                       1,
+                       downsampled_prev_w,
+                       downsampled_prev_h,
+                       previous_frame_arg);
+               current_frame = downsample_cache->get_image(current_downsample, 
+                       0,
+                       downsampled_current_w,
+                       downsampled_current_h,
+                       current_frame_arg);
 
-               downsample_frame(downsampled_previous,
-                       previous_frame_arg,
-                       current_downsample);
-               downsample_frame(downsampled_current,
-                       current_frame_arg,
-                       current_downsample);
-               previous_frame = downsampled_previous;
-               current_frame = downsampled_current;
 
        }
        else
index 7511e64223b25d66a280e1f912cc102669a3ad4d..b9241c5955fc48fff25a2d34480199488d214ccb 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "affine.inc"
 #include "loadbalance.h"
+#include "motioncache-hv.inc"
 #include "vframe.inc"
 #include <stdint.h>
 
@@ -89,6 +90,7 @@ public:
        LoadPackage* new_package();
 // Test for identical frames before scanning
        void set_test_match(int value);
+       void set_cache(MotionHVCache *cache);
 
 // Invoke the motion engine for a search
 // Frame before motion
@@ -196,7 +198,8 @@ private:
                int color_model);
 
 
-
+       MotionHVCache *downsample_cache;
+       int shared_downsample;
        AffineEngine *rotater;
 // Pointer to downsampled frame before motion
        VFrame *previous_frame;
@@ -205,9 +208,6 @@ private:
 // Frames passed from user
        VFrame *previous_frame_arg;
        VFrame *current_frame_arg;
-// Downsampled frames
-       VFrame *downsampled_previous;
-       VFrame *downsampled_current;
 // rotated versions of current_frame
        VFrame **rotated_current;
 // allocation of rotated_current array, a copy of angle_steps
index 5a00398c627d9584cf251c8c78cec20baa0d3778..038095d1fc6e64e4074990b40b7c08d2e8a131ad 100644 (file)
@@ -2,6 +2,7 @@ include ../../plugin_defs
 
 OBJS := \
        $(OBJDIR)/downsampleengine.o \
+       $(OBJDIR)/motioncache-hv.o \
        $(OBJDIR)/motionscan-hv.o \
        $(OBJDIR)/motion.o \
        $(OBJDIR)/motionwindow.o
@@ -14,5 +15,6 @@ include ../../plugin_config
 
 $(OBJDIR)/downsampleengine.o: downsampleengine.C
 $(OBJDIR)/motion.o: motion.C
+$(OBJDIR)/motionscan-hv.o: motioncache-hv.C
 $(OBJDIR)/motionscan-hv.o: motionscan-hv.C
 $(OBJDIR)/motionwindow.o: motionwindow.C
diff --git a/cinelerra-5.1/plugins/motion2point/motioncache-hv.C b/cinelerra-5.1/plugins/motion2point/motioncache-hv.C
new file mode 120000 (symlink)
index 0000000..5e5d9aa
--- /dev/null
@@ -0,0 +1 @@
+../motion-hv/motioncache-hv.C
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/motion2point/motioncache-hv.h b/cinelerra-5.1/plugins/motion2point/motioncache-hv.h
new file mode 120000 (symlink)
index 0000000..d6ebb12
--- /dev/null
@@ -0,0 +1 @@
+../motion-hv/motioncache-hv.h
\ No newline at end of file
diff --git a/cinelerra-5.1/plugins/motion2point/motioncache-hv.inc b/cinelerra-5.1/plugins/motion2point/motioncache-hv.inc
new file mode 120000 (symlink)
index 0000000..d59d139
--- /dev/null
@@ -0,0 +1 @@
+../motion-hv/motioncache-hv.inc
\ No newline at end of file
index 92417a6c42badb6b08e787422632eae36f066bb3..eb60c71dff2617ebe371031fe35b231bc297eb9c 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -350,87 +350,91 @@ void Reverb::update_gui()
 {
        if(thread)
        {
-               thread->window->lock_window();
-               ((ReverbWindow*)thread->window)->level_init->update(config.level_init);
-               ((ReverbWindow*)thread->window)->delay_init->update(config.delay_init);
-               ((ReverbWindow*)thread->window)->ref_level1->update(config.ref_level1);
-               ((ReverbWindow*)thread->window)->ref_level2->update(config.ref_level2);
-               ((ReverbWindow*)thread->window)->ref_total->update(config.ref_total);
-               ((ReverbWindow*)thread->window)->ref_length->update(config.ref_length);
-               ((ReverbWindow*)thread->window)->lowpass1->update(config.lowpass1);
-               ((ReverbWindow*)thread->window)->lowpass2->update(config.lowpass2);
-               thread->window->unlock_window();
-       }
-}
-
-
-
-
-int Reverb::load_from_file(char *path)
-{
-       int result = 0;
-       int length;
-       char string[1024];
-
-       FILE *in = fopen(path, "rb");
-       if( in )
-       {
-               fseek(in, 0, SEEK_END);
-               length = ftell(in);
-               fseek(in, 0, SEEK_SET);
-               (void)fread(string, length, 1, in);
-               fclose(in);
-//             read_data(string);
-       }
-       else
-       {
-               perror("fopen:");
-// failed
-               ErrorBox errorbox("");
-               char string[1024];
-               sprintf(string, _("Couldn't open %s."), path);
-               errorbox.create_objects(string);
-               errorbox.run_window();
-               result = 1;
+               if(load_configuration())
+               {
+//printf("Reverb::update_gui %d %d\n", __LINE__, config.ref_length);
+                       thread->window->lock_window("Reverb::update_gui");
+                       ((ReverbWindow*)thread->window)->level_init->update(config.level_init);
+                       ((ReverbWindow*)thread->window)->delay_init->update(config.delay_init);
+                       ((ReverbWindow*)thread->window)->ref_level1->update(config.ref_level1);
+                       ((ReverbWindow*)thread->window)->ref_level2->update(config.ref_level2);
+                       ((ReverbWindow*)thread->window)->ref_total->update(config.ref_total);
+                       ((ReverbWindow*)thread->window)->ref_length->update(config.ref_length);
+                       ((ReverbWindow*)thread->window)->lowpass1->update(config.lowpass1);
+                       ((ReverbWindow*)thread->window)->lowpass2->update(config.lowpass2);
+                       thread->window->unlock_window();
+               }
        }
-
-       return result;
 }
 
-int Reverb::save_to_file(char *path)
-{
-       int result = 0;
-       char string[1024];
 
-       {
-//             ConfirmSave confirm;
-//             result = confirm.test_file("", path);
-       }
 
-       if(!result)
-       {
-               FILE *out = fopen(path, "wb");
-               if( out )
-               {
-//                     save_data(string);
-                       fwrite(string, strlen(string), 1, out);
-                       fclose(out);
-               }
-               else
-               {
-                       result = 1;
-// failed
-                       ErrorBox errorbox("");
-                       char string[1024];
-                       sprintf(string, _("Couldn't save %s."), path);
-                       errorbox.create_objects(string);
-                       errorbox.run_window();
-                       result = 1;
-               }
-       }
 
-       return result;
-}
+// int Reverb::load_from_file(char *path)
+// {
+//     FILE *in;
+//     int result = 0;
+//     int length;
+//     char string[1024];
+//     
+//     if(in = fopen(path, "rb"))
+//     {
+//             fseek(in, 0, SEEK_END);
+//             length = ftell(in);
+//             fseek(in, 0, SEEK_SET);
+//             int temp = fread(string, length, 1, in);
+//             fclose(in);
+// //          read_data(string);
+//     }
+//     else
+//     {
+//             perror("fopen:");
+// // failed
+//             ErrorBox errorbox("");
+//             char string[1024];
+//             sprintf(string, _("Couldn't open %s."), path);
+//             errorbox.create_objects(string);
+//             errorbox.run_window();
+//             result = 1;
+//     }
+//     
+//     return result;
+// }
+// 
+// int Reverb::save_to_file(char *path)
+// {
+//     FILE *out;
+//     int result = 0;
+//     char string[1024];
+//     
+//     {
+// //          ConfirmSave confirm;
+// //          result = confirm.test_file("", path);
+//     }
+//     
+//     if(!result)
+//     {
+//             if(out = fopen(path, "wb"))
+//             {
+// //                  save_data(string);
+//                     fwrite(string, strlen(string), 1, out);
+//                     fclose(out);
+//             }
+//             else
+//             {
+//                     result = 1;
+// // failed
+//                     ErrorBox errorbox("");
+//                     char string[1024];
+//                     sprintf(string, _("Couldn't save %s."), path);
+//                     errorbox.create_objects(string);
+//                     errorbox.run_window();
+//                     result = 1;
+//             }
+//     }
+//     
+//     return result;
+// }
 
 ReverbEngine::ReverbEngine(Reverb *plugin)
  : Thread(1, 0, 0)
index ca04f739835372d24da2ee856b05a003e5f90d5c..629c74ce173ef24dc38a620217fe4393f5c0f36b 100644 (file)
@@ -65,8 +65,8 @@ public:
        ~Reverb();
 
        void update_gui();
-       int load_from_file(char *data);
-       int save_to_file(char *data);
+//     int load_from_file(char *data);
+//     int save_to_file(char *data);
 
 // data for reverb
        char config_directory[1024];
index 4da0fafc701c25cff70ba5be6c5832ab148ffb6b..add6ab4588c769ed9bcbff3ac901cd28600fa558 100644 (file)
@@ -33,9 +33,9 @@
 
 ReverbWindow::ReverbWindow(Reverb *reverb)
  : PluginClientWindow(reverb,
-       250,
-       230,
-       250,
+       300, 
+       230, 
+       300, 
        230,
        0)
 {
@@ -48,7 +48,7 @@ ReverbWindow::~ReverbWindow()
 
 void ReverbWindow::create_objects()
 {
-       int x = 170, y = 10;
+       int x = 200, y = 10;
        add_tool(new BC_Title(5, y + 10, _("Initial signal level:")));
        add_tool(level_init = new ReverbLevelInit(reverb, x, y)); y += 25;
        add_tool(new BC_Title(5, y + 10, _("ms before reflections:")));
@@ -215,319 +215,317 @@ int ReverbLowPass2::handle_event()
        return 1;
 }
 
-ReverbMenu::ReverbMenu(Reverb *reverb, ReverbWindow *window)
- : BC_MenuBar(0, 0, window->get_w())
-{
-       this->window = window;
-       this->reverb = reverb;
-}
-
-ReverbMenu::~ReverbMenu()
-{
-       delete load;
-       delete save;
-       //delete set_default;
-       for(int i = 0; i < total_loads; i++)
-       {
-               delete prev_load[i];
-       }
-       delete prev_load_thread;
-}
-
-void ReverbMenu::create_objects(BC_Hash *defaults)
-{
-       add_menu(filemenu = new BC_Menu(_("File")));
-       filemenu->add_item(load = new ReverbLoad(reverb, this));
-       filemenu->add_item(save = new ReverbSave(reverb, this));
-       //filemenu->add_item(set_default = new ReverbSetDefault);
-       load_defaults(defaults);
-       prev_load_thread = new ReverbLoadPrevThread(reverb, this);
-}
-
-int ReverbMenu::load_defaults(BC_Hash *defaults)
-{
-       FileSystem fs;
-       total_loads = defaults->get("TOTAL_LOADS", 0);
-       if(total_loads > 0)
-       {
-               filemenu->add_item(new BC_MenuItem("-"));
-               char string[1024], path[1024], filename[1024];
-
-               for(int i = 0; i < total_loads; i++)
-               {
-                       sprintf(string, "LOADPREVIOUS%d", i);
-                       defaults->get(string, path);
-                       fs.extract_name(filename, path);
-//printf("ReverbMenu::load_defaults %s\n", path);
-                       filemenu->add_item(prev_load[i] = new ReverbLoadPrev(reverb, this, filename, path));
-               }
-       }
-       return 0;
-}
-
-int ReverbMenu::save_defaults(BC_Hash *defaults)
-{
-       if(total_loads > 0)
-       {
-               defaults->update("TOTAL_LOADS",  total_loads);
-               char string[1024];
-
-               for(int i = 0; i < total_loads; i++)
-               {
-                       sprintf(string, "LOADPREVIOUS%d", i);
-                       defaults->update(string, prev_load[i]->path);
-               }
-       }
-       return 0;
-}
-
-int ReverbMenu::add_load(char *path)
-{
-       if(total_loads == 0)
-       {
-               filemenu->add_item(new BC_MenuItem("-"));
-       }
-
-// test for existing copy
-       FileSystem fs;
-       char text[1024], new_path[1024];      // get text and path
-       fs.extract_name(text, path);
-       strcpy(new_path, path);
-
-       for(int i = 0; i < total_loads; i++)
-       {
-               if(!strcmp(prev_load[i]->get_text(), text))     // already exists
-               {                                // swap for top load
-                       for(int j = i; j > 0; j--)   // move preceeding loads down
-                       {
-                               prev_load[j]->set_text(prev_load[j - 1]->get_text());
-                               prev_load[j]->set_path(prev_load[j - 1]->path);
-                       }
-                       prev_load[0]->set_text(text);
-                       prev_load[0]->set_path(new_path);
-                       return 1;
-               }
-       }
-
-// add another load
-       if(total_loads < TOTAL_LOADS)
-       {
-               filemenu->add_item(prev_load[total_loads] = new ReverbLoadPrev(reverb, this));
-               total_loads++;
-       }
-
-// cycle loads down
-       for(int i = total_loads - 1; i > 0; i--)
-       {
-       // set menu item text
-               prev_load[i]->set_text(prev_load[i - 1]->get_text());
-       // set filename
-               prev_load[i]->set_path(prev_load[i - 1]->path);
-       }
-
-// set up the new load
-       prev_load[0]->set_text(text);
-       prev_load[0]->set_path(new_path);
-       return 0;
-}
-
-ReverbLoad::ReverbLoad(Reverb *reverb, ReverbMenu *menu)
- : BC_MenuItem(_("Load..."))
-{
-       this->reverb = reverb;
-       this->menu = menu;
-       thread = new ReverbLoadThread(reverb, menu);
-}
-ReverbLoad::~ReverbLoad()
-{
-       delete thread;
-}
-int ReverbLoad::handle_event()
-{
-       thread->start();
-       return 0;
-}
-
-ReverbSave::ReverbSave(Reverb *reverb, ReverbMenu *menu)
- : BC_MenuItem(_("Save..."))
-{
-       this->reverb = reverb;
-       this->menu = menu;
-       thread = new ReverbSaveThread(reverb, menu);
-}
-ReverbSave::~ReverbSave()
-{
-       delete thread;
-}
-int ReverbSave::handle_event()
-{
-       thread->start();
-       return 0;
-}
-
-ReverbSetDefault::ReverbSetDefault()
- : BC_MenuItem(_("Set default"))
-{
-}
-int ReverbSetDefault::handle_event()
-{
-       return 0;
-}
-
-ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu, char *filename, char *path)
- : BC_MenuItem(filename)
-{
-       this->reverb = reverb;
-       this->menu = menu;
-       strcpy(this->path, path);
-}
-ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu)
- : BC_MenuItem("")
-{
-       this->reverb = reverb;
-       this->menu = menu;
-}
-int ReverbLoadPrev::handle_event()
-{
-       menu->prev_load_thread->set_path(path);
-       menu->prev_load_thread->start();
-       return 0;
-}
-int ReverbLoadPrev::set_path(char *path)
-{
-       strcpy(this->path, path);
-       return 0;
-}
-
-
-ReverbSaveThread::ReverbSaveThread(Reverb *reverb, ReverbMenu *menu)
- : Thread()
-{
-       this->reverb = reverb;
-       this->menu = menu;
-}
-ReverbSaveThread::~ReverbSaveThread()
-{
-}
-void ReverbSaveThread::run()
-{
-       int result = 0;
-       {
-               ReverbSaveDialog dialog(reverb);
-               dialog.create_objects();
-               result = dialog.run_window();
-//             if(!result) strcpy(reverb->config_directory, dialog.get_path());
-       }
-       if(!result)
-       {
-               result = reverb->save_to_file(reverb->config_directory);
-               menu->add_load(reverb->config_directory);
-       }
-}
-
-ReverbSaveDialog::ReverbSaveDialog(Reverb *reverb)
- : BC_FileBox(0,
-                       0,
-                       reverb->config_directory,
-                       _("Save reverb"),
-                       _("Select the reverb file to save as"), 0, 0)
-{
-       this->reverb = reverb;
-}
-ReverbSaveDialog::~ReverbSaveDialog()
-{
-}
-int ReverbSaveDialog::ok_event()
-{
-       set_done(0);
-       return 0;
-}
-int ReverbSaveDialog::cancel_event()
-{
-       set_done(1);
-       return 0;
-}
-
-
-
-ReverbLoadThread::ReverbLoadThread(Reverb *reverb, ReverbMenu *menu)
- : Thread()
-{
-       this->reverb = reverb;
-       this->menu = menu;
-}
-ReverbLoadThread::~ReverbLoadThread()
-{
-}
-void ReverbLoadThread::run()
-{
-       int result = 0;
-       {
-               ReverbLoadDialog dialog(reverb);
-               dialog.create_objects();
-               result = dialog.run_window();
-//             if(!result) strcpy(reverb->config_directory, dialog.get_path());
-       }
-       if(!result)
-       {
-               result = reverb->load_from_file(reverb->config_directory);
-               if(!result)
-               {
-                       menu->add_load(reverb->config_directory);
-                       reverb->send_configure_change();
-               }
-       }
-}
-
-ReverbLoadPrevThread::ReverbLoadPrevThread(Reverb *reverb, ReverbMenu *menu) : Thread()
-{
-       this->reverb = reverb;
-       this->menu = menu;
-}
-ReverbLoadPrevThread::~ReverbLoadPrevThread()
-{
-}
-void ReverbLoadPrevThread::run()
-{
-       int result = 0;
-       strcpy(reverb->config_directory, path);
-       result = reverb->load_from_file(path);
-       if(!result)
-       {
-               menu->add_load(path);
-               reverb->send_configure_change();
-       }
-}
-int ReverbLoadPrevThread::set_path(char *path)
-{
-       strcpy(this->path, path);
-       return 0;
-}
-
-
-
-
-
-ReverbLoadDialog::ReverbLoadDialog(Reverb *reverb)
- : BC_FileBox(0,
-                       0,
-                       reverb->config_directory,
-                       _("Load reverb"),
-                       _("Select the reverb file to load from"), 0, 0)
-{
-       this->reverb = reverb;
-}
-ReverbLoadDialog::~ReverbLoadDialog()
-{
-}
-int ReverbLoadDialog::ok_event()
-{
-       set_done(0);
-       return 0;
-}
-int ReverbLoadDialog::cancel_event()
-{
-       set_done(1);
-       return 0;
-}
+// ReverbMenu::ReverbMenu(Reverb *reverb, ReverbWindow *window)
+//  : BC_MenuBar(0, 0, window->get_w())
+// {
+//     this->window = window;
+//     this->reverb = reverb;
+// }
+// 
+// ReverbMenu::~ReverbMenu()
+// {
+//     delete load;
+//     delete save;
+//     //delete set_default;
+//     for(int i = 0; i < total_loads; i++)
+//     {
+//             delete prev_load[i];
+//     }
+//     delete prev_load_thread;
+// }
+// 
+// void ReverbMenu::create_objects(BC_Hash *defaults)
+// {
+//     add_menu(filemenu = new BC_Menu(_("File")));
+//     filemenu->add_item(load = new ReverbLoad(reverb, this));
+//     filemenu->add_item(save = new ReverbSave(reverb, this));
+//     //filemenu->add_item(set_default = new ReverbSetDefault);
+//     load_defaults(defaults);
+//     prev_load_thread = new ReverbLoadPrevThread(reverb, this);
+// }
+// 
+// int ReverbMenu::load_defaults(BC_Hash *defaults)
+// {
+//     FileSystem fs;
+//     total_loads = defaults->get("TOTAL_LOADS", 0);
+//     if(total_loads > 0)
+//     {
+//             filemenu->add_item(new BC_MenuItem("-"));
+//             char string[1024], path[1024], filename[1024];
+//     
+//             for(int i = 0; i < total_loads; i++)
+//             {
+//                     sprintf(string, "LOADPREVIOUS%d", i);
+//                     defaults->get(string, path);
+//                     fs.extract_name(filename, path);
+// //printf("ReverbMenu::load_defaults %s\n", path);
+//                     filemenu->add_item(prev_load[i] = new ReverbLoadPrev(reverb, this, filename, path));
+//             }
+//     }
+//     return 0;
+// }
+// 
+// int ReverbMenu::save_defaults(BC_Hash *defaults)
+// {
+//     if(total_loads > 0)
+//     {
+//             defaults->update("TOTAL_LOADS",  total_loads);
+//             char string[1024];
+//             
+//             for(int i = 0; i < total_loads; i++)
+//             {
+//                     sprintf(string, "LOADPREVIOUS%d", i);
+//                     defaults->update(string, prev_load[i]->path);
+//             }
+//     }
+//     return 0;
+// }
+// 
+// int ReverbMenu::add_load(char *path)
+// {
+//     if(total_loads == 0)
+//     {
+//             filemenu->add_item(new BC_MenuItem("-"));
+//     }
+//     
+// // test for existing copy
+//     FileSystem fs;
+//     char text[1024], new_path[1024];      // get text and path
+//     fs.extract_name(text, path);
+//     strcpy(new_path, path);
+//     
+//     for(int i = 0; i < total_loads; i++)
+//     {
+//             if(!strcmp(prev_load[i]->get_text(), text))     // already exists
+//             {                                // swap for top load
+//                     for(int j = i; j > 0; j--)   // move preceeding loads down
+//                     {
+//                             prev_load[j]->set_text(prev_load[j - 1]->get_text());
+//                             prev_load[j]->set_path(prev_load[j - 1]->path);
+//                     }
+//                     prev_load[0]->set_text(text);
+//                     prev_load[0]->set_path(new_path);
+//                     return 1;
+//             }
+//     }
+//     
+// // add another load
+//     if(total_loads < TOTAL_LOADS)
+//     {
+//             filemenu->add_item(prev_load[total_loads] = new ReverbLoadPrev(reverb, this));
+//             total_loads++;
+//     }
+//     
+// // cycle loads down
+//     for(int i = total_loads - 1; i > 0; i--)
+//     {         
+//     // set menu item text
+//             prev_load[i]->set_text(prev_load[i - 1]->get_text());
+//     // set filename
+//             prev_load[i]->set_path(prev_load[i - 1]->path);
+//     }
+// 
+// // set up the new load
+//     prev_load[0]->set_text(text);
+//     prev_load[0]->set_path(new_path);
+//     return 0;
+// }
+// 
+// ReverbLoad::ReverbLoad(Reverb *reverb, ReverbMenu *menu)
+//  : BC_MenuItem(_("Load..."))
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+//     thread = new ReverbLoadThread(reverb, menu);
+// }
+// ReverbLoad::~ReverbLoad()
+// {
+//     delete thread;
+// }
+// int ReverbLoad::handle_event()
+// {
+//     thread->start();
+//     return 0;
+// }
+// 
+// ReverbSave::ReverbSave(Reverb *reverb, ReverbMenu *menu)
+//  : BC_MenuItem(_("Save..."))
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+//     thread = new ReverbSaveThread(reverb, menu);
+// }
+// ReverbSave::~ReverbSave()
+// {
+//     delete thread;
+// }
+// int ReverbSave::handle_event()
+// {
+//     thread->start();
+//     return 0;
+// }
+// 
+// ReverbSetDefault::ReverbSetDefault()
+//  : BC_MenuItem(_("Set default"))
+// {
+// }
+// int ReverbSetDefault::handle_event()
+// {
+//     return 0;
+// }
+// 
+// ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu, char *filename, char *path)
+//  : BC_MenuItem(filename)
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+//     strcpy(this->path, path);
+// }
+// ReverbLoadPrev::ReverbLoadPrev(Reverb *reverb, ReverbMenu *menu)
+//  : BC_MenuItem("")
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+// }
+// int ReverbLoadPrev::handle_event()
+// {
+//     menu->prev_load_thread->set_path(path);
+//     menu->prev_load_thread->start();
+// }
+// int ReverbLoadPrev::set_path(char *path)
+// {
+//     strcpy(this->path, path);
+// }
+// 
+// 
+// ReverbSaveThread::ReverbSaveThread(Reverb *reverb, ReverbMenu *menu)
+//  : Thread()
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+// }
+// ReverbSaveThread::~ReverbSaveThread()
+// {
+// }
+// void ReverbSaveThread::run()
+// {
+//     int result = 0;
+//     {
+//             ReverbSaveDialog dialog(reverb);
+//             dialog.create_objects();
+//             result = dialog.run_window();
+// //          if(!result) strcpy(reverb->config_directory, dialog.get_path());
+//     }
+//     if(!result) 
+//     {
+//             result = reverb->save_to_file(reverb->config_directory);
+//             menu->add_load(reverb->config_directory);
+//     }
+// }
+// 
+// ReverbSaveDialog::ReverbSaveDialog(Reverb *reverb)
+//  : BC_FileBox(0,
+//                     0, 
+//                     reverb->config_directory, 
+//                     _("Save reverb"), 
+//                     _("Select the reverb file to save as"), 0, 0)
+// {
+//     this->reverb = reverb;
+// }
+// ReverbSaveDialog::~ReverbSaveDialog()
+// {
+// }
+// int ReverbSaveDialog::ok_event()
+// {
+//     set_done(0);
+//     return 0;
+// }
+// int ReverbSaveDialog::cancel_event()
+// {
+//     set_done(1);
+//     return 0;
+// }
+// 
+// 
+// 
+// ReverbLoadThread::ReverbLoadThread(Reverb *reverb, ReverbMenu *menu)
+//  : Thread()
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+// }
+// ReverbLoadThread::~ReverbLoadThread()
+// {
+// }
+// void ReverbLoadThread::run()
+// {
+//     int result = 0;
+//     {
+//             ReverbLoadDialog dialog(reverb);
+//             dialog.create_objects();
+//             result = dialog.run_window();
+// //          if(!result) strcpy(reverb->config_directory, dialog.get_path());
+//     }
+//     if(!result) 
+//     {
+//             result = reverb->load_from_file(reverb->config_directory);
+//             if(!result)
+//             {
+//                     menu->add_load(reverb->config_directory);
+//                     reverb->send_configure_change();
+//             }
+//     }
+// }
+// 
+// ReverbLoadPrevThread::ReverbLoadPrevThread(Reverb *reverb, ReverbMenu *menu) : Thread()
+// {
+//     this->reverb = reverb;
+//     this->menu = menu;
+// }
+// ReverbLoadPrevThread::~ReverbLoadPrevThread()
+// {
+// }
+// void ReverbLoadPrevThread::run()
+// {
+//     int result = 0;
+//     strcpy(reverb->config_directory, path);
+//     result = reverb->load_from_file(path);
+//     if(!result)
+//     {
+//             menu->add_load(path);
+//             reverb->send_configure_change();
+//     }
+// }
+// int ReverbLoadPrevThread::set_path(char *path)
+// {
+//     strcpy(this->path, path);
+//     return 0;
+// }
+// 
+// 
+// 
+// 
+// 
+// ReverbLoadDialog::ReverbLoadDialog(Reverb *reverb)
+//  : BC_FileBox(0,
+//                     0, 
+//                     reverb->config_directory, 
+//                     _("Load reverb"), 
+//                     _("Select the reverb file to load from"), 0, 0)
+// {
+//     this->reverb = reverb;
+// }
+// ReverbLoadDialog::~ReverbLoadDialog()
+// {
+// }
+// int ReverbLoadDialog::ok_event()
+// {
+//     set_done(0);
+//     return 0;
+// }
+// int ReverbLoadDialog::cancel_event()
+// {
+//     set_done(1);
+//     return 0;
+// }
 
index 6cfb38b23f94c790b3ea50946fe624832c8a254a..21dd42745b12fedf148d4ed2f6e8d337b2827b0e 100644 (file)
@@ -25,7 +25,7 @@
 #include "filexml.h"
 #include "guicast.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
index 9707f1261b78e7c5f7c705f3b7b8637ac41c88b2..4648737bc5d6c71e6b2d5161edfe7aa958544140 100644 (file)
@@ -25,7 +25,7 @@
 #include "bchash.h"
 #include "filexml.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "samples.h"
 #include "spectrogram.h"
 #include "theme.h"
diff --git a/cinelerra-5.1/plugins/spherecam/Makefile b/cinelerra-5.1/plugins/spherecam/Makefile
new file mode 100644 (file)
index 0000000..9bdb0c7
--- /dev/null
@@ -0,0 +1,9 @@
+include ../../plugin_defs
+
+OBJS = $(OBJDIR)/spherecam.o
+
+PLUGIN = spherecam
+
+include ../../plugin_config
+
+$(OBJDIR)/spherecam.o: spherecam.C
diff --git a/cinelerra-5.1/plugins/spherecam/picon_cinfinity.png b/cinelerra-5.1/plugins/spherecam/picon_cinfinity.png
new file mode 100644 (file)
index 0000000..ee0b79a
Binary files /dev/null and b/cinelerra-5.1/plugins/spherecam/picon_cinfinity.png differ
diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.C b/cinelerra-5.1/plugins/spherecam/spherecam.C
new file mode 100644 (file)
index 0000000..8b1f695
--- /dev/null
@@ -0,0 +1,1026 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include "affine.h"
+#include "bcdisplayinfo.h"
+#include "bchash.h"
+#include "bcsignals.h"
+#include "clip.h"
+#include "filexml.h"
+#include "language.h"
+#include "spherecam.h"
+#include "theme.h"
+
+#include <string.h>
+
+// largely based on equations from http://paulbourke.net/dome/fish2/
+
+REGISTER_PLUGIN(SphereCamMain)
+
+
+SphereCamConfig::SphereCamConfig()
+{
+       feather = 0;
+       
+       for( int i = 0; i < EYES; i++ ) {
+               enabled[i] = 1;
+               fov[i] = 180;
+               radius[i] = 100.0;
+               center_y[i] = 50.0;
+               rotate_y[i] = 50.0;
+               rotate_z[i] = 0;
+       }
+       
+       center_x[0] = 25.0;
+       center_x[1] = 75.0;
+       rotate_x[0] = 50.0;
+       rotate_x[1] = 100.0;
+       draw_guides = 1;
+       mode = SphereCamConfig::DO_NOTHING;
+}
+
+int SphereCamConfig::equivalent(SphereCamConfig &that)
+{
+       for( int i = 0; i < EYES; i++ ) {
+               if( enabled[i] != that.enabled[i] ||
+                       !EQUIV(fov[i], that.fov[i]) ||
+                       !EQUIV(radius[i], that.radius[i]) ||
+                       !EQUIV(center_x[i], that.center_x[i]) ||
+                       !EQUIV(center_y[i], that.center_y[i]) ||
+                       !EQUIV(rotate_x[i], that.rotate_x[i]) ||
+                       !EQUIV(rotate_y[i], that.rotate_y[i]) ||
+                       !EQUIV(rotate_z[i], that.rotate_z[i]) ) {
+                       return 0;
+               }
+       }
+
+       if( feather != that.feather || mode != that.mode ||
+           draw_guides != that.draw_guides ) {
+               return 0;
+       }
+
+
+       return 1;
+}
+
+void SphereCamConfig::copy_from(SphereCamConfig &that)
+{
+       *this = that;
+}
+
+void SphereCamConfig::interpolate(SphereCamConfig &prev, 
+       SphereCamConfig &next, 
+       int64_t prev_frame, 
+       int64_t next_frame, 
+       int64_t current_frame)
+{
+       double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
+       double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
+
+       for( int i = 0; i < EYES; i++ ) {
+               enabled[i] = prev.enabled[i];
+               fov[i] = prev.fov[i] * prev_scale + next.fov[i] * next_scale;
+               radius[i] = prev.radius[i] * prev_scale + next.radius[i] * next_scale;
+               center_x[i] = prev.center_x[i] * prev_scale + next.center_x[i] * next_scale;
+               center_y[i] = prev.center_y[i] * prev_scale + next.center_y[i] * next_scale;
+               rotate_x[i] = prev.rotate_x[i] * prev_scale + next.rotate_x[i] * next_scale;
+               rotate_y[i] = prev.rotate_y[i] * prev_scale + next.rotate_y[i] * next_scale;
+               rotate_z[i] = prev.rotate_z[i] * prev_scale + next.rotate_z[i] * next_scale;
+       }
+
+       feather = prev.feather * prev_scale + next.feather * next_scale;
+       draw_guides = prev.draw_guides;
+       mode = prev.mode;
+
+       boundaries();
+}
+
+void SphereCamConfig::boundaries()
+{
+       for( int i = 0; i < EYES; i++ ) {
+               CLAMP(fov[i], 1.0, 359.0);
+               CLAMP(radius[i], 1.0, 150.0);
+               CLAMP(center_x[i], 0.0, 100.0);
+               CLAMP(center_y[i], 0.0, 100.0);
+               CLAMP(rotate_x[i], 0.0, 100.0);
+               CLAMP(rotate_y[i], 0.0, 100.0);
+               CLAMP(rotate_z[i], -180.0, 180.0);
+       }
+       
+       CLAMP(feather, 0, 50);
+}
+
+
+SphereCamSlider::SphereCamSlider(SphereCamMain *client, 
+       SphereCamGUI *gui,
+       SphereCamText *text,
+       float *output, 
+       int x, 
+       int y, 
+       float min,
+       float max)
+ : BC_FSlider(x, 
+       y, 
+       0, 
+       gui->get_w() / 2 - client->get_theme()->widget_border * 3 - 100, 
+       gui->get_w() / 2 - client->get_theme()->widget_border * 3 - 100, 
+       min, 
+       max, 
+       *output)
+{
+       this->gui = gui;
+       this->client = client;
+       this->output = output;
+       this->text = text;
+       set_precision(0.01);
+}
+
+int SphereCamSlider::handle_event()
+{
+       *output = get_value();
+       text->update(*output);
+       client->send_configure_change();
+       return 1;
+}
+
+
+SphereCamText::SphereCamText(SphereCamMain *client, 
+       SphereCamGUI *gui,
+       SphereCamSlider *slider,
+       float *output, 
+       int x, 
+       int y)
+ : BC_TextBox(x, y, 100, 1, *output)
+{
+       this->gui = gui;
+       this->client = client;
+       this->output = output;
+       this->slider = slider;
+}
+
+int SphereCamText::handle_event()
+{
+       *output = atof(get_text());
+       slider->update(*output);
+       client->send_configure_change();
+       return 1;
+}
+
+
+SphereCamToggle::SphereCamToggle(SphereCamMain *client, 
+       int *output, int x, int y, const char *text)
+ : BC_CheckBox(x, y, *output, text)
+{
+       this->output = output;
+       this->client = client;
+}
+
+int SphereCamToggle::handle_event()
+{
+       *output = get_value();
+       client->send_configure_change();
+       return 1;
+}
+
+
+SphereCamMode::SphereCamMode(SphereCamMain *plugin,  
+       SphereCamGUI *gui, int x, int y)
+ : BC_PopupMenu(x, y, calculate_w(gui), "", 1)
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+
+int SphereCamMode::handle_event()
+{
+       plugin->config.mode = from_text(get_text());
+       plugin->send_configure_change();
+       return 1;
+
+}
+
+void SphereCamMode::create_objects()
+{
+       add_item(new BC_MenuItem(to_text(SphereCamConfig::DO_NOTHING)));
+       add_item(new BC_MenuItem(to_text(SphereCamConfig::EQUIRECT)));
+       add_item(new BC_MenuItem(to_text(SphereCamConfig::ALIGN)));
+       update(plugin->config.mode);
+}
+
+void SphereCamMode::update(int mode)
+{
+       char string[BCTEXTLEN];
+       sprintf(string, "%s", to_text(mode));
+       set_text(string);
+}
+
+int SphereCamMode::calculate_w(SphereCamGUI *gui)
+{
+       int result = 0;
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(SphereCamConfig::EQUIRECT)));
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(SphereCamConfig::DO_NOTHING)));
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(SphereCamConfig::ALIGN)));
+       return result + 50;
+}
+
+int SphereCamMode::from_text(char *text)
+{
+       for( int i = 0; i < 3; i++ ) {
+               if( !strcmp(text, to_text(i)) ) {
+                       return i;
+               }
+       }
+
+       return SphereCamConfig::EQUIRECT;
+}
+
+const char* SphereCamMode::to_text(int mode)
+{
+       switch( mode ) {
+       case SphereCamConfig::DO_NOTHING:
+               return "Do nothing";
+               break;
+       case SphereCamConfig::EQUIRECT:
+               return "Equirectangular";
+               break;
+       case SphereCamConfig::ALIGN:
+               return "Align only";
+               break;
+       }
+       return "Equirectangular";
+}
+
+
+SphereCamGUI::SphereCamGUI(SphereCamMain *client)
+ : PluginClientWindow(client, 640, 600, 640, 600, 0)
+{
+       this->client = client;
+}
+
+SphereCamGUI::~SphereCamGUI()
+{
+}
+
+
+void SphereCamGUI::create_objects()
+{
+       int margin = client->get_theme()->widget_border;
+       int margin2 = margin;
+       int y = margin;
+       int x[EYES];
+
+       x[0] = margin;
+       x[1] = get_w() / 2 + margin / 2;
+
+       BC_Title *title;
+
+       for( int i = 0; i < EYES; i++ ) {
+               int x3 = x[i];
+               y = margin;
+
+               add_tool(title = new BC_Title(x[i], y,
+                       i == 0 ? _("Left Eye") : _("Right Eye"), LARGEFONT));
+               y += title->get_h() + margin2;
+               
+               add_tool(enabled[i] = new SphereCamToggle(client, 
+                       &client->config.enabled[i], x3, y, _("Enabled")));
+               y += enabled[i]->get_h() + margin2;
+               
+               add_tool(title = new BC_Title(x3, y, _("FOV:")));
+               y += title->get_h() + margin2;
+               add_tool(fov_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.fov[i], x3, y, 1, 359));
+               fov_slider[i]->set_precision(0.1);
+               x3 += fov_slider[i]->get_w() + margin;
+               add_tool(fov_text[i] = new SphereCamText(client, this,
+                       fov_slider[i], &client->config.fov[i], x3, y));
+               fov_slider[i]->text = fov_text[i];
+               y += fov_text[i]->get_h() + margin2;
+
+               x3 = x[i];
+               add_tool(title = new BC_Title(x3, y, _("Radius:")));
+               y += title->get_h() + margin2;
+               add_tool(radius_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.radius[i], x3, y, 1, 150));
+               radius_slider[i]->set_precision(0.1);
+               x3 += radius_slider[i]->get_w() + margin;
+               add_tool(radius_text[i] = new SphereCamText(client, this,
+                       radius_slider[i], &client->config.radius[i], x3, y));
+               radius_slider[i]->text = radius_text[i];
+               y += radius_text[i]->get_h() + margin2;
+
+               x3 = x[i];
+               add_tool(title = new BC_Title(x3, y, _("Input X:")));
+               y += title->get_h() + margin2;
+               add_tool(centerx_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.center_x[i], x3, y, 0, 100));
+               centerx_slider[i]->set_precision(0.1);
+               x3 += centerx_slider[i]->get_w() + margin;
+               add_tool(centerx_text[i] = new SphereCamText(client, this,
+                       centerx_slider[i], &client->config.center_x[i], x3, y));
+               centerx_slider[i]->text = centerx_text[i];
+               y += centerx_text[i]->get_h() + margin2;
+
+               x3 = x[i];
+               add_tool(title = new BC_Title(x3, y, _("Input Y:")));
+               y += title->get_h() + margin2;
+               add_tool(centery_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.center_y[i], x3, y, 0, 100));
+               centery_slider[i]->set_precision(0.1);
+               x3 += centery_slider[i]->get_w() + margin;
+               add_tool(centery_text[i] = new SphereCamText(client, this,
+                       centery_slider[i], &client->config.center_y[i], x3, y));
+               centery_slider[i]->text = centery_text[i];
+               y += centery_text[i]->get_h() + margin2;
+
+               x3 = x[i];
+               add_tool(title = new BC_Title(x3, y, _("Output X:")));
+               y += title->get_h() + margin2;
+               add_tool(rotatex_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.rotate_x[i], x3, y, 0, 100));
+               rotatex_slider[i]->set_precision(0.1);
+               x3 += rotatex_slider[i]->get_w() + margin;
+               add_tool(rotatex_text[i] = new SphereCamText(client, this,
+                       rotatex_slider[i], &client->config.rotate_x[i], x3, y));
+               rotatex_slider[i]->text = rotatex_text[i];
+               y += rotatex_text[i]->get_h() + margin2;
+
+               x3 = x[i];
+               add_tool(title = new BC_Title(x3, y, _("Output Y:")));
+               y += title->get_h() + margin2;
+               add_tool(rotatey_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.rotate_y[i], x3, y, 0, 100));
+               rotatey_slider[i]->set_precision(0.1);
+               x3 += rotatey_slider[i]->get_w() + margin;
+               add_tool(rotatey_text[i] = new SphereCamText(client, this,
+                       rotatey_slider[i], &client->config.rotate_y[i], x3, y));
+               rotatey_slider[i]->text = rotatey_text[i];
+               y += rotatey_text[i]->get_h() + margin2;
+
+               x3 = x[i];
+               add_tool(title = new BC_Title(x3, y, _("Rotate:")));
+               y += title->get_h() + margin2;
+               add_tool(rotatez_slider[i] = new SphereCamSlider(client, this,
+                       0, &client->config.rotate_z[i], x3, y, -180, 180));
+               rotatez_slider[i]->set_precision(0.1);
+               x3 += rotatez_slider[i]->get_w() + margin;
+               add_tool(rotatez_text[i] = new SphereCamText(client, this,
+                       rotatez_slider[i], &client->config.rotate_z[i], x3, y));
+               rotatez_slider[i]->text = rotatez_text[i];
+               y += rotatez_text[i]->get_h() + margin2;
+       }
+
+       int x3 = x[0];
+       add_tool(title = new BC_Title(x3, y, _("Feather:")));
+       y += title->get_h() + margin2;
+       add_tool(feather_slider = new SphereCamSlider(client, this,
+               0, &client->config.feather, x3, y, 0, 100));
+       feather_slider->set_precision(0.1);
+       x3 += feather_slider->get_w() + margin;
+       add_tool(feather_text = new SphereCamText(client, this,
+               feather_slider, &client->config.feather, x3, y));
+       feather_slider->text = feather_text;
+       y += feather_text->get_h() + margin2;
+
+//printf("SphereCamGUI::create_objects %d %f\n", __LINE__, client->config.distance);
+
+       x3 = x[0];
+       add_tool(draw_guides = new SphereCamToggle(client, 
+               &client->config.draw_guides, x3, y, _("Draw guides")));
+       y += draw_guides->get_h() + margin2;
+       
+       add_tool(title = new BC_Title(x3, y, _("Mode:")));
+       add_tool(mode = new SphereCamMode(client, 
+               this, 
+               x3 + title->get_w() + margin, 
+               y));
+       mode->create_objects();
+       y += mode->get_h() + margin2;
+
+       show_window();
+       flush();
+}
+
+
+SphereCamMain::SphereCamMain(PluginServer *server)
+ : PluginVClient(server)
+{
+       engine = 0;
+       affine = 0;
+}
+
+SphereCamMain::~SphereCamMain()
+{
+       delete engine;
+       delete affine;
+}
+
+NEW_WINDOW_MACRO(SphereCamMain, SphereCamGUI)
+LOAD_CONFIGURATION_MACRO(SphereCamMain, SphereCamConfig)
+int SphereCamMain::is_realtime() { return 1; }
+const char* SphereCamMain::plugin_title() { return N_("Sphere Cam"); }
+
+void SphereCamMain::update_gui()
+{
+       if( !thread ) return;
+       if( !load_configuration() ) return;
+       ((SphereCamGUI*)thread->window)->lock_window("SphereCamMain::update_gui");
+       SphereCamGUI *window = (SphereCamGUI*)thread->window;
+
+       for( int i = 0; i < EYES; i++ ) {
+               window->enabled[i]->update(config.enabled[i]);
+
+               window->fov_slider[i]->update(config.fov[i]);
+               window->fov_text[i]->update(config.fov[i]);
+
+               window->radius_slider[i]->update(config.radius[i]);
+               window->radius_text[i]->update(config.radius[i]);
+
+               window->centerx_slider[i]->update(config.center_x[i]);
+               window->centerx_text[i]->update(config.center_x[i]);
+
+               window->centery_slider[i]->update(config.center_y[i]);
+               window->centery_text[i]->update(config.center_y[i]);
+
+               window->rotatex_slider[i]->update(config.rotate_x[i]);
+               window->rotatex_text[i]->update(config.rotate_x[i]);
+
+               window->rotatey_slider[i]->update(config.rotate_y[i]);
+               window->rotatey_text[i]->update(config.rotate_y[i]);
+
+               window->rotatez_slider[i]->update(config.rotate_z[i]);
+               window->rotatez_text[i]->update(config.rotate_z[i]);
+       }
+
+       window->feather_slider->update(config.feather);
+       window->feather_text->update(config.feather);
+
+       window->mode->update(config.mode);
+       window->draw_guides->update(config.draw_guides);
+       window->unlock_window();
+}
+
+void SphereCamMain::save_data(KeyFrame *keyframe)
+{
+       FileXML output;
+       char string[BCTEXTLEN];
+
+// cause data to be stored directly in text
+       output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+       output.tag.set_title("SPHERECAM");
+       
+       for( int i = 0; i < EYES; i++ ) {
+               sprintf(string, "ENABLED_%d", i);
+               output.tag.set_property(string, config.enabled[i]);
+               sprintf(string, "FOV_%d", i);
+               output.tag.set_property(string, config.fov[i]);
+               sprintf(string, "RADIUS_%d", i);
+               output.tag.set_property(string, config.radius[i]);
+               sprintf(string, "CENTER_X_%d", i);
+               output.tag.set_property(string, config.center_x[i]);
+               sprintf(string, "CENTER_Y_%d", i);
+               output.tag.set_property(string, config.center_y[i]);
+               sprintf(string, "ROTATE_X_%d", i);
+               output.tag.set_property(string, config.rotate_x[i]);
+               sprintf(string, "ROTATE_Y_%d", i);
+               output.tag.set_property(string, config.rotate_y[i]);
+               sprintf(string, "ROTATE_Z_%d", i);
+               output.tag.set_property(string, config.rotate_z[i]);
+       }
+       
+       output.tag.set_property("FEATHER", config.feather);
+       output.tag.set_property("DRAW_GUIDES", config.draw_guides);
+       output.tag.set_property("MODE", config.mode);
+       output.append_tag();
+       output.terminate_string();
+}
+
+
+void SphereCamMain::read_data(KeyFrame *keyframe)
+{
+       FileXML input;
+       char string[BCTEXTLEN];
+
+
+       input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+
+       int result = 0;
+
+       while(!result)
+       {
+               result = input.read_tag();
+
+               if( !result ) {
+                       if( input.tag.title_is("SPHERECAM") ) {
+                               for( int i = 0; i < EYES; i++ ) {
+                                       sprintf(string, "ENABLED_%d", i);
+                                       config.enabled[i] = input.tag.get_property(string, config.enabled[i]);
+                                       sprintf(string, "FOV_%d", i);
+                                       config.fov[i] = input.tag.get_property(string, config.fov[i]);
+                                       sprintf(string, "RADIUS_%d", i);
+                                       config.radius[i] = input.tag.get_property(string, config.radius[i]);
+                                       sprintf(string, "CENTER_X_%d", i);
+                                       config.center_x[i] = input.tag.get_property(string, config.center_x[i]);
+                                       sprintf(string, "CENTER_Y_%d", i);
+                                       config.center_y[i] = input.tag.get_property(string, config.center_y[i]);
+                                       sprintf(string, "ROTATE_X_%d", i);
+                                       config.rotate_x[i] = input.tag.get_property(string, config.rotate_x[i]);
+                                       sprintf(string, "ROTATE_Y_%d", i);
+                                       config.rotate_y[i] = input.tag.get_property(string, config.rotate_y[i]);
+                                       sprintf(string, "ROTATE_Z_%d", i);
+                                       config.rotate_z[i] = input.tag.get_property(string, config.rotate_z[i]);
+                               }
+
+                               config.feather = input.tag.get_property("FEATHER", config.feather);
+                               config.draw_guides = input.tag.get_property("DRAW_GUIDES", config.draw_guides);
+                               config.mode = input.tag.get_property("MODE", config.mode);
+                       }
+               }
+       }
+}
+
+
+
+int SphereCamMain::process_buffer(VFrame *frame,
+       int64_t start_position,
+       double frame_rate)
+{
+       load_configuration();
+       
+       VFrame *input = new_temp(frame->get_w(), frame->get_h(), frame->get_color_model());
+       
+       read_frame(input, 0, start_position, frame_rate, 0); // use opengl
+
+//     find_lenses();
+       calculate_extents();
+
+       if( config.mode == SphereCamConfig::DO_NOTHING ) {
+               get_output()->copy_from(input);
+       }
+       else {
+               get_output()->clear_frame();
+               if( !engine ) engine = new SphereCamEngine(this);
+               engine->process_packages();
+       }
+
+       if( config.draw_guides ) {
+// input regions
+// printf("SphereCamMain::process_buffer %d %d %d\n", __LINE__, out_x1[0], out_x4[0]);
+               for( int eye = 0; eye < EYES; eye++ ) {
+                       if( config.enabled[eye] ) {
+// input regions
+                               get_output()->draw_oval(input_x[eye] - radius[eye], 
+                                       input_y[eye] - radius[eye], 
+                                       input_x[eye] + radius[eye], 
+                                       input_y[eye] + radius[eye]);
+
+
+// output regions.  If they overlap, don't xor out the line
+                               if( eye == 0 || (out_x1[eye] != out_x1[0] && out_x1[eye] != out_x4[0]) ) {
+                                       get_output()->draw_line(out_x1[eye], 0, out_x1[eye], h);
+                               }
+                               
+                               if( eye == 0 || (out_x4[eye] != out_x4[0] && out_x4[eye] != out_x1[0]) ) {
+                                       get_output()->draw_line(out_x4[eye], 0, out_x4[eye], h);
+                               }
+
+                               if( feather != 0 && eye == 1 ) {
+// crosshatch feather of right eye only, since only the right eye feathers
+                                       int feather_gap = h / 20;
+                                       for( int j = 0; j < h + feather; j += feather_gap ) {
+                                               draw_feather(out_x1[eye], out_x1[eye] + feather, eye, j);
+                                               draw_feather(out_x4[eye] - feather, out_x4[eye], eye, j);
+                                       }
+                               }
+                       }
+               }
+
+       }
+
+       return 0;
+}
+
+void SphereCamMain::draw_feather(int left, int right, int eye, int y)
+{
+       int slope = 1;
+       if( eye == 1 ) {
+               slope = -1;
+       }
+
+// wrap
+       if( left < 0 ) {
+               int left2 = w + left;
+               get_output()->draw_line(left2, y, left2 + right - left, y + feather * slope);
+       }
+
+       if( right > w ) {
+               int right2 = right - w;
+               get_output()->draw_line(0, y, right2, y + feather * slope);
+
+       }
+
+// proper
+       get_output()->draw_line(left, y, right, y + feather * slope);
+
+}
+
+
+// void SphereCamMain::find_lenses()
+// {
+// }
+
+
+void SphereCamMain::calculate_extents()
+{
+       w = get_output()->get_w();
+       h = get_output()->get_h();
+
+       feather = (int)(config.feather * w / 100);
+       
+       for( int i = 0; i < EYES; i++ ) {
+// input regions
+               input_x[i] = (int)(config.center_x[i] * w / 100);
+               input_y[i] = (int)(config.center_y[i] * h / 100);
+               radius[i] = (int)(h / 2 * config.radius[i] / 100);
+
+// output regions
+               output_x[i] = (int)(config.rotate_x[i] * w / 100);
+               output_y[i] = (int)(config.rotate_y[i] * h / 100);
+
+
+// Assume each lens fills 1/2 the width
+               out_x1[i] = output_x[i] - w / 4 - feather / 2;
+               out_x2[i] = output_x[i];
+               out_x3[i] = output_x[i];
+               out_x4[i] = output_x[i] + w / 4 + feather / 2;
+       }
+
+// If the output isn't 50% apart, we have to expand the left eye to fill the feathering region
+//printf("SphereCamMain::calculate_extents %d %f\n", __LINE__, config.rotate_x[0] - config.rotate_x[1]);
+       float x_separation = config.rotate_x[0] - config.rotate_x[1];
+       if( !EQUIV(fabs(x_separation), 50) ) {
+               if( x_separation < -50 ) {
+                       out_x4[0] += (-49.5 - x_separation) * w / 100;
+               }
+               else
+               if( x_separation < 0 ) {
+                       out_x1[0] -= (x_separation + 50) * w / 100;
+               }
+               else
+               if( x_separation < 50 ) {
+                       out_x4[0] += (50.5 - x_separation) * w / 100;
+               }
+               else {
+                       out_x1[0] -= (x_separation - 49.5) * w / 100;
+               }
+       }
+
+
+// wrap around
+       for( int i = 0; i < EYES; i++ ) {
+               if( out_x1[i] < 0 ) {
+                       out_x1[i] = w + out_x1[i];
+                       out_x2[i] = w;
+                       out_x3[i] = 0;
+               }
+
+               if( out_x4[i] > w ) {
+                       out_x2[i] = w;
+                       out_x3[i] = 0;
+                       out_x4[i] -= w;
+               }
+
+// printf("SphereCamMain::calculate_extents %d i=%d x=%d y=%d radius=%d\n", 
+// __LINE__, 
+// i, 
+// center_x[i],
+// center_y[i],
+// radius[i]);
+       }
+}
+
+SphereCamPackage::SphereCamPackage()
+ : LoadPackage() {}
+
+SphereCamUnit::SphereCamUnit(SphereCamEngine *engine, SphereCamMain *plugin)
+ : LoadClient(engine)
+{
+       this->plugin = plugin;
+}
+
+
+SphereCamUnit::~SphereCamUnit()
+{
+}
+
+
+
+// interpolate & accumulate a pixel in the output
+#define BLEND_PIXEL(type, components) \
+       if( x_in < 0.0 || x_in >= w - 1 || \
+           y_in < 0.0 || y_in >= h - 1 ) { \
+               out_row += components; \
+       } \
+       else { \
+               float y1_fraction = y_in - floor(y_in); \
+               float y2_fraction = 1.0 - y1_fraction; \
+               float x1_fraction = x_in - floor(x_in); \
+               float x2_fraction = 1.0 - x1_fraction; \
+               type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \
+               type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \
+               for( int i = 0; i < components; i++ ) { \
+                       float value = in_pixel1[i] * x2_fraction * y2_fraction + \
+                               in_pixel2[i] * x2_fraction * y1_fraction + \
+                               in_pixel1[i + components] * x1_fraction * y2_fraction + \
+                               in_pixel2[i + components] * x1_fraction * y1_fraction; \
+                       value = *out_row * inv_a + value * a; \
+                       *out_row++ = (type)value; \
+               } \
+       }
+
+
+// nearest neighbor & accumulate a pixel in the output
+#define BLEND_NEAREST(type, components) \
+       if( x_in < 0.0 || x_in >= w - 1 || \
+           y_in < 0.0 || y_in >= h - 1 ) { \
+               out_row += components; \
+       } \
+       else { \
+               type *in_pixel = in_rows[(int)y_in] + (int)x_in * components; \
+               for( int i = 0; i < components; i++ ) { \
+                       float value = in_pixel[i]; \
+                       value = *out_row * inv_a + value * a; \
+                       *out_row++ = (type)value; \
+               } \
+       }
+
+
+#define COLORSPACE_SWITCH(function) \
+       switch( plugin->get_input()->get_color_model() ) { \
+       case BC_RGB888:     function(unsigned char, 3, 0x0); break; \
+       case BC_RGBA8888:   function(unsigned char, 4, 0x0); break; \
+       case BC_RGB_FLOAT:  function(float, 3, 0.0); break; \
+       case BC_RGBA_FLOAT: function(float, 4, 0.0); break; \
+       case BC_YUV888:     function(unsigned char, 3, 0x80); break; \
+       case BC_YUVA8888:   function(unsigned char, 4, 0x80); break; \
+       }
+
+void SphereCamUnit::process_equirect(SphereCamPackage *pkg)
+{
+       VFrame *input = plugin->get_temp();
+       VFrame *output = plugin->get_output();
+
+
+// overlay a single eye
+#define PROCESS_EQUIRECT(type, components, chroma) \
+{ \
+       type **in_rows = (type**)input->get_rows(); \
+       type **out_rows = (type**)output->get_rows(); \
+ \
+       for( int out_y = row1; out_y < row2; out_y++ ) { \
+               type *out_row = out_rows[out_y]; \
+/* polar angle - -M_PI/2 to M_PI/2 */ \
+               float y_diff = out_y - output_y; \
+               float phi = M_PI / 2 * (y_diff / radius); \
+ \
+               for( int out_x = 0; out_x < w; out_x++ ) { \
+/* alpha */ \
+                       float a = alpha[out_x]; \
+                       float inv_a = 1.0f - a; \
+                       if( a > 0 ) { \
+/* polar angle */ \
+                               float x_diff = out_x - output_x; \
+/* -M_PI/2 to M_PI/2 */ \
+                               float theta = M_PI / 2 * (x_diff / radius); \
+/* vector in 3D space */ \
+                               float vect_x = cos(phi) * sin(theta); \
+                               float vect_y = cos(phi) * cos(theta); \
+                               float vect_z = sin(phi); \
+/* fisheye angle & radius */ \
+                               float theta2 = atan2(vect_z, vect_x) - rotate_z; \
+                               float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \
+                               float r = radius * 2 * phi2 / fov; \
+/* pixel in fisheye space */ \
+                               float x_in = input_x + r * cos(theta2); \
+                               float y_in = input_y + r * sin(theta2); \
+ \
+                               BLEND_PIXEL(type, components) \
+                       } \
+                       else { \
+                               out_row += components; \
+                       } \
+               } \
+       } \
+}
+
+       int row1 = pkg->row1;
+       int row2 = pkg->row2;
+       for( int eye = 0; eye < EYES; eye++ ) {
+               if( plugin->config.enabled[eye] ) {
+                       int w = plugin->w;
+                       int h = plugin->h;
+                       float fov = plugin->config.fov[eye] * M_PI * 2 / 360;
+//                     float radius = plugin->radius[eye];
+                       float radius = h / 2;
+                       float input_x = plugin->input_x[eye];
+                       float input_y = plugin->input_y[eye];
+                       float output_x = plugin->output_x[eye];
+                       float output_y = plugin->output_y[eye];
+                       float rotate_z = plugin->config.rotate_z[eye] * M_PI * 2 / 360;
+                       int feather = plugin->feather;
+                       int out_x1 = plugin->out_x1[eye];
+                       int out_x2 = plugin->out_x2[eye];
+                       int out_x3 = plugin->out_x3[eye];
+                       int out_x4 = plugin->out_x4[eye];
+
+// compute the alpha for every X
+                       float alpha[w];
+                       for( int i = 0; i < w; i++ ) {
+                               alpha[i] = 0;
+                       }
+
+                       for( int i = out_x1; i < out_x2; i++ ) {
+                               alpha[i] = 1.0f;
+                       }
+
+                       for( int i = out_x3; i < out_x4; i++ ) {
+                               alpha[i] = 1.0f;
+                       }
+                       
+                       if( eye == 1 ) {
+                               for( int i = out_x1; i < out_x1 + feather; i++ ) {
+                                       float value = (float)(i - out_x1) / feather;
+                                       if( i >= w ) {
+                                               alpha[i - w] = value;
+                                       }
+                                       else {
+                                               alpha[i] = value;
+                                       }
+                               }
+
+                               for( int i = out_x4 - feather; i < out_x4; i++ ) {
+                                       float value = (float)(out_x4 - i) / feather;
+                                       if( i < 0 ) {
+                                               alpha[w + i] = value;
+                                       }
+                                       else {
+                                               alpha[i] = value;
+                                       }
+                               }
+                       }
+                       
+
+//printf("SphereCamUnit::process_equirect %d rotate_x=%f rotate_y=%f rotate_z=%f\n", 
+// __LINE__, rotate_x, rotate_y, rotate_z);
+
+                       COLORSPACE_SWITCH(PROCESS_EQUIRECT)
+               }
+       }
+}
+
+
+
+void SphereCamUnit::process_align(SphereCamPackage *pkg)
+{
+       VFrame *input = plugin->get_temp();
+       VFrame *output = plugin->get_output();
+
+
+// overlay a single eye
+#define PROCESS_ALIGN(type, components, chroma) \
+{ \
+       type **in_rows = (type**)input->get_rows(); \
+       type **out_rows = (type**)output->get_rows(); \
+ \
+       for( int out_y = row1; out_y < row2; out_y++ ) { \
+               type *out_row = out_rows[out_y]; \
+/* polar angle */ \
+/* -M_PI/2 to M_PI/2 */ \
+               float y_diff = out_y - output_y; \
+               float phi = M_PI / 2 * (y_diff / radius); \
+ \
+               for( int out_x = 0; out_x < w; out_x++ ) { \
+/* alpha */ \
+                       float a = alpha[out_x]; \
+                       float inv_a = 1.0f - a; \
+                       if( a > 0 ) { \
+/* polar angle */ \
+                               float x_diff = out_x - output_x; \
+/* -M_PI/2 to M_PI/2 */ \
+                               float theta = M_PI / 2 * (x_diff / radius); \
+       /* vector in 3D space */ \
+                               float vect_x = cos(phi) * sin(theta); \
+                               float vect_y = cos(phi) * cos(theta); \
+                               float vect_z = sin(phi); \
+       /* fisheye angle & radius */ \
+                               float theta2 = atan2(vect_z, vect_x) - rotate_z; \
+                               float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \
+                               float r = radius * 2 * phi2 / fov; \
+       /* pixel in fisheye space */ \
+                               float x_in = input_x + r * cos(theta2); \
+                               float y_in = input_y + r * sin(theta2); \
+       \
+                               BLEND_NEAREST(type, components) \
+                       } \
+                       else { \
+                               out_row += components; \
+                       } \
+               } \
+       } \
+}
+
+       int row1 = pkg->row1;
+       int row2 = pkg->row2;
+       for( int eye = 0; eye < EYES; eye++ ) {
+               if( plugin->config.enabled[eye] ) {
+                       int w = plugin->w;
+                       int h = plugin->h;
+                       float fov = plugin->config.fov[eye] * M_PI * 2 / 360;
+//                     float radius = plugin->radius[eye];
+                       float radius = h / 2;
+                       float input_x = plugin->input_x[eye];
+                       float input_y = plugin->input_y[eye];
+                       float output_x = plugin->output_x[eye];
+                       float output_y = plugin->output_y[eye];
+                       float rotate_z = plugin->config.rotate_z[eye] * M_PI * 2 / 360;
+                       int out_x1 = plugin->out_x1[eye];
+                       int out_x2 = plugin->out_x2[eye];
+                       int out_x3 = plugin->out_x3[eye];
+                       int out_x4 = plugin->out_x4[eye];
+// left eye is opaque.  right eye overlaps
+// compute the alpha for every X
+                       float alpha[w];
+                       for( int i = 0; i < w; i++ ) alpha[i] = 0;
+                       float v = eye == 0 || !plugin->config.enabled[0] ? 1.0f : 0.5f;
+                       for( int i = out_x1; i < out_x2; i++ ) alpha[i] = v;
+                       for( int i = out_x3; i < out_x4; i++ ) alpha[i] = v;
+
+                       COLORSPACE_SWITCH(PROCESS_ALIGN)
+               }
+       }
+}
+
+void SphereCamUnit::process_package(LoadPackage *package)
+{
+       SphereCamPackage *pkg = (SphereCamPackage*)package;
+
+       switch( plugin->config.mode ) {
+       case SphereCamConfig::EQUIRECT:
+               process_equirect(pkg);
+               break;
+       case SphereCamConfig::ALIGN:
+               process_align(pkg);
+               break;
+       }
+}
+
+
+SphereCamEngine::SphereCamEngine(SphereCamMain *plugin)
+ : LoadServer(plugin->PluginClient::smp + 1, plugin->PluginClient::smp + 1)
+// : LoadServer(1, 1)
+{
+       this->plugin = plugin;
+}
+
+SphereCamEngine::~SphereCamEngine()
+{
+}
+
+void SphereCamEngine::init_packages()
+{
+       for( int i = 0; i < LoadServer::get_total_packages(); i++ ) {
+               SphereCamPackage *package = (SphereCamPackage*)LoadServer::get_package(i);
+               package->row1 = plugin->get_input()->get_h() * i / LoadServer::get_total_packages();
+               package->row2 = plugin->get_input()->get_h() * (i + 1) / LoadServer::get_total_packages();
+       }
+}
+
+LoadClient* SphereCamEngine::new_client()
+{
+       return new SphereCamUnit(this, plugin);
+}
+
+LoadPackage* SphereCamEngine::new_package()
+{
+       return new SphereCamPackage;
+}
+
+
diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.C.bak b/cinelerra-5.1/plugins/spherecam/spherecam.C.bak
new file mode 100644 (file)
index 0000000..99d4077
--- /dev/null
@@ -0,0 +1,1310 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#include "affine.h"
+#include "bcdisplayinfo.h"
+#include "bchash.h"
+#include "bcsignals.h"
+#include "clip.h"
+#include "filexml.h"
+#include "language.h"
+#include "360fuser.h"
+
+
+#include <string.h>
+
+
+
+// largely based on equations from http://paulbourke.net/dome/fish2/
+
+
+
+REGISTER_PLUGIN(Fuse360Main)
+
+
+
+
+Fuse360Config::Fuse360Config()
+{
+       fov = 1.0;
+       radius_x = 0.5;
+       radius_y = 0.5;
+       center_x = 50.0;
+       center_y = 50.0;
+       distance_x = 50;
+       distance_y = 0;
+       feather = 0;
+       translate_x = 0;
+       rotation = 0;
+       draw_guides = 1;
+       mode = Fuse360Config::DO_NOTHING;
+}
+
+int Fuse360Config::equivalent(Fuse360Config &that)
+{
+       if(EQUIV(fov, that.fov) &&
+               EQUIV(radius_x, that.radius_x) &&
+               EQUIV(radius_y, that.radius_y) &&
+               EQUIV(feather, that.feather) && 
+               EQUIV(center_x, that.center_x) &&
+               EQUIV(center_y, that.center_y) &&
+               EQUIV(distance_x, that.distance_x) &&
+               EQUIV(distance_y, that.distance_y) &&
+               EQUIV(translate_x, that.translate_x) &&
+               EQUIV(rotation, that.rotation) &&
+               mode == that.mode &&
+               draw_guides == that.draw_guides)
+       {
+               return 1;
+       }
+       else
+       {
+               return 0;
+       }
+}
+
+void Fuse360Config::copy_from(Fuse360Config &that)
+{
+       *this = that;
+}
+
+void Fuse360Config::interpolate(Fuse360Config &prev, 
+       Fuse360Config &next, 
+       int64_t prev_frame, 
+       int64_t next_frame, 
+       int64_t current_frame)
+{
+       double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
+       double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
+
+       fov = prev.fov * prev_scale + next.fov * next_scale;
+       radius_x = prev.radius_x * prev_scale + next.radius_x * next_scale;
+       radius_y = prev.radius_y * prev_scale + next.radius_y * next_scale;
+       feather = prev.feather * prev_scale + next.feather * next_scale;
+       center_x = prev.center_x * prev_scale + next.center_x * next_scale;
+       center_y = prev.center_y * prev_scale + next.center_y * next_scale;
+       distance_x = prev.distance_x * prev_scale + next.distance_x * next_scale;
+       distance_y = prev.distance_y * prev_scale + next.distance_y * next_scale;
+       rotation = prev.rotation * prev_scale + next.rotation * next_scale;
+       translate_x = prev.translate_x * prev_scale + next.translate_x * next_scale;
+       draw_guides = prev.draw_guides;
+       mode = prev.mode;
+
+       boundaries();
+}
+
+void Fuse360Config::boundaries()
+{
+       CLAMP(fov, 0.0, 1.0);
+       CLAMP(radius_x, 0.3, 1.0);
+       CLAMP(radius_y, 0.3, 1.0);
+       CLAMP(feather, 0, 50);
+       CLAMP(center_x, 0.0, 99.0);
+       CLAMP(center_y, 0.0, 99.0);
+       CLAMP(distance_x, 0.0, 100.0);
+       CLAMP(distance_y, -50.0, 50.0);
+       CLAMP(translate_x, -100, 100);
+       CLAMP(rotation, -180, 180);
+}
+
+
+
+
+Fuse360Slider::Fuse360Slider(Fuse360Main *client, 
+       Fuse360GUI *gui,
+       Fuse360Text *text,
+       float *output, 
+       int x, 
+       int y, 
+       float min,
+       float max)
+ : BC_FSlider(x, y, 0, 200, 200, min, max, *output)
+{
+       this->gui = gui;
+       this->client = client;
+       this->output = output;
+       this->text = text;
+       set_precision(0.01);
+}
+
+int Fuse360Slider::handle_event()
+{
+       float prev_output = *output;
+       *output = get_value();
+       text->update(*output);
+
+
+       client->send_configure_change();
+       return 1;
+}
+
+
+
+Fuse360Text::Fuse360Text(Fuse360Main *client, 
+       Fuse360GUI *gui,
+       Fuse360Slider *slider,
+       float *output, 
+       int x, 
+       int y)
+ : BC_TextBox(x, y, 100, 1, *output)
+{
+       this->gui = gui;
+       this->client = client;
+       this->output = output;
+       this->slider = slider;
+}
+
+int Fuse360Text::handle_event()
+{
+       float prev_output = *output;
+       *output = atof(get_text());
+       slider->update(*output);
+
+
+       client->send_configure_change();
+       return 1;
+}
+
+
+
+Fuse360Toggle::Fuse360Toggle(Fuse360Main *client, 
+       int *output, 
+       int x, 
+       int y,
+       const char *text)
+ : BC_CheckBox(x, y, *output, text)
+{
+       this->output = output;
+       this->client = client;
+}
+
+int Fuse360Toggle::handle_event()
+{
+       *output = get_value();
+       client->send_configure_change();
+       return 1;
+}
+
+
+
+
+
+
+
+
+
+
+Fuse360Mode::Fuse360Mode(Fuse360Main *plugin,  
+       Fuse360GUI *gui,
+       int x,
+       int y)
+ : BC_PopupMenu(x,
+       y,
+       calculate_w(gui),
+       "",
+       1)
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+
+int Fuse360Mode::handle_event()
+{
+       plugin->config.mode = from_text(get_text());
+       plugin->send_configure_change();
+       return 1;
+
+}
+
+void Fuse360Mode::create_objects()
+{
+       add_item(new BC_MenuItem(to_text(Fuse360Config::DO_NOTHING)));
+       add_item(new BC_MenuItem(to_text(Fuse360Config::STRETCHXY)));
+       add_item(new BC_MenuItem(to_text(Fuse360Config::STANDARD)));
+       add_item(new BC_MenuItem(to_text(Fuse360Config::BLEND)));
+       update(plugin->config.mode);
+}
+
+void Fuse360Mode::update(int mode)
+{
+       char string[BCTEXTLEN];
+       sprintf(string, "%s", to_text(mode));
+       set_text(string);
+}
+
+int Fuse360Mode::calculate_w(Fuse360GUI *gui)
+{
+       int result = 0;
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::STRETCHXY)));
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::STANDARD)));
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::BLEND)));
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(Fuse360Config::DO_NOTHING)));
+       return result + 50;
+}
+
+int Fuse360Mode::from_text(char *text)
+{
+       for(int i = 0; i < 4; i++)
+       {
+               if(!strcmp(text, to_text(i)))
+               {
+                       return i;
+               }
+       }
+
+       return Fuse360Config::STRETCHXY;
+}
+
+const char* Fuse360Mode::to_text(int mode)
+{
+       switch(mode)
+       {
+               case Fuse360Config::DO_NOTHING:
+                       return "Do nothing";
+                       break;
+               case Fuse360Config::STRETCHXY:
+                       return "Stretch";
+                       break;
+               case Fuse360Config::STANDARD:
+                       return "Equirectangular";
+                       break;
+       }
+       return "Blend";
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fuse360GUI::Fuse360GUI(Fuse360Main *client)
+ : PluginClientWindow(client,
+       350, 
+       650, 
+       350, 
+       650, 
+       0)
+{
+       this->client = client;
+}
+
+Fuse360GUI::~Fuse360GUI()
+{
+}
+
+
+void Fuse360GUI::create_objects()
+{
+       int x = 10;
+       int y = 10;
+       int x1;
+       int margin = 10;
+       BC_Title *title;
+       Fuse360Toggle *toggle;
+
+//     add_tool(title = new BC_Title(x, y, _("Field of View:")));
+//     y += title->get_h() + 5;
+//     add_tool(fov_slider = new Fuse360Slider(client, 
+//             this,
+//             0,
+//             &client->config.fov, 
+//             x, 
+//             y, 
+//             0.0001,
+//             1.0));
+// 
+// 
+//     x1 = x + fov_slider->get_w() + margin;
+//     add_tool(fov_text = new Fuse360Text(client, 
+//             this,
+//             fov_slider,
+//             &client->config.fov, 
+//             x1, 
+//             y));
+//     fov_slider->text = fov_text;
+//     y += fov_text->get_h() + margin;
+
+
+
+
+       add_tool(title = new BC_Title(x, y, _("Eye Radius X:")));
+       y += title->get_h() + 5;
+       add_tool(radiusx_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.radius_x, 
+               x, 
+               y, 
+               0.3,
+               1.0));
+       x1 = x + radiusx_slider->get_w() + margin;
+       add_tool(radiusx_text = new Fuse360Text(client, 
+               this,
+               radiusx_slider,
+               &client->config.radius_x, 
+               x1, 
+               y));
+       radiusx_slider->text = radiusx_text;
+       y += radiusx_text->get_h() + 5;
+
+
+       add_tool(title = new BC_Title(x, y, _("Eye Radius Y:")));
+       y += title->get_h() + margin;
+       add_tool(radiusy_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.radius_y, 
+               x, 
+               y, 
+               0.3,
+               1.0));
+       x1 = x + radiusy_slider->get_w() + margin;
+       add_tool(radiusy_text = new Fuse360Text(client, 
+               this,
+               radiusy_slider,
+               &client->config.radius_y, 
+               x1, 
+               y));
+       radiusy_slider->text = radiusy_text;
+       y += radiusy_text->get_h() + margin;
+
+
+//     add_tool(title = new BC_Title(x, y, _("Center X:")));
+//     y += title->get_h() + 5;
+//     add_tool(centerx_slider = new Fuse360Slider(client, 
+//             this,
+//             0,
+//             &client->config.center_x, 
+//             x, 
+//             y, 
+//             0.0,
+//             99.0));
+//     x1 = x + centerx_slider->get_w() + margin;
+//     add_tool(centerx_text = new Fuse360Text(client, 
+//             this,
+//             centerx_slider,
+//             &client->config.center_x, 
+//             x1, 
+//             y));
+//     centerx_slider->text = centerx_text;
+//     centerx_slider->set_precision(0.1);
+//     y += centerx_text->get_h() + margin;
+// 
+// 
+//     add_tool(title = new BC_Title(x, y, _("Center Y:")));
+//     y += title->get_h() + 5;
+//     add_tool(centery_slider = new Fuse360Slider(client, 
+//             this,
+//             0,
+//             &client->config.center_y, 
+//             x, 
+//             y, 
+//             0.0,
+//             99.0));
+//     x1 = x + centery_slider->get_w() + margin;
+//     add_tool(centery_text = new Fuse360Text(client, 
+//             this,
+//             centery_slider,
+//             &client->config.center_y, 
+//             x1, 
+//             y));
+//     centery_slider->text = centery_text;
+//     centery_slider->set_precision(0.1);
+//     y += centery_text->get_h() + margin;
+
+
+
+
+       add_tool(title = new BC_Title(x, y, _("X Eye Spacing:")));
+       y += title->get_h() + 5;
+       add_tool(distancex_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.distance_x, 
+               x, 
+               y, 
+               0.0,
+               100.0));
+       x1 = x + distancex_slider->get_w() + margin;
+       add_tool(distancex_text = new Fuse360Text(client, 
+               this,
+               distancex_slider,
+               &client->config.distance_x, 
+               x1, 
+               y));
+       distancex_slider->text = distancex_text;
+       distancex_slider->set_precision(0.1);
+       y += distancex_text->get_h() + margin;
+
+
+
+
+
+
+
+       add_tool(title = new BC_Title(x, y, _("Y Eye Spacing:")));
+       y += title->get_h() + 5;
+       add_tool(distancey_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.distance_y, 
+               x, 
+               y, 
+               -50,
+               50));
+       x1 = x + distancey_slider->get_w() + margin;
+       add_tool(distancey_text = new Fuse360Text(client, 
+               this,
+               distancey_slider,
+               &client->config.distance_y, 
+               x1, 
+               y));
+       distancey_slider->text = distancey_text;
+       distancey_slider->set_precision(0.1);
+       y += distancey_text->get_h() + margin;
+
+
+
+
+
+
+       add_tool(title = new BC_Title(x, y, _("X Translation:")));
+       y += title->get_h() + 5;
+       add_tool(translatex_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.translate_x, 
+               x, 
+               y, 
+               -50.0,
+               50.0));
+       x1 = x + translatex_slider->get_w() + margin;
+       add_tool(translatex_text = new Fuse360Text(client, 
+               this,
+               translatex_slider,
+               &client->config.translate_x, 
+               x1, 
+               y));
+       translatex_slider->text = translatex_text;
+       translatex_slider->set_precision(0.1);
+       y += translatex_text->get_h() + margin;
+
+
+
+
+
+
+       add_tool(title = new BC_Title(x, y, _("Feather:")));
+       y += title->get_h() + 5;
+       add_tool(feather_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.feather, 
+               x, 
+               y, 
+               0,
+               50));
+       x1 = x + feather_slider->get_w() + margin;
+       add_tool(feather_text = new Fuse360Text(client, 
+               this,
+               feather_slider,
+               &client->config.feather, 
+               x1, 
+               y));
+       feather_slider->text = feather_text;
+       feather_slider->set_precision(1);
+       y += feather_text->get_h() + margin;
+
+
+
+
+
+
+       add_tool(title = new BC_Title(x, y, _("Rotation:")));
+       y += title->get_h() + 5;
+       add_tool(rotation_slider = new Fuse360Slider(client, 
+               this,
+               0,
+               &client->config.rotation, 
+               x, 
+               y, 
+               -180,
+               180));
+       x1 = x + rotation_slider->get_w() + margin;
+       add_tool(rotation_text = new Fuse360Text(client, 
+               this,
+               rotation_slider,
+               &client->config.rotation, 
+               x1, 
+               y));
+       rotation_slider->text = rotation_text;
+       rotation_slider->set_precision(0.1);
+       y += rotation_text->get_h() + margin;
+
+
+
+
+
+
+
+//printf("Fuse360GUI::create_objects %d %f\n", __LINE__, client->config.distance);
+
+
+       add_tool(draw_guides = new Fuse360Toggle(client, 
+               &client->config.draw_guides, 
+               x, 
+               y,
+               _("Draw guides")));
+       y += draw_guides->get_h() + margin;
+
+       
+       add_tool(title = new BC_Title(x, y, _("Mode:")));
+       add_tool(mode = new Fuse360Mode(client, 
+               this, 
+               x + title->get_w() + margin, 
+               y));
+       mode->create_objects();
+       y += mode->get_h() + margin;
+
+
+
+       show_window();
+       flush();
+}
+
+
+
+
+
+
+
+Fuse360Main::Fuse360Main(PluginServer *server)
+ : PluginVClient(server)
+{
+       engine = 0;
+       affine = 0;
+}
+
+Fuse360Main::~Fuse360Main()
+{
+       delete engine;
+       delete affine;
+}
+
+NEW_WINDOW_MACRO(Fuse360Main, Fuse360GUI)
+LOAD_CONFIGURATION_MACRO(Fuse360Main, Fuse360Config)
+int Fuse360Main::is_realtime() { return 1; }
+const char* Fuse360Main::plugin_title() { return N_("360 Fuser"); }
+
+void Fuse360Main::update_gui()
+{
+       if(thread)
+       {
+               if(load_configuration())
+               {
+                       ((Fuse360GUI*)thread->window)->lock_window("Fuse360Main::update_gui");
+//                     ((Fuse360GUI*)thread->window)->fov_slider->update(config.fov);
+//                     ((Fuse360GUI*)thread->window)->fov_text->update(config.fov);
+                       ((Fuse360GUI*)thread->window)->radiusx_slider->update(config.radius_x);
+                       ((Fuse360GUI*)thread->window)->radiusx_text->update(config.radius_x);
+                       ((Fuse360GUI*)thread->window)->radiusy_slider->update(config.radius_y);
+                       ((Fuse360GUI*)thread->window)->radiusy_text->update(config.radius_y);
+//                     ((Fuse360GUI*)thread->window)->centerx_slider->update(config.center_x);
+//                     ((Fuse360GUI*)thread->window)->centerx_text->update(config.center_x);
+//                     ((Fuse360GUI*)thread->window)->centery_slider->update(config.center_y);
+//                     ((Fuse360GUI*)thread->window)->centery_text->update(config.center_y);
+                       ((Fuse360GUI*)thread->window)->distancex_slider->update(config.distance_x);
+                       ((Fuse360GUI*)thread->window)->distancex_text->update(config.distance_x);
+                       ((Fuse360GUI*)thread->window)->distancey_slider->update(config.distance_y);
+                       ((Fuse360GUI*)thread->window)->distancey_text->update(config.distance_y);
+                       ((Fuse360GUI*)thread->window)->translatex_slider->update(config.translate_x);
+                       ((Fuse360GUI*)thread->window)->translatex_text->update(config.translate_x);
+                       ((Fuse360GUI*)thread->window)->feather_slider->update(config.feather);
+                       ((Fuse360GUI*)thread->window)->feather_text->update(config.feather);
+                       ((Fuse360GUI*)thread->window)->rotation_slider->update(config.rotation);
+                       ((Fuse360GUI*)thread->window)->rotation_text->update(config.rotation);
+                       ((Fuse360GUI*)thread->window)->mode->update(config.mode);
+                       ((Fuse360GUI*)thread->window)->draw_guides->update(config.draw_guides);
+                       ((Fuse360GUI*)thread->window)->unlock_window();
+               }
+       }
+}
+
+
+void Fuse360Main::save_data(KeyFrame *keyframe)
+{
+       FileXML output;
+       char string[BCTEXTLEN];
+
+
+
+// cause data to be stored directly in text
+       output.set_shared_string(keyframe->get_data(), MESSAGESIZE);
+       output.tag.set_title("360FUSER");
+       output.tag.set_property("FOCAL_LENGTH", config.fov);
+       output.tag.set_property("RADIUS_X", config.radius_x);
+       output.tag.set_property("RADIUS_Y", config.radius_y);
+       output.tag.set_property("FEATHER", config.feather);
+       output.tag.set_property("CENTER_X", config.center_x);
+       output.tag.set_property("CENTER_Y", config.center_y);
+       output.tag.set_property("DISTANCE_X", config.distance_x);
+       output.tag.set_property("DISTANCE_Y", config.distance_y);
+       output.tag.set_property("TRANSLATE_X", config.translate_x);
+       output.tag.set_property("ROTATION", config.rotation);
+       output.tag.set_property("DRAW_GUIDES", config.draw_guides);
+       output.tag.set_property("MODE", config.mode);
+       output.append_tag();
+       output.terminate_string();
+
+}
+
+
+void Fuse360Main::read_data(KeyFrame *keyframe)
+{
+       FileXML input;
+       char string[BCTEXTLEN];
+
+
+       input.set_shared_string(keyframe->get_data(), strlen(keyframe->get_data()));
+
+       int result = 0;
+
+       while(!result)
+       {
+               result = input.read_tag();
+
+               if(!result)
+               {
+                       if(input.tag.title_is("360FUSER"))
+                       {
+                               config.fov = input.tag.get_property("FOCAL_LENGTH", config.fov);
+                               config.radius_x = input.tag.get_property("RADIUS_X", config.radius_x);
+                               config.radius_y = input.tag.get_property("RADIUS_Y", config.radius_y);
+                               config.feather = input.tag.get_property("FEATHER", config.feather);
+                               config.center_x = input.tag.get_property("CENTER_X", config.center_x);
+                               config.center_y = input.tag.get_property("CENTER_Y", config.center_y);
+                               config.distance_x = input.tag.get_property("DISTANCE_X", config.distance_x);
+                               config.distance_y = input.tag.get_property("DISTANCE_Y", config.distance_y);
+                               config.translate_x = input.tag.get_property("TRANSLATE_X", config.translate_x);
+                               config.rotation = input.tag.get_property("ROTATION", config.rotation);
+                               config.draw_guides = input.tag.get_property("DRAW_GUIDES", config.draw_guides);
+                               config.mode = input.tag.get_property("MODE", config.mode);
+                       }
+               }
+       }
+}
+
+
+
+int Fuse360Main::process_buffer(VFrame *frame,
+       int64_t start_position,
+       double frame_rate)
+{
+       load_configuration();
+       
+       VFrame *input = new_temp(frame->get_w(), frame->get_h(), frame->get_color_model());
+       
+       read_frame(input, 
+               0, 
+               start_position, 
+               frame_rate,
+               0); // use opengl
+
+       calculate_extents();
+
+// always rotate it
+       if(!EQUIV(config.rotation, 0))
+       {
+               int center_x = w / 2;
+               int center_y = h / 2;
+               int center_x1 = w / 4;
+               int center_y1 = h / 2;
+               int center_x2 = w * 3 / 4;
+               int center_y2 = h / 2;
+               int radius_x = 0;
+               int radius_y = 0;
+
+               radius_x = config.radius_x * w / 2;
+               radius_y = config.radius_y * h;
+
+               if(!affine) affine = new AffineEngine(PluginClient::smp + 1, 
+                       PluginClient::smp + 1);
+               affine->set_in_pivot(center_x1, center_y1);
+               affine->set_in_viewport(0, 0, center_x, h);
+               affine->set_out_viewport(0, 0, center_x, h);
+               affine->rotate(get_output(),
+                       input, 
+                       config.rotation);
+
+               affine->set_in_pivot(center_x2, center_y2);
+               affine->set_in_viewport(center_x, 0, w - center_x, h);
+               affine->set_out_viewport(center_x, 0, w - center_x, h);
+               affine->rotate(get_output(),
+                       input, 
+                       -config.rotation);
+
+               input->copy_from(get_output());
+               get_output()->clear_frame();
+
+       }
+
+       if(config.mode == Fuse360Config::DO_NOTHING)
+       {
+               get_output()->copy_from(input);
+       }
+       else
+       {
+
+               if(!engine) engine = new Fuse360Engine(this);
+               engine->process_packages();
+       }
+
+
+
+       if(config.draw_guides)
+       {
+
+               get_output()->draw_line(center_x, 0, center_x, h);
+
+// draw lenses
+               get_output()->draw_oval(center_x1 - radius_x + distance_x, 
+                       center_y1 - radius_y + distance_y, 
+                       center_x1 + radius_x + distance_x, 
+                       center_y1 + radius_y + distance_y);
+               get_output()->draw_oval(center_x2 - radius_x - distance_x, 
+                       center_y2 - radius_y - distance_y, 
+                       center_x2 + radius_x - distance_x, 
+                       center_y2 + radius_y - distance_y);
+
+// draw feather
+               get_output()->draw_line(feather_x1, 0, feather_x1, h);
+               get_output()->draw_line(feather_x2, 0, feather_x2, h);
+               
+
+       }
+
+       return 0;
+}
+
+
+void Fuse360Main::calculate_extents()
+{
+       w = get_output()->get_w();
+       h = get_output()->get_h();
+       center_x = w / 2;
+       center_y = h / 2;
+       center_x1 = w * 1 / 4;
+       center_y1 = h / 2;
+       center_x2 = w * 3 / 4;
+       center_y2 = h / 2;
+       radius_x = 0;
+       radius_y = 0;
+       distance_x = (int)((50 - config.distance_x) * w / 100 / 2);
+       distance_y = (int)(config.distance_y * h / 100 / 2);
+       feather = (int)(config.feather * w / 100);
+       feather_x1 = center_x - (int)(config.feather * w / 100 / 2);
+       feather_x2 = center_x + (int)(config.feather * w / 100 / 2);
+       radius_x = config.radius_x * w / 2;
+       radius_y = config.radius_y * h;
+//printf("Fuse360Main::calculate_extents %d radius_y=%d\n", __LINE__, radius_y);
+}
+
+
+
+
+
+Fuse360Package::Fuse360Package()
+ : LoadPackage() {}
+
+
+
+
+
+Fuse360Unit::Fuse360Unit(Fuse360Engine *engine, Fuse360Main *plugin)
+ : LoadClient(engine)
+{
+       this->plugin = plugin;
+}
+
+
+Fuse360Unit::~Fuse360Unit()
+{
+}
+
+
+
+void Fuse360Unit::process_blend(Fuse360Package *pkg)
+{
+       VFrame *input = plugin->get_temp();
+       VFrame *output = plugin->get_output();
+
+       int row1 = pkg->row1;
+       int row2 = pkg->row2;
+       int width = input->get_w();
+       int height = input->get_h();
+
+#define PROCESS_BLEND(type, components, chroma) \
+{ \
+       type **in_rows = (type**)input->get_rows(); \
+       type **out_rows = (type**)output->get_rows(); \
+       type black[4] = { 0, chroma, chroma, 0 }; \
+ \
+       for(int y = row1; y < row2; y++) \
+       { \
+               type *out_row = out_rows[y]; \
+               type *in_row = in_rows[y]; \
+ \
+               for(int x = 0; x < width; x++) \
+               { \
+               } \
+       } \
+}
+
+
+       switch(plugin->get_input()->get_color_model())
+       {
+               case BC_RGB888:
+                       PROCESS_BLEND(unsigned char, 3, 0x0);
+                       break;
+               case BC_RGBA8888:
+                       PROCESS_BLEND(unsigned char, 4, 0x0);
+                       break;
+               case BC_RGB_FLOAT:
+                       PROCESS_BLEND(float, 3, 0.0);
+                       break;
+               case BC_RGBA_FLOAT:
+                       PROCESS_BLEND(float, 4, 0.0);
+                       break;
+               case BC_YUV888:
+                       PROCESS_BLEND(unsigned char, 3, 0x80);
+                       break;
+               case BC_YUVA8888:
+                       PROCESS_BLEND(unsigned char, 4, 0x80);
+                       break;
+       }
+       
+}
+
+// interpolate 1 eye
+#define BLEND_PIXEL(type, components) \
+       if(x_in < 0.0 || x_in >= w - 1 || \
+               y_in < 0.0 || y_in >= h - 1) \
+       { \
+               *out_row++ = black[0]; \
+               *out_row++ = black[1]; \
+               *out_row++ = black[2]; \
+               if(components == 4) *out_row++ = black[3]; \
+       } \
+       else \
+       { \
+               float y1_fraction = y_in - floor(y_in); \
+               float y2_fraction = 1.0 - y1_fraction; \
+               float x1_fraction = x_in - floor(x_in); \
+               float x2_fraction = 1.0 - x1_fraction; \
+               type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \
+               type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \
+               for(int i = 0; i < components; i++) \
+               { \
+                       *out_row++ = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
+                               in_pixel2[i] * x2_fraction * y1_fraction + \
+                               in_pixel1[i + components] * x1_fraction * y2_fraction + \
+                               in_pixel2[i + components] * x1_fraction * y1_fraction); \
+               } \
+       }
+
+
+// interpolate 2 eyes
+#define BLEND_PIXEL2(type, components) \
+       type pixel1[components], pixel2[components]; \
+ \
+/* calculate the left eye */ \
+       if(x_in1 < 0.0 || x_in1 >= w - 1 || \
+               y_in1 < 0.0 || y_in1 >= h - 1) \
+       { \
+               pixel1[0] = black[0]; \
+               pixel1[1] = black[1]; \
+               pixel1[2] = black[2]; \
+               if(components == 4) pixel1[3] = black[3]; \
+       } \
+       else \
+       { \
+               float y1_fraction = y_in1 - floor(y_in1); \
+               float y2_fraction = 1.0 - y1_fraction; \
+               float x1_fraction = x_in1 - floor(x_in1); \
+               float x2_fraction = 1.0 - x1_fraction; \
+               type *in_pixel1 = in_rows[(int)y_in1] + (int)x_in1 * components; \
+               type *in_pixel2 = in_rows[(int)y_in1 + 1] + (int)x_in1 * components; \
+               for(int i = 0; i < components; i++) \
+               { \
+                       pixel1[i] = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
+                               in_pixel2[i] * x2_fraction * y1_fraction + \
+                               in_pixel1[i + components] * x1_fraction * y2_fraction + \
+                               in_pixel2[i + components] * x1_fraction * y1_fraction); \
+               } \
+       } \
+ \
+ \
+/* calculate the right eye */ \
+       if(x_in2 < 0.0 || x_in2 >= w - 1 || \
+               y_in2 < 0.0 || y_in2 >= h - 1) \
+       { \
+               pixel2[0] = black[0]; \
+               pixel2[1] = black[1]; \
+               pixel2[2] = black[2]; \
+               if(components == 4) pixel2[3] = black[3]; \
+       } \
+       else \
+       { \
+               float y1_fraction = y_in2 - floor(y_in2); \
+               float y2_fraction = 1.0 - y1_fraction; \
+               float x1_fraction = x_in2 - floor(x_in2); \
+               float x2_fraction = 1.0 - x1_fraction; \
+               type *in_pixel1 = in_rows[(int)y_in2] + (int)x_in2 * components; \
+               type *in_pixel2 = in_rows[(int)y_in2 + 1] + (int)x_in2 * components; \
+               for(int i = 0; i < components; i++) \
+               { \
+                       pixel2[i] = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
+                               in_pixel2[i] * x2_fraction * y1_fraction + \
+                               in_pixel1[i + components] * x1_fraction * y2_fraction + \
+                               in_pixel2[i + components] * x1_fraction * y1_fraction); \
+               } \
+       } \
+ \
+/* blend the 2 eyes */ \
+       for(int i = 0; i < components; i++) \
+       { \
+               *out_row++ = (type)(pixel1[i] * (1.0f - fraction) + \
+                       pixel2[i] * fraction); \
+       } \
+
+
+
+
+#define COLORSPACE_SWITCH(function) \
+       switch(plugin->get_input()->get_color_model()) \
+       { \
+               case BC_RGB888: \
+                       function(unsigned char, 3, 0x0); \
+                       break; \
+               case BC_RGBA8888: \
+                       function(unsigned char, 4, 0x0); \
+                       break; \
+               case BC_RGB_FLOAT: \
+                       function(float, 3, 0.0); \
+                       break; \
+               case BC_RGBA_FLOAT: \
+                       function(float, 4, 0.0); \
+                       break; \
+               case BC_YUV888: \
+                       function(unsigned char, 3, 0x80); \
+                       break; \
+               case BC_YUVA8888: \
+                       function(unsigned char, 4, 0x80); \
+                       break; \
+       }
+
+
+double Fuse360Unit::calculate_max_z(double a, double r)
+{
+       if(a < 0) a += 2 * M_PI;
+
+       if(a < M_PI / 4)
+       {
+               return r / cos(a); // bottom right edge
+       }
+       else
+       if(a < 3 * M_PI / 4)
+       {
+               return r / cos(M_PI / 2 - a); // bottom edge
+       }
+       else
+       if(a < 5 * M_PI / 4)
+       {
+               return r / cos(M_PI - a); // left edge
+       }
+       else
+       if(a < 7 * M_PI / 4)
+       {
+               return r / cos(3 * M_PI / 2 - a); // top edge
+       }
+       else
+       {
+               return r / cos(a); // top right edge
+       }
+}
+
+void Fuse360Unit::process_stretch(Fuse360Package *pkg)
+{
+       VFrame *input = plugin->get_temp();
+       VFrame *output = plugin->get_output();
+
+       float fov = plugin->config.fov;
+       int row1 = pkg->row1;
+       int row2 = pkg->row2;
+       int center_x1 = plugin->center_x1;
+       int center_x2 = plugin->center_x2;
+       int center_y1 = plugin->center_y1;
+       int center_y2 = plugin->center_y2;
+       int center_x = plugin->center_x;
+       int center_y = plugin->center_y;
+       int w = plugin->w;
+       int h = plugin->h;
+       double radius = plugin->radius_x;
+
+
+#define PROCESS_STRETCH(type, components, chroma) \
+{ \
+       type **in_rows = (type**)input->get_rows(); \
+       type **out_rows = (type**)output->get_rows(); \
+       type black[4] = { 0, chroma, chroma, 0 }; \
+ \
+       for(int y = row1; y < row2; y++) \
+       { \
+               type *out_row = out_rows[y]; \
+               type *in_row = in_rows[y]; \
+               double y_diff = y - center_y1; \
+ \
+/* left eye */ \
+               for(int x = 0; x < center_x; x++) \
+               { \
+                       double x_diff = x - center_x1; \
+/* polar output coordinate */ \
+                       double z = hypot(x_diff, y_diff); \
+                       double a = atan2(y_diff, x_diff); \
+ \
+/* scale the magnitude to the radius */ \
+                       double scaled_z = z * radius / calculate_max_z(a, radius); \
+/* xy input coordinate */ \
+                       double x_in = scaled_z * cos(a) + center_x1; \
+                       double y_in = scaled_z * sin(a) + center_y1; \
+ \
+                       if(x_in < center_x) \
+                       { \
+                               BLEND_PIXEL(type, components) \
+                       } \
+               } \
+       } \
+ \
+       for(int y = row1; y < row2; y++) \
+       { \
+               type *out_row = out_rows[y] + center_x * components; \
+               type *in_row = in_rows[y]; \
+               double y_diff = y - center_y2; \
+ \
+/* right eye */ \
+               for(int x = center_x; x < w; x++) \
+               { \
+                       double x_diff = x - center_x2; \
+/* polar output coordinate */ \
+                       double z = hypot(x_diff, y_diff); \
+                       double a = atan2(y_diff, x_diff); \
+ \
+/* scale the magnitude to the radius */ \
+                       double scaled_z = z * radius / calculate_max_z(a, radius); \
+/* xy input coordinate */ \
+                       double x_in = scaled_z * cos(a) + center_x2; \
+                       double y_in = scaled_z * sin(a) + center_y2; \
+ \
+                       if(x_in >= center_x) \
+                       { \
+                               BLEND_PIXEL(type, components) \
+                       } \
+               } \
+       } \
+}
+
+
+
+       COLORSPACE_SWITCH(PROCESS_STRETCH)
+}
+
+
+
+
+
+void Fuse360Unit::process_standard(Fuse360Package *pkg)
+{
+       VFrame *input = plugin->get_temp();
+       VFrame *output = plugin->get_output();
+
+       float fov = plugin->config.fov;
+       int row1 = pkg->row1;
+       int row2 = pkg->row2;
+       int center_x1 = plugin->center_x1;
+       int center_x2 = plugin->center_x2;
+       int center_y1 = plugin->center_y1;
+       int center_y2 = plugin->center_y2;
+       int center_x = plugin->center_x;
+       int center_y = plugin->center_y;
+       int feather = plugin->feather;
+       int feather_x1 = plugin->feather_x1;
+       int feather_x2 = plugin->feather_x2;
+       int w = plugin->w;
+       int h = plugin->h;
+       float radius_x = plugin->radius_x;
+       float radius_y = plugin->radius_y;
+       int distance_x = plugin->distance_x;
+       int distance_y = plugin->distance_y;
+// field of view of the fisheye
+       float FOV = M_PI;
+
+#define PROCESS_STANDARD(type, components, chroma) \
+{ \
+       type **in_rows = (type**)input->get_rows(); \
+       type **out_rows = (type**)output->get_rows(); \
+       type black[4] = { 0, chroma, chroma, 0 }; \
+ \
+/* left eye */ \
+       for(int y = row1; y < row2; y++) \
+       { \
+               type *out_row = out_rows[y]; \
+ \
+/* -M_PI/2 to M_PI/2 */ \
+               float y_diff = y - center_y1; \
+/* polar angles */ \
+               float phi = M_PI / 2 * (y_diff / radius_y); \
+               for(int x = 0; x < feather_x1; x++) \
+               { \
+                       float x_diff = x - center_x1; \
+/* polar angles */ \
+/* -M_PI/2 to M_PI/2 */ \
+                       float theta = M_PI / 2 * (x_diff / radius_x); \
+/* vector in 3D space */ \
+                       float vect_x = cos(phi) * sin(theta); \
+                       float vect_y = cos(phi) * cos(theta); \
+                       float vect_z = sin(phi); \
+/* fisheye angle & radius */ \
+                       float theta2 = atan2(vect_z, vect_x); \
+                       float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \
+                       float r = radius_x * 2 * phi2 / FOV; \
+/* pixel in fisheye space */ \
+                       float x_in = center_x1 + r * cos(theta2); \
+                       float y_in = center_y1 + r * sin(theta2); \
+ \
+                       BLEND_PIXEL(type, components) \
+               } \
+       } \
+ \
+ \
+ \
+/* right eye */ \
+       for(int y = row1; y < row2; y++) \
+       { \
+               type *out_row = out_rows[y] + components * feather_x2; \
+ \
+/* -M_PI/2 to M_PI/2 */ \
+               float y_diff = y - center_y2; \
+/* polar angles */ \
+               float phi = M_PI / 2 * (y_diff / radius_y); \
+               for(int x = feather_x2; x < w; x++) \
+               { \
+                       float x_diff = x - center_x2; \
+/* polar angles */ \
+/* -M_PI/2 to M_PI/2 */ \
+                       float theta = M_PI / 2 * (x_diff / radius_x); \
+/* vector in 3D space */ \
+                       float vect_x = cos(phi) * sin(theta); \
+                       float vect_y = cos(phi) * cos(theta); \
+                       float vect_z = sin(phi); \
+/* fisheye angle & radius */ \
+                       float theta2 = atan2(vect_z, vect_x); \
+                       float phi2 = atan2(hypot(vect_x, vect_z), vect_y); \
+                       float r = radius_x * 2 * phi2 / FOV; \
+/* pixel in fisheye space */ \
+                       float x_in = center_x2 + r * cos(theta2); \
+                       float y_in = center_y2 + r * sin(theta2); \
+ \
+                       BLEND_PIXEL(type, components) \
+               } \
+       } \
+ \
+ \
+}
+
+       COLORSPACE_SWITCH(PROCESS_STANDARD)
+}
+
+
+
+void Fuse360Unit::process_package(LoadPackage *package)
+{
+       Fuse360Package *pkg = (Fuse360Package*)package;
+
+       switch(plugin->config.mode)
+       {
+               case Fuse360Config::STRETCHXY:
+                       process_stretch(pkg);
+                       break;
+               case Fuse360Config::STANDARD:
+                       process_standard(pkg);
+                       break;
+               case Fuse360Config::BLEND:
+                       process_blend(pkg);
+                       break;
+       }
+}
+
+
+
+
+
+Fuse360Engine::Fuse360Engine(Fuse360Main *plugin)
+// : LoadServer(plugin->PluginClient::smp + 1, plugin->PluginClient::smp + 1)
+ : LoadServer(1, 1)
+{
+       this->plugin = plugin;
+}
+
+Fuse360Engine::~Fuse360Engine()
+{
+}
+
+void Fuse360Engine::init_packages()
+{
+       for(int i = 0; i < LoadServer::get_total_packages(); i++)
+       {
+               Fuse360Package *package = (Fuse360Package*)LoadServer::get_package(i);
+               package->row1 = plugin->get_input()->get_h() * i / LoadServer::get_total_packages();
+               package->row2 = plugin->get_input()->get_h() * (i + 1) / LoadServer::get_total_packages();
+       }
+}
+
+LoadClient* Fuse360Engine::new_client()
+{
+       return new Fuse360Unit(this, plugin);
+}
+
+LoadPackage* Fuse360Engine::new_package()
+{
+       return new Fuse360Package;
+}
+
+
diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.h b/cinelerra-5.1/plugins/spherecam/spherecam.h
new file mode 100644 (file)
index 0000000..cbc6ad2
--- /dev/null
@@ -0,0 +1,273 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef FUSE360_H
+#define FUSE360_H
+
+
+#include "affine.inc"
+#include "bchash.inc"
+#include "guicast.h"
+#include "loadbalance.h"
+#include "pluginvclient.h"
+#include "thread.h"
+
+
+class SphereCamEngine;
+class SphereCamGUI;
+class SphereCamMain;
+class SphereCamText;
+
+#define EYES 2
+
+class SphereCamSlider : public BC_FSlider
+{
+public:
+       SphereCamSlider(SphereCamMain *client, 
+               SphereCamGUI *gui,
+               SphereCamText *text,
+               float *output, 
+               int x, 
+               int y, 
+               float min,
+               float max);
+       int handle_event();
+
+       SphereCamGUI *gui;
+       SphereCamMain *client;
+       SphereCamText *text;
+       float *output;
+};
+
+class SphereCamText : public BC_TextBox
+{
+public:
+       SphereCamText(SphereCamMain *client, 
+               SphereCamGUI *gui,
+               SphereCamSlider *slider,
+               float *output, 
+               int x, 
+               int y);
+       int handle_event();
+
+       SphereCamGUI *gui;
+       SphereCamMain *client;
+       SphereCamSlider *slider;
+       float *output;
+};
+
+
+class SphereCamToggle : public BC_CheckBox
+{
+public:
+       SphereCamToggle(SphereCamMain *client, 
+               int *output, 
+               int x, 
+               int y,
+               const char *text);
+       int handle_event();
+
+       SphereCamMain *client;
+       int *output;
+};
+
+
+class SphereCamMode : public BC_PopupMenu
+{
+public:
+       SphereCamMode(SphereCamMain *plugin,  
+               SphereCamGUI *gui,
+               int x,
+               int y);
+       int handle_event();
+       void create_objects();
+       static int calculate_w(SphereCamGUI *gui);
+       static int from_text(char *text);
+       static const char* to_text(int mode);
+       void update(int mode);
+       SphereCamMain *plugin;
+       SphereCamGUI *gui;
+};
+
+
+class SphereCamGUI : public PluginClientWindow
+{
+public:
+       SphereCamGUI(SphereCamMain *client);
+       ~SphereCamGUI();
+       
+       void create_objects();
+
+       SphereCamMain *client;
+       SphereCamToggle *enabled[EYES];
+       SphereCamSlider *fov_slider[EYES];
+       SphereCamText *fov_text[EYES];
+       SphereCamSlider *radius_slider[EYES];
+       SphereCamText *radius_text[EYES];
+       SphereCamSlider *centerx_slider[EYES];
+       SphereCamText *centerx_text[EYES];
+       SphereCamSlider *centery_slider[EYES];
+       SphereCamText *centery_text[EYES];
+       SphereCamSlider *rotatex_slider[EYES];
+       SphereCamText *rotatex_text[EYES];
+       SphereCamSlider *rotatey_slider[EYES];
+       SphereCamText *rotatey_text[EYES];
+       SphereCamSlider *rotatez_slider[EYES];
+       SphereCamText *rotatez_text[EYES];
+       SphereCamSlider *feather_slider;
+       SphereCamText *feather_text;
+       
+       SphereCamMode *mode;
+       SphereCamToggle *draw_guides;
+};
+
+class SphereCamConfig
+{
+public:
+       SphereCamConfig();
+       int equivalent(SphereCamConfig &that);
+       void copy_from(SphereCamConfig &that);
+       void interpolate(SphereCamConfig &prev, 
+               SphereCamConfig &next, 
+               int64_t prev_frame, 
+               int64_t next_frame, 
+               int64_t current_frame);
+       void boundaries();
+
+
+       int enabled[EYES];
+// degrees 1-359
+       float fov[EYES];
+// radius of each eye 1-150
+       float radius[EYES];
+// center of 2 eyes  0-100
+       float center_x[EYES];
+       float center_y[EYES];
+// rotation  0-359
+       float rotate_x[EYES];
+       float rotate_y[EYES];
+       float rotate_z[EYES];
+// amount to feather eye edges 0-50
+       float feather;
+       int draw_guides;
+       int mode;
+       enum
+       {
+// draw guides only
+               DO_NOTHING,
+// the standard algorithm
+               EQUIRECT,
+// alignment only
+               ALIGN,
+       };
+};
+
+
+
+
+
+class SphereCamPackage : public LoadPackage
+{
+public:
+       SphereCamPackage();
+       int row1, row2;
+};
+
+
+class SphereCamUnit : public LoadClient
+{
+public:
+       SphereCamUnit(SphereCamEngine *engine, SphereCamMain *plugin);
+       ~SphereCamUnit();
+       
+       
+       void process_package(LoadPackage *package);
+       void process_equirect(SphereCamPackage *pkg);
+       void process_align(SphereCamPackage *pkg);
+       double calculate_max_z(double a, double r);
+
+       
+       SphereCamEngine *engine;
+       SphereCamMain *plugin;
+};
+
+class SphereCamEngine : public LoadServer
+{
+public:
+       SphereCamEngine(SphereCamMain *plugin);
+       ~SphereCamEngine();
+       
+       void init_packages();
+       LoadClient* new_client();
+       LoadPackage* new_package();
+       
+       SphereCamMain *plugin;
+};
+
+class SphereCamMain : public PluginVClient
+{
+public:
+       SphereCamMain(PluginServer *server);
+       ~SphereCamMain();
+
+       PLUGIN_CLASS_MEMBERS2(SphereCamConfig)
+       int process_buffer(VFrame *frame,
+               int64_t start_position,
+               double frame_rate);
+       void draw_feather(int left, int right, int eye, int y);
+       int is_realtime();
+       void update_gui();
+       void save_data(KeyFrame *keyframe);
+       void read_data(KeyFrame *keyframe);
+       void calculate_extents();
+       double calculate_max_z(double a, int r);
+
+// config values converted to pixels
+       int w;
+       int h;
+
+// the center of the output regions, shifted by the rotations
+       int output_x[EYES];
+       int output_y[EYES];
+// The output of each eye is split into 2 halves so it can wrap around
+       int out_x1[EYES];
+       int out_y1[EYES];
+       int out_x2[EYES];
+       int out_y2[EYES];
+       int out_x3[EYES];
+       int out_y3[EYES];
+       int out_x4[EYES];
+       int out_y4[EYES];
+// the center of the input regions
+       int input_x[EYES];
+       int input_y[EYES];
+// radius of the input regions for drawing the guide only
+       int radius[EYES];
+// pixels to add to the output regions
+       int feather;
+
+       SphereCamEngine *engine;
+       AffineEngine *affine;
+};
+
+
+
+#endif
diff --git a/cinelerra-5.1/plugins/spherecam/spherecam.h.bak b/cinelerra-5.1/plugins/spherecam/spherecam.h.bak
new file mode 100644 (file)
index 0000000..b3619c1
--- /dev/null
@@ -0,0 +1,272 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2017 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+#ifndef FUSE360_H
+#define FUSE360_H
+
+
+#include "affine.inc"
+#include "bchash.inc"
+#include "guicast.h"
+#include "loadbalance.h"
+#include "pluginvclient.h"
+#include "thread.h"
+
+
+class Fuse360Engine;
+class Fuse360GUI;
+class Fuse360Main;
+class Fuse360Text;
+
+
+class Fuse360Slider : public BC_FSlider
+{
+public:
+       Fuse360Slider(Fuse360Main *client, 
+               Fuse360GUI *gui,
+               Fuse360Text *text,
+               float *output, 
+               int x, 
+               int y, 
+               float min,
+               float max);
+       int handle_event();
+
+       Fuse360GUI *gui;
+       Fuse360Main *client;
+       Fuse360Text *text;
+       float *output;
+};
+
+class Fuse360Text : public BC_TextBox
+{
+public:
+       Fuse360Text(Fuse360Main *client, 
+               Fuse360GUI *gui,
+               Fuse360Slider *slider,
+               float *output, 
+               int x, 
+               int y);
+       int handle_event();
+
+       Fuse360GUI *gui;
+       Fuse360Main *client;
+       Fuse360Slider *slider;
+       float *output;
+};
+
+
+class Fuse360Toggle : public BC_CheckBox
+{
+public:
+       Fuse360Toggle(Fuse360Main *client, 
+               int *output, 
+               int x, 
+               int y,
+               const char *text);
+       int handle_event();
+
+       Fuse360Main *client;
+       int *output;
+};
+
+
+class Fuse360Mode : public BC_PopupMenu
+{
+public:
+       Fuse360Mode(Fuse360Main *plugin,  
+               Fuse360GUI *gui,
+               int x,
+               int y);
+       int handle_event();
+       void create_objects();
+       static int calculate_w(Fuse360GUI *gui);
+       static int from_text(char *text);
+       static const char* to_text(int mode);
+       void update(int mode);
+       Fuse360Main *plugin;
+       Fuse360GUI *gui;
+};
+
+
+class Fuse360GUI : public PluginClientWindow
+{
+public:
+       Fuse360GUI(Fuse360Main *client);
+       ~Fuse360GUI();
+       
+       void create_objects();
+
+       Fuse360Main *client;
+//     Fuse360Slider *fov_slider;
+//     Fuse360Text *fov_text;
+       Fuse360Slider *radiusx_slider;
+       Fuse360Text *radiusx_text;
+       Fuse360Slider *radiusy_slider;
+       Fuse360Text *radiusy_text;
+//     Fuse360Slider *centerx_slider;
+//     Fuse360Text *centerx_text;
+//     Fuse360Slider *centery_slider;
+//     Fuse360Text *centery_text;
+       Fuse360Slider *distancex_slider;
+       Fuse360Text *distancex_text;
+       Fuse360Slider *distancey_slider;
+       Fuse360Text *distancey_text;
+       Fuse360Slider *translatex_slider;
+       Fuse360Text *translatex_text;
+       Fuse360Slider *feather_slider;
+       Fuse360Text *feather_text;
+       Fuse360Slider *rotation_slider;
+       Fuse360Text *rotation_text;
+       
+       Fuse360Mode *mode;
+       Fuse360Toggle *draw_guides;
+};
+
+class Fuse360Config
+{
+public:
+       Fuse360Config();
+       int equivalent(Fuse360Config &that);
+       void copy_from(Fuse360Config &that);
+       void interpolate(Fuse360Config &prev, 
+               Fuse360Config &next, 
+               int64_t prev_frame, 
+               int64_t next_frame, 
+               int64_t current_frame);
+       void boundaries();
+
+
+
+       float fov;
+// radius of each eye
+       float radius_x;
+       float radius_y;
+// amount to feather eye edges
+       float feather;
+// center of 2 eyes
+       float center_x;
+       float center_y;
+// X distance between 2 eyes
+       float distance_x;
+// Y offset between 2 eyes
+       float distance_y;
+// translate output position
+       float translate_x;
+       float rotation;
+       int draw_guides;
+       int mode;
+       enum
+       {
+// align guides only
+               DO_NOTHING,
+// rectilinear
+               STRETCHXY,
+// the standard blend
+               STANDARD,
+// don't stretch eyes
+               BLEND
+       };
+};
+
+
+
+
+
+class Fuse360Package : public LoadPackage
+{
+public:
+       Fuse360Package();
+       int row1, row2;
+};
+
+
+class Fuse360Unit : public LoadClient
+{
+public:
+       Fuse360Unit(Fuse360Engine *engine, Fuse360Main *plugin);
+       ~Fuse360Unit();
+       
+       
+       void process_package(LoadPackage *package);
+       void process_stretch(Fuse360Package *pkg);
+       void process_blend(Fuse360Package *pkg);
+       void process_standard(Fuse360Package *pkg);
+       double calculate_max_z(double a, double r);
+
+       
+       Fuse360Engine *engine;
+       Fuse360Main *plugin;
+};
+
+class Fuse360Engine : public LoadServer
+{
+public:
+       Fuse360Engine(Fuse360Main *plugin);
+       ~Fuse360Engine();
+       
+       void init_packages();
+       LoadClient* new_client();
+       LoadPackage* new_package();
+       
+       Fuse360Main *plugin;
+};
+
+class Fuse360Main : public PluginVClient
+{
+public:
+       Fuse360Main(PluginServer *server);
+       ~Fuse360Main();
+
+       PLUGIN_CLASS_MEMBERS2(Fuse360Config)
+       int process_buffer(VFrame *frame,
+               int64_t start_position,
+               double frame_rate);
+       int is_realtime();
+       void update_gui();
+       void save_data(KeyFrame *keyframe);
+       void read_data(KeyFrame *keyframe);
+       void calculate_extents();
+       double calculate_max_z(double a, int r);
+
+       int w;
+       int h;
+       int center_x;
+       int center_y;
+       int center_x1;
+       int center_y1;
+       int center_x2;
+       int center_y2;
+       int radius_x;
+       int radius_y;
+       int distance_x;
+       int distance_y;
+       int feather;
+       int feather_x1;
+       int feather_x2;
+
+       Fuse360Engine *engine;
+       AffineEngine *affine;
+};
+
+
+
+#endif
index 0b8673932581725bd553ab344b5890b9cfb2e168..8284b6fa03706a24e8b77bd4012f3324fb502d4f 100644 (file)
@@ -25,7 +25,7 @@
 #include "filexml.h"
 #include "guicast.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "swapframes.h"
 #include "vframe.h"
index 412a28ef3af0b6617efa190050f7781db36c629d..e7c69ff0a9a3d5cbda95450eb1f19f43707aeeb7 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include "histogramengine.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.h"
 
 #include <stdio.h>
index e2591c61f3f5141b0112a4441ff7e3d58b180855..41603cb8f4fd5e2efe898e1b630331e6b959d6eb 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "histogramengine.inc"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "vframe.inc"
 
 #include <stdint.h>
index 8ad43bafded917fa8980a589d9a2a4bd1ac0fadc..052ba25257c28a53b7e65214653acdb32db4729a 100644 (file)
@@ -27,7 +27,7 @@
 #include "filexml.h"
 #include "histogramengine.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "threshold.h"
 #include "thresholdwindow.h"
 #include "vframe.h"
index 6083737c8af70e156f54238a8523f9363ff4bbcc..0d8769f24a19cdf7de20cdb49d888503874f6c76 100644 (file)
@@ -26,7 +26,7 @@
 #include "histogramengine.inc"
 #include "loadbalance.h"
 #include "thresholdwindow.inc"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 
 
index 1929a1400ad36056d876697898968f3028888390..fa055c3fb24d0a19daf7d05e45fb0c1411bf7421 100644 (file)
@@ -24,7 +24,7 @@
 #include "filexml.h"
 #include "keyframe.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "timeavg.h"
 #include "timeavgwindow.h"
 #include "transportque.h"
index 2fb38d199ef3503f48ffa23adf73d6b5b22e8f86..9eeb4ee2be43c097a6d45c0e75c32f47cb369634 100644 (file)
@@ -34,7 +34,7 @@ class TimeFrontServer;
 #include "guicast.h"
 #include "loadbalance.h"
 #include "overlayframe.inc"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "thread.h"
 #include "vframe.inc"
index 5023212e154f121ece897dd3d95c64a99597221b..89b7efa4bc3a47a4b475a8327235d26faa91f080 100644 (file)
@@ -42,19 +42,26 @@ REGISTER_PLUGIN(TimeStretchRT);
 
 TimeStretchRTConfig::TimeStretchRTConfig()
 {
-       scale = 1;
+//     scale = 1;
+       num = 1;
+       denom = 1;
        size = 40;
 }
 
 
 int TimeStretchRTConfig::equivalent(TimeStretchRTConfig &src)
 {
-       return fabs(scale - src.scale) < 0.0001 && size == src.size;
+//     return fabs(scale - src.scale) < 0.0001 && size == src.size;
+       return fabs(num - src.num) < 0.0001 &&
+               fabs(denom - src.denom) < 0.0001 && 
+               size == src.size;
 }
 
 void TimeStretchRTConfig::copy_from(TimeStretchRTConfig &src)
 {
-       this->scale = src.scale;
+       this->num = src.num;
+       this->denom = src.denom;
+//     this->scale = src.scale;
        this->size = src.size;
 }
 
@@ -64,15 +71,19 @@ void TimeStretchRTConfig::interpolate(TimeStretchRTConfig &prev,
        int64_t next_frame,
        int64_t current_frame)
 {
-       this->scale = prev.scale;
+       this->num = prev.num;
+       this->denom = prev.denom;
+//     this->scale = prev.scale;
        this->size = prev.size;
        boundaries();
 }
 
 void TimeStretchRTConfig::boundaries()
 {
-       if(fabs(scale) < 0.01) scale = 0.01;
-       if(fabs(scale) > 100) scale = 100;
+       if(num < 0.0001) num = 0.0001;
+       if(denom < 0.0001) denom = 0.0001;
+//     if(fabs(scale) < 0.01) scale = 0.01;
+//     if(fabs(scale) > 100) scale = 100;
        if(size < 10) size = 10;
        if(size > 1000) size = 1000;
 }
@@ -82,10 +93,10 @@ void TimeStretchRTConfig::boundaries()
 
 TimeStretchRTWindow::TimeStretchRTWindow(TimeStretchRT *plugin)
  : PluginClientWindow(plugin,
+       210, 
+       200, 
+       200, 
        210,
-       160,
-       200,
-       160,
        0)
 {
        this->plugin = plugin;
@@ -98,19 +109,31 @@ TimeStretchRTWindow::~TimeStretchRTWindow()
 void TimeStretchRTWindow::create_objects()
 {
        int x = 10, y = 10;
+       int margin = plugin->get_theme()->widget_border;
 
        BC_Title *title = 0;
-       add_subwindow(title = new BC_Title(x, y, _("Fraction of original speed:")));
+       add_subwindow(title = new BC_Title(x, y, _("Input samples:")));
        y += title->get_h() + plugin->get_theme()->widget_border;
-       scale = new TimeStretchRTScale(this,
-               plugin,
-               x,
-               y);
-       scale->create_objects();
-
-       y += scale->get_h() + plugin->get_theme()->widget_border;
-       add_subwindow(title = new BC_Title(x, y, _("Window size (ms):")));
+       num = new TimeStretchRTScale(this,
+               plugin, 
+               x, 
+               y,
+               &plugin->config.num);
+       num->create_objects();
+       y += num->get_h() + margin;
+
+       add_subwindow(title = new BC_Title(x, y, _("Output samples:")));
        y += title->get_h() + plugin->get_theme()->widget_border;
+       denom = new TimeStretchRTScale(this,
+               plugin, 
+               x, 
+               y,
+               &plugin->config.denom);
+       denom->create_objects();
+
+       y += denom->get_h() + margin;
+       add_subwindow(title = new BC_Title(x, y, _("Window size (ms):")));
+       y += title->get_h() + margin;
        size = new TimeStretchRTSize(this,
                plugin,
                x,
@@ -128,9 +151,10 @@ void TimeStretchRTWindow::create_objects()
 TimeStretchRTScale::TimeStretchRTScale(TimeStretchRTWindow *window,
        TimeStretchRT *plugin,
        int x,
-       int y)
+       int y,
+       double *value)
  : BC_TumbleTextBox(window,
-       (float)(1.0 / plugin->config.scale),
+       (float)*value,
        (float)0.0001,
        (float)1000,
        x,
@@ -138,12 +162,14 @@ TimeStretchRTScale::TimeStretchRTScale(TimeStretchRTWindow *window,
        100)
 {
        this->plugin = plugin;
+       this->value = value;
        set_increment(0.01);
 }
 
 int TimeStretchRTScale::handle_event()
 {
-       plugin->config.scale = 1.0 / atof(get_text());
+       *value = atof(get_text());
+       plugin->config.boundaries();
        plugin->send_configure_change();
        return 1;
 }
@@ -213,7 +239,7 @@ int TimeStretchRT::process_buffer(int64_t size,
 {
        need_reconfigure = load_configuration();
 
-       if(!engine) engine = new TimeStretchEngine(config.scale,
+       if(!engine) engine = new TimeStretchEngine(config.denom / config.num, 
                sample_rate,
                config.size);
 
@@ -222,7 +248,6 @@ int TimeStretchRT::process_buffer(int64_t size,
 
 // Get start position of the input.
 // Sample 0 is the keyframe position
-//printf("TimeStretchRT::process_buffer %d %f\n", __LINE__, config.scale);
        if(need_reconfigure)
        {
                int64_t prev_position = edl_to_local(
@@ -234,15 +259,18 @@ int TimeStretchRT::process_buffer(int64_t size,
                        prev_position = get_source_start();
                }
 
-               source_start = (int64_t)((start_position - prev_position) /
-                       config.scale) + prev_position;
+               source_start = (int64_t)((start_position - prev_position) 
+                       config.num / config.denom) + prev_position;
 
                engine->reset();
-               engine->update(config.scale, sample_rate, config.size);
+               engine->update(config.denom / config.num, sample_rate, config.size);
                need_reconfigure = 0;
-//printf("TimeStretchRT::process_buffer %d start_position=" _LD
-//      " prev_position=%jd scale=%f source_start=%jd\n",
-//     __LINE__, start_position, prev_position, config.scale, source_start);
+// printf("TimeStretchRT::process_buffer %d start_position=%lld prev_position=%lld scale=%f source_start=%lld\n", 
+// __LINE__, 
+// start_position,
+// prev_position,
+// config.scale,
+// source_start);
        }
 
 // process buffers until output length is reached
@@ -297,7 +325,8 @@ void TimeStretchRT::save_data(KeyFrame *keyframe)
 // cause data to be stored directly in text
        output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
        output.tag.set_title("TIMESTRETCHRT");
-       output.tag.set_property("SCALE", config.scale);
+       output.tag.set_property("NUM", config.num);
+       output.tag.set_property("DENOM", config.denom);
        output.tag.set_property("SIZE", config.size);
        output.append_tag();
        output.tag.set_title("/TIMESTRETCHRT");
@@ -316,7 +345,8 @@ void TimeStretchRT::read_data(KeyFrame *keyframe)
        {
                if(input.tag.title_is("TIMESTRETCHRT"))
                {
-                       config.scale = input.tag.get_property("SCALE", config.scale);
+                       config.num = input.tag.get_property("NUM", config.num);
+                       config.denom = input.tag.get_property("DENOM", config.denom);
                        config.size = input.tag.get_property("SIZE", config.size);
                }
        }
@@ -330,7 +360,8 @@ void TimeStretchRT::update_gui()
                {
 
                        thread->window->lock_window("TimeStretchRT::update_gui");
-                       ((TimeStretchRTWindow*)thread->window)->scale->update((float)(1.0 / config.scale));
+                       ((TimeStretchRTWindow*)thread->window)->num->update((float)config.num);
+                       ((TimeStretchRTWindow*)thread->window)->denom->update((float)config.denom);
                        ((TimeStretchRTWindow*)thread->window)->size->update((int64_t)config.size);
                        thread->window->unlock_window();
                }
index 652e4a11fe4587cee9123ef8d6b3c246d3782dcc..6e0be35cdc0f1b356c3b5ec4908836899c5da2a6 100644 (file)
@@ -45,7 +45,9 @@ public:
                int64_t prev_frame,
                int64_t next_frame,
                int64_t current_frame);
-       double scale;
+//     double scale;
+       double num;
+       double denom;
        int size;
 };
 
@@ -56,9 +58,11 @@ public:
        TimeStretchRTScale(TimeStretchRTWindow *window,
                TimeStretchRT *plugin,
                int x,
-               int y);
+               int y,
+               double *value);
        int handle_event();
        TimeStretchRT *plugin;
+       double *value;
 };
 
 
@@ -80,7 +84,8 @@ public:
        void create_objects();
 
        TimeStretchRT *plugin;
-       TimeStretchRTScale *scale;
+       TimeStretchRTScale *num;
+       TimeStretchRTScale *denom;
        TimeStretchRTSize *size;
 };
 
index a420acf269c10096f7da000a5a5205717ec43b05..0fbae88f197d966e315a4f40d7c76294b162f87e 100644 (file)
@@ -26,7 +26,7 @@
 #include "guicast.h"
 #include "language.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "fonts.h"
 #include "scopewindow.h"
index 28d9fc2a33c507f5349a3b60c5f6b5a752f0c7c8..18846756d8bc22495a672c7d104ba9a2f87d1bac 100644 (file)
@@ -25,7 +25,7 @@
 #include "filexml.h"
 #include "guicast.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
index 6f877c48fe593614daa20ab4809871f1433c003d..b1e07d36ba7bc3a082d4578cb14e678fe85970d4 100644 (file)
@@ -28,7 +28,7 @@ class YUVMain;
 class YUVEngine;
 
 #include "bcbase.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "yuvwindow.h"
 #include "pluginvclient.h"
 
index 393fc11b1ebc34f1beacab7f80b507762ac713eb..a08eeffe61544f042795d82e4e9a5acbc878ef89 100644 (file)
@@ -6,7 +6,7 @@
 #include "mutex.h"
 #include "pluginvclient.h"
 #include "bctitle.h"
-#include "colors.h"
+#include "bccolors.h"
 #include "fonts.h"
 
 class yuv411Toggle;
index 2b814c03fb76e3e216a2b6c7107ee738bd2f255a..e16364a2f9ce73cbf96c33332ae5cde54ec9ff2f 100644 (file)
@@ -25,7 +25,7 @@
 #include "filexml.h"
 #include "guicast.h"
 #include "language.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "pluginvclient.h"
 #include "vframe.h"
 
diff --git a/cinelerra-5.1/thirdparty/src/libXft-2.3.2.patch1 b/cinelerra-5.1/thirdparty/src/libXft-2.3.2.patch1
new file mode 100644 (file)
index 0000000..79cf727
--- /dev/null
@@ -0,0 +1,61 @@
+diff -ur libXft-2.3.2.orig/src/xftdpy.c libXft-2.3.2/src/xftdpy.c
+--- libXft-2.3.2.orig/src/xftdpy.c     2014-06-06 00:05:07.000000000 -0600
++++ libXft-2.3.2/src/xftdpy.c  2017-10-17 08:55:30.227746279 -0600
+@@ -22,6 +22,11 @@
+ #include "xftint.h"
++#include <pthread.h>
++static pthread_mutex_t info_mutex = PTHREAD_MUTEX_INITIALIZER;
++static inline void info_lock() { pthread_mutex_lock(&info_mutex); }
++static inline void info_unlock() { pthread_mutex_unlock(&info_mutex); }
++
+ _X_HIDDEN XftDisplayInfo      *_XftDisplayInfo;
+ static int
+@@ -48,10 +53,12 @@
+     /*
+      * Unhook from the global list
+      */
++    info_lock();
+     for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
+       if (info->display == dpy)
+           break;
+     *prev = info->next;
++    info_unlock();
+     free (info);
+     return 0;
+@@ -66,6 +73,7 @@
+     int                       i;
+     int                       event_base, error_base;
++    info_lock();
+     for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
+     {
+       if (info->display == dpy)
+@@ -79,9 +87,12 @@
+               info->next = _XftDisplayInfo;
+               _XftDisplayInfo = info;
+           }
++          info_unlock();
+           return info;
+       }
+     }
++    info_unlock();
++
+     if (!createIfNecessary)
+       return NULL;
+@@ -157,8 +168,10 @@
+     }
+     info->fonts = NULL;
++    info_lock();
+     info->next = _XftDisplayInfo;
+     _XftDisplayInfo = info;
++    info_unlock();
+     info->glyph_memory = 0;
+     info->max_glyph_memory = XftDefaultGetInteger (dpy,
+Only in libXft-2.3.2: tags