From 80f0c6dac40cfba9994e5e7e436d50a7aa1f8b6c Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Mon, 16 Aug 2004 19:31:36 +0000 Subject: [PATCH] r370: Heroine Virutal's official release 1.2.1 --- hvirtual/cinelerra/TODO | 82 +- hvirtual/cinelerra/aboutprefs.C | 7 +- hvirtual/cinelerra/adeviceprefs.C | 8 +- hvirtual/cinelerra/amodule.C | 6 +- hvirtual/cinelerra/apatchgui.C | 17 +- hvirtual/cinelerra/arender.C | 19 +- hvirtual/cinelerra/arender.h | 7 +- hvirtual/cinelerra/assetedit.C | 4 +- hvirtual/cinelerra/assetremove.C | 4 +- hvirtual/cinelerra/attachmentpoint.C | 19 +- hvirtual/cinelerra/attachmentpoint.h | 24 +- hvirtual/cinelerra/audio1394.C | 4 +- hvirtual/cinelerra/audioalsa.C | 128 +- hvirtual/cinelerra/audioalsa.h | 7 + hvirtual/cinelerra/audiodevice.C | 20 +- hvirtual/cinelerra/audiodevice.h | 16 +- hvirtual/cinelerra/audioodevice.C | 14 +- hvirtual/cinelerra/autoconf.C | 102 ++ hvirtual/cinelerra/autoconf.h | 36 + hvirtual/cinelerra/autos.C | 31 +- hvirtual/cinelerra/autos.h | 2 + hvirtual/cinelerra/batch.C | 19 +- hvirtual/cinelerra/browsebutton.C | 14 +- hvirtual/cinelerra/builddate.h | 2 +- hvirtual/cinelerra/channeledit.C | 12 +- hvirtual/cinelerra/channelpicker.C | 1 + hvirtual/cinelerra/clipedit.C | 4 +- hvirtual/cinelerra/commonrender.C | 3 +- hvirtual/cinelerra/commonrender.h | 2 +- hvirtual/cinelerra/confirmquit.C | 4 +- hvirtual/cinelerra/confirmsave.C | 4 +- hvirtual/cinelerra/cplayback.C | 5 +- hvirtual/cinelerra/cplayback.h | 20 + hvirtual/cinelerra/ctracking.C | 10 - hvirtual/cinelerra/cwindowtool.C | 18 +- hvirtual/cinelerra/deleteallindexes.C | 4 +- hvirtual/cinelerra/drivesync.C | 2 - hvirtual/cinelerra/edits.C | 7 + hvirtual/cinelerra/edl.C | 21 +- hvirtual/cinelerra/edl.h | 12 +- hvirtual/cinelerra/edlsession.C | 94 +- hvirtual/cinelerra/edlsession.h | 14 +- hvirtual/cinelerra/fadeengine.C | 35 +- hvirtual/cinelerra/file.C | 55 +- hvirtual/cinelerra/file.inc | 6 + hvirtual/cinelerra/fileavi.C | 8 +- hvirtual/cinelerra/fileformat.C | 4 +- hvirtual/cinelerra/filejpeg.C | 8 +- hvirtual/cinelerra/filelist.C | 38 +- hvirtual/cinelerra/filelist.h | 6 +- hvirtual/cinelerra/filemov.C | 36 +- hvirtual/cinelerra/filempeg.C | 8 +- hvirtual/cinelerra/filepng.C | 40 +- hvirtual/cinelerra/filesndfile.C | 4 +- hvirtual/cinelerra/filetga.C | 6 +- hvirtual/cinelerra/filethread.C | 5 +- hvirtual/cinelerra/filetiff.C | 313 ++-- hvirtual/cinelerra/filetiff.h | 56 +- hvirtual/cinelerra/filevorbis.C | 9 +- hvirtual/cinelerra/formatpopup.C | 1 + hvirtual/cinelerra/indexfile.C | 31 +- hvirtual/cinelerra/indexthread.C | 6 +- hvirtual/cinelerra/interfaceprefs.C | 47 +- hvirtual/cinelerra/interfaceprefs.h | 13 +- hvirtual/cinelerra/loadbalance.C | 35 +- hvirtual/cinelerra/loadbalance.h | 10 +- hvirtual/cinelerra/loadfile.C | 14 +- hvirtual/cinelerra/localsession.C | 8 +- hvirtual/cinelerra/localsession.h | 2 +- hvirtual/cinelerra/main.C | 4 +- hvirtual/cinelerra/maincursor.C | 4 +- hvirtual/cinelerra/mainindexes.C | 5 - hvirtual/cinelerra/mainprogress.C | 4 +- hvirtual/cinelerra/mainsession.C | 3 + hvirtual/cinelerra/mainsession.h | 1 + hvirtual/cinelerra/maskengine.C | 204 ++- hvirtual/cinelerra/maskengine.h | 3 +- hvirtual/cinelerra/menueffects.C | 8 +- hvirtual/cinelerra/meterpanel.C | 21 +- hvirtual/cinelerra/meterpanel.h | 80 + hvirtual/cinelerra/module.C | 6 +- hvirtual/cinelerra/mwindow.C | 78 +- hvirtual/cinelerra/mwindow.h | 5 +- hvirtual/cinelerra/mwindow.inc | 2 +- hvirtual/cinelerra/mwindowgui.C | 22 +- hvirtual/cinelerra/new.C | 308 +--- hvirtual/cinelerra/new.h | 51 +- hvirtual/cinelerra/newfolder.C | 15 +- hvirtual/cinelerra/overlayframe.C | 909 +++++----- hvirtual/cinelerra/overlayframe.h | 1 + hvirtual/cinelerra/packagedispatcher.C | 4 +- hvirtual/cinelerra/packagerenderer.C | 42 +- hvirtual/cinelerra/patchbay.C | 10 +- hvirtual/cinelerra/patchbay.h | 2 +- hvirtual/cinelerra/playbackconfig.C | 254 ++- hvirtual/cinelerra/playbackconfig.h | 15 +- hvirtual/cinelerra/playbackengine.C | 276 +-- hvirtual/cinelerra/playbackengine.h | 92 +- hvirtual/cinelerra/playbackprefs.C | 405 ++--- hvirtual/cinelerra/playbackprefs.h | 92 +- hvirtual/cinelerra/pluginaclient.h | 8 - hvirtual/cinelerra/pluginclient.h | 12 +- hvirtual/cinelerra/plugindialog.C | 185 +- hvirtual/cinelerra/plugindialog.h | 56 +- hvirtual/cinelerra/pluginpopup.C | 16 +- hvirtual/cinelerra/pluginpopup.h | 154 ++ hvirtual/cinelerra/pluginserver.C | 19 +- hvirtual/cinelerra/pluginserver.h | 3 +- hvirtual/cinelerra/pluginvclient.h | 2 +- hvirtual/cinelerra/preferences.C | 12 +- hvirtual/cinelerra/preferencesthread.C | 74 +- hvirtual/cinelerra/preferencesthread.h | 114 ++ hvirtual/cinelerra/question.C | 10 +- hvirtual/cinelerra/quit.C | 8 +- hvirtual/cinelerra/recconfirmdelete.C | 4 +- hvirtual/cinelerra/record.C | 71 +- hvirtual/cinelerra/record.h | 5 +- hvirtual/cinelerra/recordaudio.C | 17 +- hvirtual/cinelerra/recordaudio.h | 3 +- hvirtual/cinelerra/recordconfig.C | 68 +- hvirtual/cinelerra/recordconfig.h | 2 + hvirtual/cinelerra/recordgui.C | 3 +- hvirtual/cinelerra/recordmonitor.C | 5 +- hvirtual/cinelerra/recordprefs.C | 5 +- hvirtual/cinelerra/recordthread.C | 5 +- hvirtual/cinelerra/recordvideo.C | 27 +- hvirtual/cinelerra/recordwindow.C | 18 +- hvirtual/cinelerra/recordwindow.h | 5 +- hvirtual/cinelerra/render.C | 69 +- hvirtual/cinelerra/renderengine.C | 56 +- hvirtual/cinelerra/renderengine.h | 4 +- hvirtual/cinelerra/renderfarm.C | 4 +- hvirtual/cinelerra/renderfarmclient.C | 14 +- hvirtual/cinelerra/renderfarmclient.h | 2 +- hvirtual/cinelerra/resizetrackthread.C | 10 +- hvirtual/cinelerra/resourcepixmap.C | 6 +- hvirtual/cinelerra/savefile.C | 12 +- hvirtual/cinelerra/setformat.C | 183 +- hvirtual/cinelerra/setformat.h | 208 +++ hvirtual/cinelerra/theme.C | 6 +- hvirtual/cinelerra/theme.h | 4 +- hvirtual/cinelerra/threadindexer.C | 4 +- hvirtual/cinelerra/timebar.C | 6 - hvirtual/cinelerra/track.C | 12 +- hvirtual/cinelerra/trackcanvas.C | 236 ++- hvirtual/cinelerra/trackcanvas.h | 3 + hvirtual/cinelerra/tracking.C | 2 +- hvirtual/cinelerra/tracking.inc | 9 + hvirtual/cinelerra/transitionpopup.C | 4 +- hvirtual/cinelerra/transportque.C | 19 +- hvirtual/cinelerra/transportque.h | 2 + hvirtual/cinelerra/vattachmentpoint.C | 14 +- hvirtual/cinelerra/vattachmentpoint.h | 3 +- hvirtual/cinelerra/vdevice1394.C | 4 +- hvirtual/cinelerra/vdeviceprefs.C | 4 +- hvirtual/cinelerra/vdevicev4l.C | 14 +- hvirtual/cinelerra/videodevice.C | 5 +- hvirtual/cinelerra/virtualaconsole.C | 18 +- hvirtual/cinelerra/virtualanode.C | 39 +- hvirtual/cinelerra/virtualconsole.C | 3 +- hvirtual/cinelerra/virtualconsole.h | 3 +- hvirtual/cinelerra/virtualnode.C | 3 +- hvirtual/cinelerra/virtualnode.h | 2 +- hvirtual/cinelerra/virtualvconsole.C | 32 +- hvirtual/cinelerra/virtualvnode.C | 34 +- hvirtual/cinelerra/vmodule.C | 14 +- hvirtual/cinelerra/vmodule.h | 3 +- hvirtual/cinelerra/vplayback.C | 33 + hvirtual/cinelerra/vplayback.h | 20 + hvirtual/cinelerra/vrender.C | 20 +- hvirtual/guicast/bcbitmap.C | 8 +- hvirtual/guicast/bcbutton.C | 7 +- hvirtual/guicast/bccounter.C | 29 + hvirtual/guicast/bcdisplayinfo.C | 5 + hvirtual/guicast/bcdragwindow.C | 12 +- hvirtual/guicast/bcfilebox.C | 46 +- hvirtual/guicast/bcfilebox.h | 6 +- hvirtual/guicast/bclistbox.C | 23 +- hvirtual/guicast/bcmenubar.C | 1 + hvirtual/guicast/bcmeter.C | 222 +-- hvirtual/guicast/bcmeter.h | 87 + hvirtual/guicast/bcmeter.inc | 8 + hvirtual/guicast/bcpixmap.C | 3 + hvirtual/guicast/bcpopup.C | 84 + hvirtual/guicast/bcpopupmenu.C | 14 +- hvirtual/guicast/bcpot.C | 2 +- hvirtual/guicast/bcprogressbox.C | 94 + hvirtual/guicast/bcrepeater.C | 1 + hvirtual/guicast/bcresources.C | 13 +- hvirtual/guicast/bcresources.h | 11 +- hvirtual/guicast/bcscrollbar.C | 29 +- hvirtual/guicast/bcscrollbar.h | 1 - hvirtual/guicast/bcsignals.C | 123 +- hvirtual/guicast/bcsignals.h | 35 +- hvirtual/guicast/bcsubwindow.C | 52 + hvirtual/guicast/bctextbox.C | 10 +- hvirtual/guicast/bctextbox.h | 1 + hvirtual/guicast/bctheme.C | 191 +- hvirtual/guicast/bctheme.h | 18 +- hvirtual/guicast/bctitle.C | 6 +- hvirtual/guicast/bctitle.h | 2 +- hvirtual/guicast/bctoggle.C | 82 +- hvirtual/guicast/bctoggle.h | 13 +- hvirtual/guicast/bctumble.C | 2 +- hvirtual/guicast/bcwindowbase.C | 510 +++--- hvirtual/guicast/bcwindowbase.h | 69 +- hvirtual/guicast/filesystem.h | 2 +- hvirtual/guicast/images/xmeter.xcf.bz2 | Bin 0 -> 3756 bytes hvirtual/guicast/images/xmeter_green.png | Bin 0 -> 208 bytes hvirtual/guicast/images/xmeter_green_png.h | 22 + hvirtual/guicast/images/xmeter_normal.png | Bin 0 -> 211 bytes hvirtual/guicast/images/xmeter_normal_png.h | 23 + hvirtual/guicast/images/xmeter_red.png | Bin 0 -> 208 bytes hvirtual/guicast/images/xmeter_red_png.h | 22 + hvirtual/guicast/images/xmeter_yellow.png | Bin 0 -> 210 bytes hvirtual/guicast/images/xmeter_yellow_png.h | 23 + hvirtual/guicast/images/ymeter_green.png | Bin 0 -> 207 bytes hvirtual/guicast/images/ymeter_green_png.h | 22 + hvirtual/guicast/images/ymeter_normal.png | Bin 0 -> 210 bytes hvirtual/guicast/images/ymeter_normal_png.h | 23 + hvirtual/guicast/images/ymeter_red.png | Bin 0 -> 207 bytes hvirtual/guicast/images/ymeter_red_png.h | 22 + hvirtual/guicast/images/ymeter_yellow.png | Bin 0 -> 208 bytes hvirtual/guicast/images/ymeter_yellow_png.h | 22 + hvirtual/guicast/mutex.C | 2 + hvirtual/guicast/rotateframe.C | 50 +- hvirtual/guicast/rotateframe.h | 83 + hvirtual/guicast/sema.C | 8 + hvirtual/guicast/sema.h | 2 + hvirtual/guicast/test.C | 6 +- hvirtual/guicast/thread.C | 9 + hvirtual/guicast/thread.h | 2 + hvirtual/guicast/vframe.C | 134 +- hvirtual/guicast/vframe.h | 4 - hvirtual/libmpeg3/libmpeg3.c | 2 +- hvirtual/libmpeg3/mpeg3css.c | 1011 ++++++++++- hvirtual/libmpeg3/mpeg3demux.c | 10 +- hvirtual/libmpeg3/mpeg3title.c | 7 +- hvirtual/plugins/aging/aging.C | 137 +- hvirtual/plugins/aging/agingwindow.C | 7 +- hvirtual/plugins/bandslide/bandslide.C | 10 +- hvirtual/plugins/bandwipe/bandwipe.C | 12 +- hvirtual/plugins/blur/blur.C | 11 +- hvirtual/plugins/blur/blur.h | 2 +- hvirtual/plugins/brightness/brightness.C | 124 +- hvirtual/plugins/burn/burn.C | 150 +- hvirtual/plugins/burn/burn.h | 112 ++ hvirtual/plugins/burn/burnwindow.C | 7 +- hvirtual/plugins/cdripper/cdripper.C | 8 +- hvirtual/plugins/chromakey/chromakey.C | 54 +- hvirtual/plugins/colorbalance/colorbalance.C | 80 +- hvirtual/plugins/colorbalance/colorbalance.h | 5 + hvirtual/plugins/compressor/compressor.C | 641 ++++--- hvirtual/plugins/compressor/compressor.h | 76 +- hvirtual/plugins/defaulttheme/defaulttheme.C | 28 +- hvirtual/plugins/deinterlace/deinterlace.C | 85 +- hvirtual/plugins/delayvideo/delayvideo.C | 75 +- hvirtual/plugins/delayvideo/delayvideo.h | 18 +- hvirtual/plugins/denoisefft/denoisefft.C | 6 +- hvirtual/plugins/denoisevideo/denoisevideo.C | 14 +- hvirtual/plugins/dot/dot.C | 84 +- hvirtual/plugins/dot/dotwindow.C | 14 +- hvirtual/plugins/fieldframe/fieldframe.C | 167 +- hvirtual/plugins/flash/flash.C | 38 +- hvirtual/plugins/flip/flip.C | 42 +- hvirtual/plugins/framefield/framefield.C | 20 +- hvirtual/plugins/gradient/gradient.C | 177 +- hvirtual/plugins/histogram/histogram.C | 634 ++++--- hvirtual/plugins/holo/holo.C | 189 +- hvirtual/plugins/holo/holo.h | 110 ++ hvirtual/plugins/holo/holowindow.C | 13 +- hvirtual/plugins/holo/holowindow.h | 3 +- hvirtual/plugins/huesaturation/huesaturation.C | 68 +- hvirtual/plugins/invertvideo/invert.C | 18 +- hvirtual/plugins/invertvideo/invertwindow.C | 34 +- hvirtual/plugins/irissquare/irissquare.C | 12 +- hvirtual/plugins/ivtc/ivtc.C | 266 +-- hvirtual/plugins/linearblur/linearblur.C | 72 +- hvirtual/plugins/oilpainting/oil.C | 142 +- hvirtual/plugins/perspective/perspective.C | 78 +- hvirtual/plugins/pitch/pitch.C | 4 +- hvirtual/plugins/polar/polar.C | 17 +- hvirtual/plugins/radialblur/radialblur.C | 58 +- hvirtual/plugins/reframe/reframe.C | 14 +- hvirtual/plugins/rgb601/rgb601.C | 49 +- hvirtual/plugins/rgb601/rgb601window.C | 13 +- hvirtual/plugins/rotate/rotate.C | 7 +- hvirtual/plugins/sharpen/sharpen.C | 219 ++- hvirtual/plugins/sharpen/sharpen.h | 160 ++ hvirtual/plugins/shiftinterlace/shiftinterlace.C | 6 + hvirtual/plugins/slide/slide.C | 6 + hvirtual/plugins/swapchannels/swapchannels.C | 21 +- hvirtual/plugins/timeavg/timeavg.C | 481 ++++- hvirtual/plugins/timeavg/timeavg.h | 69 + hvirtual/plugins/timeavg/timeavgwindow.C | 89 +- hvirtual/plugins/timeavg/timeavgwindow.h | 71 + hvirtual/plugins/titler/title.C | 18 + hvirtual/plugins/videoscope/videoscope.C | 169 +- hvirtual/plugins/wave/wave.C | 11 +- hvirtual/plugins/whirl/whirl.C | 12 +- hvirtual/plugins/wipe/wipe.C | 6 + hvirtual/plugins/yuv/yuv.C | 84 +- hvirtual/plugins/zoomblur/zoomblur.C | 58 +- hvirtual/quicktime/cmodel_default.c | 1958 ++++++++++++++++++++ hvirtual/quicktime/cmodel_permutation.h | 2063 +++++----------------- hvirtual/quicktime/cmodel_yuv420p.c | 601 ++++++- hvirtual/quicktime/cmodel_yuv422.c | 550 ++++++ hvirtual/quicktime/colormodels.c | 149 +- hvirtual/quicktime/colormodels.h | 20 +- hvirtual/quicktime/funcprotos.h | 10 + hvirtual/quicktime/libmjpeg.c | 27 +- hvirtual/quicktime/libmjpeg.h | 3 + hvirtual/quicktime/plugin.c | 2 +- hvirtual/quicktime/qtprivate.h | 4 +- hvirtual/quicktime/quicktime.c | 4 + hvirtual/quicktime/quicktime.h | 1 + hvirtual/quicktime/stsd.c | 3 +- hvirtual/quicktime/stsdtable.c | 21 + hvirtual/quicktime/util.c | 105 +- hvirtual/quicktime/vorbis.c | 5 + hvirtual/quicktime/workarounds.c | 5 + hvirtual/quicktime/workarounds.h | 1 + 322 files changed, 13810 insertions(+), 7151 deletions(-) create mode 100644 hvirtual/cinelerra/autoconf.C create mode 100644 hvirtual/cinelerra/autoconf.h create mode 100644 hvirtual/cinelerra/cplayback.h create mode 100644 hvirtual/cinelerra/meterpanel.h create mode 100644 hvirtual/cinelerra/pluginpopup.h create mode 100644 hvirtual/cinelerra/preferencesthread.h create mode 100644 hvirtual/cinelerra/setformat.h create mode 100644 hvirtual/cinelerra/tracking.inc create mode 100644 hvirtual/cinelerra/vplayback.C create mode 100644 hvirtual/cinelerra/vplayback.h create mode 100644 hvirtual/guicast/bccounter.C create mode 100644 hvirtual/guicast/bcmeter.h create mode 100644 hvirtual/guicast/bcmeter.inc create mode 100644 hvirtual/guicast/bcpopup.C create mode 100644 hvirtual/guicast/bcprogressbox.C create mode 100644 hvirtual/guicast/bcsubwindow.C create mode 100644 hvirtual/guicast/images/xmeter.xcf.bz2 create mode 100644 hvirtual/guicast/images/xmeter_green.png create mode 100644 hvirtual/guicast/images/xmeter_green_png.h create mode 100644 hvirtual/guicast/images/xmeter_normal.png create mode 100644 hvirtual/guicast/images/xmeter_normal_png.h create mode 100644 hvirtual/guicast/images/xmeter_red.png create mode 100644 hvirtual/guicast/images/xmeter_red_png.h create mode 100644 hvirtual/guicast/images/xmeter_yellow.png create mode 100644 hvirtual/guicast/images/xmeter_yellow_png.h create mode 100644 hvirtual/guicast/images/ymeter_green.png create mode 100644 hvirtual/guicast/images/ymeter_green_png.h create mode 100644 hvirtual/guicast/images/ymeter_normal.png create mode 100644 hvirtual/guicast/images/ymeter_normal_png.h create mode 100644 hvirtual/guicast/images/ymeter_red.png create mode 100644 hvirtual/guicast/images/ymeter_red_png.h create mode 100644 hvirtual/guicast/images/ymeter_yellow.png create mode 100644 hvirtual/guicast/images/ymeter_yellow_png.h create mode 100644 hvirtual/guicast/rotateframe.h create mode 100644 hvirtual/plugins/burn/burn.h create mode 100644 hvirtual/plugins/holo/holo.h create mode 100644 hvirtual/plugins/sharpen/sharpen.h create mode 100644 hvirtual/plugins/timeavg/timeavg.h create mode 100644 hvirtual/plugins/timeavg/timeavgwindow.h create mode 100644 hvirtual/quicktime/cmodel_default.c create mode 100644 hvirtual/quicktime/cmodel_yuv422.c diff --git a/hvirtual/cinelerra/TODO b/hvirtual/cinelerra/TODO index 0aecab1b..104a93f7 100644 --- a/hvirtual/cinelerra/TODO +++ b/hvirtual/cinelerra/TODO @@ -11,18 +11,22 @@ An optimization error in GCC 3.3.2 causes RGB16 colormodels to crash. - Recompiling the cmodel files with just -O works. Drag effect before timeline is finished drawing after a load -> lockup Test 0 for loop video. -Keyframes for effects are still displayed if edits are collapsed. Interpolate video shouldn't always use different frames if framerate is fractionally different -Interpolate audio VFS broken on Opteron -Crash when applying interpolateaudio to small segment and repeatedly playing. diffkey debug -Transition lengths not adjusted for frame rate changes. -Undo doesn't restore project title from previous load. +Overlay doesn't handle different sized tracks Quicktime mp4a not decoded properly Quicktime mp3 needs standards check - - +File format for effect is being shared with render again. +Having shared plugin off but sharing instance on creates mono sound. +Importing assets of the same name but different resolutions crashes because the +formats aren't updated. +Attach shared reverb to both tracks. Attach different compressor on each track. + - Get artifacts in track with shared reverb. +Default pan keyframe gets pasted when dragging edit from one track to another. +Undo doesn't restore project title from previous load. + - New file can be saved under old filename if undo is used. + - Current title changes in save function and could not be restored in redo. Small bugs ---------------- @@ -36,12 +40,16 @@ List problems: Big Features ---------------- -Should restore EDL path from backup. -Test pull console with LAD. +Delete files function. +Remove unused resources function. +Document compressor. +Document meter overload (headroom). Soundcards only go to 0 DB. +Flag indicating refresh in progress. +Session management +Hourglass +Float colormodel Signal handling for non interactive rendering. -Compressor using readahead buffer. Sound level using readahead buffer. -hourglass color curves hide cursor when over video output SUV theme @@ -82,58 +90,6 @@ Independant record options for plugin sets. -Patches --------------------- -koen muylkens -newskin-cinelerra.diff - - - -Andraz Tori: -masks_fixes.diff - -Fixes are: -- when adding a point to the mask by just clicking and not dragging, -mask is not rerendered (changes to cwindowgui.C) -- when working with autokeyframes enabled with masks. If you have -keyframe A at position 0 and keyframe B at position 100, when you -would -like to edit mask at position 50 and you add a new point or move -previous one, the whole mask at position 50 snaps back to the position -as specified in keyframe A (all changes except to cwindowgui.C) - -the first fix is pretty obvious, just rerendering was mising in a -codepath - -the second one is more deep-trough, since it adds missing -functionality -to auto.h/C ... when autocreating keyframe, keyframe should be -interpolated from frame before and after it (if they exist). - -masks_fixes.diff - -if there is more than one mask, they all have to be counted -in order to figure y-bounding interval for redraw. - -maskengine4_fix.diff - -plugindialog_fix.diff - already done - -If there are only two video tracks, and one has a shared track effect -from the other. and the other is deleted. cinelerra crushes. - -shared_track_deletion_crush.diff - - - - - - - - - - - Not reproducible ---------------------- Quit freezes when background rendering is on. diff --git a/hvirtual/cinelerra/aboutprefs.C b/hvirtual/cinelerra/aboutprefs.C index 57001d6d..fa12e085 100644 --- a/hvirtual/cinelerra/aboutprefs.C +++ b/hvirtual/cinelerra/aboutprefs.C @@ -38,7 +38,7 @@ int AboutPrefs::create_objects() char license2[BCTEXTLEN]; sprintf(license2, "%s%s%s", - _("(c) 2003 Heroine Virtual Ltd.\n\n"), + _("(c) 2004 Heroine Virtual Ltd.\n\n"), _("Build date: "), BUILDDATE); set_font(MEDIUMFONT); @@ -72,10 +72,13 @@ mpeg3_release()); sprintf(credits, "Richard Baverstock\n" "Kevin Brosius\n" +"Jack Crossfire\n" +"Pierre Marc Dumuid\n" "Alex Ferrer\n" "Eric Seigne\n" +"Gustavo IƱiguez\n" +"Johannes Sixt\n" "Andraz Tori\n" -"\"ga\"\n" ); draw_text(x, y, credits); diff --git a/hvirtual/cinelerra/adeviceprefs.C b/hvirtual/cinelerra/adeviceprefs.C index fe75f9c7..887f837f 100644 --- a/hvirtual/cinelerra/adeviceprefs.C +++ b/hvirtual/cinelerra/adeviceprefs.C @@ -3,17 +3,13 @@ #include "audiodevice.inc" #include "bitspopup.h" #include "edl.h" +#include "language.h" #include "playbackconfig.h" #include "preferences.h" #include "preferencesthread.h" #include "recordconfig.h" #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #define DEVICE_H 25 ADevicePrefs::ADevicePrefs(int x, @@ -349,7 +345,7 @@ int ADevicePrefs::create_alsa_objs() 0, 0, 0, - 0); + 1); alsa_bits->create_objects(); x1 += alsa_bits->get_w() + 5; diff --git a/hvirtual/cinelerra/amodule.C b/hvirtual/cinelerra/amodule.C index b911c95a..4ff345bf 100644 --- a/hvirtual/cinelerra/amodule.C +++ b/hvirtual/cinelerra/amodule.C @@ -65,11 +65,11 @@ void AModule::create_objects() // Not needed in pluginarray if(commonrender) { - level_history = new double[((ARender*)commonrender)->history_size()]; - level_samples = new int64_t[((ARender*)commonrender)->history_size()]; + level_history = new double[((ARender*)commonrender)->total_peaks]; + level_samples = new int64_t[((ARender*)commonrender)->total_peaks]; current_level = 0; - for(int i = 0; i < ((ARender*)commonrender)->history_size(); i++) + for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++) { level_history[i] = 0; level_samples[i] = -1; diff --git a/hvirtual/cinelerra/apatchgui.C b/hvirtual/cinelerra/apatchgui.C index db5f2114..67b32860 100644 --- a/hvirtual/cinelerra/apatchgui.C +++ b/hvirtual/cinelerra/apatchgui.C @@ -21,8 +21,16 @@ -APatchGUI::APatchGUI(MWindow *mwindow, PatchBay *patchbay, ATrack *track, int x, int y) - : PatchGUI(mwindow, patchbay, track, x, y) +APatchGUI::APatchGUI(MWindow *mwindow, + PatchBay *patchbay, + ATrack *track, + int x, + int y) + : PatchGUI(mwindow, + patchbay, + track, + x, + y) { data_type = TRACK_AUDIO; this->atrack = track; @@ -333,10 +341,11 @@ AMeterPatch::AMeterPatch(MWindow *mwindow, APatchGUI *patch, int x, int y) METER_HORIZ, patch->patchbay->get_w() - 10, mwindow->edl->session->min_meter_db, + mwindow->edl->session->max_meter_db, mwindow->edl->session->meter_format, 0, - mwindow->edl->session->record_speed * 10, - mwindow->edl->session->record_speed) + TRACKING_RATE * 10, + TRACKING_RATE) { this->mwindow = mwindow; this->patch = patch; diff --git a/hvirtual/cinelerra/arender.C b/hvirtual/cinelerra/arender.C index 83f7df06..3b719a60 100644 --- a/hvirtual/cinelerra/arender.C +++ b/hvirtual/cinelerra/arender.C @@ -49,6 +49,8 @@ ARender::~ARender() void ARender::arm_command() { +// Need the meter history now so AModule can allocate its own history + calculate_history_size(); CommonRender::arm_command(); asynchronous = 1; init_meters(); @@ -65,14 +67,16 @@ Module* ARender::new_module(Track *track) return new AModule(renderengine, this, 0, track); } -int ARender::history_size() +int ARender::calculate_history_size() { if(total_peaks > 0) return total_peaks; else { meter_render_fragment = renderengine->fragment_len; - while(meter_render_fragment > renderengine->edl->session->sample_rate / 10) +// This number and the timer in tracking.C determine the rate + while(meter_render_fragment > + renderengine->edl->session->sample_rate / TRACKING_RATE) meter_render_fragment /= 2; total_peaks = 16 * renderengine->fragment_len / @@ -85,14 +89,15 @@ int ARender::init_meters() { // not providing enough peaks results in peaks that are ahead of the sound if(level_samples) delete [] level_samples; - level_samples = new int64_t[history_size()]; + calculate_history_size(); + level_samples = new int64_t[total_peaks]; for(int i = 0; i < MAXCHANNELS;i++) { current_level[i] = 0; if(audio_out[i] && !level_history[i]) level_history[i] = new double[total_peaks]; } - for(int i = 0; i < history_size(); i++) + for(int i = 0; i < total_peaks; i++) { level_samples[i] = -1; } @@ -100,7 +105,7 @@ int ARender::init_meters() for(int j = 0; j < MAXCHANNELS; j++) { if(audio_out[j]) - for(int i = 0; i < history_size(); i++) + for(int i = 0; i < total_peaks; i++) level_history[j][i] = 0; } return 0; @@ -232,7 +237,7 @@ int ARender::get_history_number(int64_t *table, int64_t position) // Get the entry closest to position int result = 0; int64_t min_difference = 0x7fffffff; - for(int i = 0; i < history_size(); i++) + for(int i = 0; i < total_peaks; i++) { //printf("%d %d ", i, table[i]); if(labs(table[i] - position) < min_difference) @@ -412,7 +417,7 @@ int ARender::reverse_buffer(double *buffer, int64_t len) int ARender::get_next_peak(int current_peak) { current_peak++; - if(current_peak == total_peaks) current_peak = 0; + if(current_peak >= total_peaks) current_peak = 0; return current_peak; } diff --git a/hvirtual/cinelerra/arender.h b/hvirtual/cinelerra/arender.h index cefa81ad..5c1069f8 100644 --- a/hvirtual/cinelerra/arender.h +++ b/hvirtual/cinelerra/arender.h @@ -28,8 +28,9 @@ public: double fromunits(int64_t position); void run(); -// Calculate number of samples - int history_size(); +// Calculate number of samples in each meter fragment and how many +// meter fragments to buffer. + int calculate_history_size(); // Get subscript of history entry corresponding to sample int get_history_number(int64_t *table, int64_t position); @@ -37,7 +38,7 @@ public: double *audio_out[MAXCHANNELS]; // information for meters int get_next_peak(int current_peak); -// samples to use for one meter update +// samples to use for one meter update. Must be multiple of fragment_len int64_t meter_render_fragment; // Level history of output buffers double *level_history[MAXCHANNELS]; diff --git a/hvirtual/cinelerra/assetedit.C b/hvirtual/cinelerra/assetedit.C index a3a992a7..cda7119c 100644 --- a/hvirtual/cinelerra/assetedit.C +++ b/hvirtual/cinelerra/assetedit.C @@ -124,8 +124,8 @@ void AssetEdit::run() AssetEditWindow::AssetEditWindow(MWindow *mwindow, AssetEdit *asset_edit) : BC_Window(PROGRAM_NAME ": Asset Info", - mwindow->gui->get_abs_cursor_x() - 400 / 2, - mwindow->gui->get_abs_cursor_y() - 500 / 2, + mwindow->gui->get_abs_cursor_x(1) - 400 / 2, + mwindow->gui->get_abs_cursor_y(1) - 500 / 2, 400, 500, 400, diff --git a/hvirtual/cinelerra/assetremove.C b/hvirtual/cinelerra/assetremove.C index cc090f6b..fbb7961b 100644 --- a/hvirtual/cinelerra/assetremove.C +++ b/hvirtual/cinelerra/assetremove.C @@ -7,8 +7,8 @@ AssetRemoveWindow::AssetRemoveWindow(MWindow *mwindow) : BC_Window(PROGRAM_NAME ": Remove assets", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), 320, 120, -1, diff --git a/hvirtual/cinelerra/attachmentpoint.C b/hvirtual/cinelerra/attachmentpoint.C index 64004086..e18e7ea0 100644 --- a/hvirtual/cinelerra/attachmentpoint.C +++ b/hvirtual/cinelerra/attachmentpoint.C @@ -41,6 +41,7 @@ int AttachmentPoint::reset_parameters() void AttachmentPoint::reset_status() { + if(!this) printf("AttachmentPoint::reset_status NULL\n"); start_position = 0; len = 0; sample_rate = 0; @@ -57,6 +58,7 @@ int AttachmentPoint::identical(AttachmentPoint *old) int AttachmentPoint::render_init() { + if(!this) printf("AttachmentPoint::render_init NULL\n"); if(plugin_server && plugin->on) { // Start new plugin servers if the number of nodes changed. @@ -122,6 +124,7 @@ int AttachmentPoint::render_init() int AttachmentPoint::render_stop(int duplicate) { + if(!this) printf("AttachmentPoint::render_stop NULL\n"); // stop plugins // Can't use the on value here because it may have changed. if(plugin_server && plugin->on && virtual_plugins.total && !duplicate) @@ -141,6 +144,7 @@ int AttachmentPoint::render_stop(int duplicate) int AttachmentPoint::attach_virtual_plugin(VirtualNode *virtual_plugin) { + if(!this) printf("AttachmentPoint::attach_virtual_plugin NULL\n"); int buffer_number = 0; if(plugin_server && plugin->on) @@ -168,6 +172,7 @@ int AttachmentPoint::attach_virtual_plugin(VirtualNode *virtual_plugin) int AttachmentPoint::multichannel_shared(int search_new) { + if(!this) printf("AttachmentPoint::multichannel_shared NULL\n"); if(search_new) { if(new_virtual_plugins.total && @@ -185,6 +190,7 @@ int AttachmentPoint::multichannel_shared(int search_new) int AttachmentPoint::singlechannel() { + if(!this) printf("AttachmentPoint::singlechannel NULL\n"); if(plugin_server && !plugin_server->multichannel) return 1; return 0; } @@ -192,12 +198,14 @@ int AttachmentPoint::singlechannel() void AttachmentPoint::render_gui(void *data) { + if(!this) printf("AttachmentPoint::render_gui 1 NULL\n"); if(renderengine && renderengine->mwindow) renderengine->mwindow->render_plugin_gui(data, plugin); } void AttachmentPoint::render_gui(void *data, int size) { + if(!this) printf("AttachmentPoint::render_gui 2 NULL\n"); if(renderengine && renderengine->mwindow) renderengine->mwindow->render_plugin_gui(data, size, plugin); } @@ -216,8 +224,15 @@ void AttachmentPoint::render_gui(void *data, int size) int AttachmentPoint::dump() { - printf(" Attachmentpoint %x virtual_plugins=%d\n", this, new_virtual_plugins.total); - if(plugin_server) plugin_server->dump(); + if(this) + { + printf(" Attachmentpoint %x virtual_plugins=%d\n", this, new_virtual_plugins.total); + if(plugin_server) plugin_server->dump(); + } + else + { + printf(" No Plugin\n"); + } } diff --git a/hvirtual/cinelerra/attachmentpoint.h b/hvirtual/cinelerra/attachmentpoint.h index 8d65ac64..2109e908 100644 --- a/hvirtual/cinelerra/attachmentpoint.h +++ b/hvirtual/cinelerra/attachmentpoint.h @@ -20,7 +20,9 @@ class AttachmentPoint { public: - AttachmentPoint(RenderEngine *renderengine, Plugin *plugin, int data_type); + AttachmentPoint(RenderEngine *renderengine, + Plugin *plugin, + int data_type); virtual ~AttachmentPoint(); virtual int reset_parameters(); @@ -44,18 +46,9 @@ public: // check all the virtual plugins for waiting status // all virtual plugins attached to this must be waiting for a render // int sort(VirtualNode *virtual_plugin); -/* - * void render(long current_position, - * long fragment_size); - */ // Called by plugin server to render GUI with data. void render_gui(void *data); void render_gui(void *data, int size); -/* - * virtual void dispatch_plugin_server(int buffer_number, - * long current_position, - * long fragment_size) {}; - */ virtual int get_buffer_size() { return 0; }; // For unshared plugins, virtual plugins to send configuration events to and @@ -102,17 +95,6 @@ public: -// For multichannel plugins store the fragment positions for each plugin -// and render the plugin when the last fragment position is stored - int render(int double_buffer_in, int double_buffer_out, - long fragment_position_in, long fragment_position_out, - long size, int node_number, - long source_position, long source_len, - FloatAutos *autos = 0, - FloatAuto **start_auto = 0, - FloatAuto **end_auto = 0, - int reverse = 0); - int multichannel_shared(int search_new); int singlechannel(); diff --git a/hvirtual/cinelerra/audio1394.C b/hvirtual/cinelerra/audio1394.C index c8c0751e..e2e1b805 100644 --- a/hvirtual/cinelerra/audio1394.C +++ b/hvirtual/cinelerra/audio1394.C @@ -50,7 +50,9 @@ int Audio1394::open_input() 30, device->in_channels, device->in_samplerate, - device->in_bits); + device->in_bits, + device->vconfig->w, + device->vconfig->h); if(result) { delete input_thread; diff --git a/hvirtual/cinelerra/audioalsa.C b/hvirtual/cinelerra/audioalsa.C index 4dc5d0fa..5363b2ce 100644 --- a/hvirtual/cinelerra/audioalsa.C +++ b/hvirtual/cinelerra/audioalsa.C @@ -8,12 +8,20 @@ #ifdef HAVE_ALSA -AudioALSA::AudioALSA(AudioDevice *device) : AudioLowLevel(device) +AudioALSA::AudioALSA(AudioDevice *device) + : AudioLowLevel(device) { + samples_written = 0; + timer = new Timer; + delay = 0; + timer_lock = new Mutex("AudioALSA::timer_lock"); + interrupted = 0; } AudioALSA::~AudioALSA() { + delete timer_lock; + delete timer; } void AudioALSA::list_devices(ArrayList *devices, int pcm_title) @@ -30,6 +38,10 @@ void AudioALSA::list_devices(ArrayList *devices, int pcm_title) snd_pcm_info_alloca(&pcminfo); card = -1; +#define DEFAULT_DEVICE "default" + char *result = new char[strlen(DEFAULT_DEVICE) + 1]; + devices->append(result); + strcpy(result, DEFAULT_DEVICE); while(snd_card_next(&card) >= 0) { @@ -221,9 +233,7 @@ void AudioALSA::set_params(snd_pcm_t *dsp, printf("AudioALSA::set_params: snd_pcm_sw_params failed\n"); } - device->device_buffer = buffer_size / - (bits / 8) / - channels; + device->device_buffer = samples * bits / 8 * channels; //printf("AudioALSA::set_params 100 %d %d\n", samples, device->device_buffer); @@ -285,6 +295,7 @@ int AudioALSA::open_output() device->out_config->alsa_out_bits, device->out_samplerate, device->out_samples); + timer->update(); return 0; } @@ -294,64 +305,137 @@ int AudioALSA::open_duplex() return 0; } +int AudioALSA::close_output() +{ + if(device->w) + { + snd_pcm_close(dsp_out); + } + return 0; +} -int AudioALSA::close_all() +int AudioALSA::close_input() { if(device->r) { - snd_pcm_reset(dsp_in); +// snd_pcm_reset(dsp_in); snd_pcm_drop(dsp_in); snd_pcm_drain(dsp_in); snd_pcm_close(dsp_in); } - if(device->w) - { - snd_pcm_close(dsp_out); - } + return 0; +} + +int AudioALSA::close_all() +{ + close_input(); + close_output(); if(device->d) { snd_pcm_close(dsp_duplex); } + samples_written = 0; + delay = 0; + interrupted = 0; } // Undocumented int64_t AudioALSA::device_position() { - return -1; + timer_lock->lock("AudioALSA::device_position"); + int64_t result = samples_written + + timer->get_scaled_difference(device->out_samplerate) - + delay; +// printf("AudioALSA::device_position 1 %lld %lld %d %lld\n", +// samples_written, +// timer->get_scaled_difference(device->out_samplerate), +// delay, +// samples_written + timer->get_scaled_difference(device->out_samplerate) - delay); + timer_lock->unlock(); + return result; } int AudioALSA::read_buffer(char *buffer, int size) { //printf("AudioALSA::read_buffer 1\n"); - snd_pcm_readi(get_input(), - buffer, - size / (device->in_bits / 8) / device->in_channels); -//printf("AudioALSA::read_buffer 2\n"); + int attempts = 0; + int done = 0; + while(attempts < 2 && !done) + { + if(snd_pcm_readi(get_input(), + buffer, + size / (device->in_bits / 8) / device->in_channels) < 0) + { + perror("AudioALSA::read_buffer"); + close_input(); + open_input(); + attempts++; + } + else + done = 1; + } return 0; } int AudioALSA::write_buffer(char *buffer, int size) { +// Don't give up and drop the buffer on the first error. + int attempts = 0; + int done = 0; + int samples = size / (device->out_bits / 8) / device->out_channels; + while(attempts < 2 && !done && !interrupted) + { // Buffers written must be equal to period_time - if(snd_pcm_writei(get_output(), - buffer, - size / (device->out_bits / 8) / device->out_channels) < 0) +// Update timing + snd_pcm_sframes_t delay; + snd_pcm_delay(get_output(), &delay); + snd_pcm_avail_update(get_output()); + + device->Thread::enable_cancel(); + if(snd_pcm_writei(get_output(), + buffer, + samples) < 0) + { + device->Thread::disable_cancel(); + perror("AudioALSA::write_buffer"); + close_output(); +// sleep(1); + open_output(); + attempts++; + } + else + { + device->Thread::disable_cancel(); + done = 1; + } + } + + if(done) { - printf("AudioALSA::write_buffer: failed\n"); - sleep(1); + timer_lock->lock("AudioALSA::write_buffer"); + this->delay = delay; + timer->update(); + samples_written += samples; + timer_lock->unlock(); } return 0; } int AudioALSA::flush_device() { - snd_pcm_drain(get_output()); + if(get_output()) snd_pcm_drain(get_output()); return 0; } int AudioALSA::interrupt_playback() { - + if(get_output()) + { + interrupted = 1; + snd_pcm_drop(get_output()); +// The only way to ensure snd_pcm_writei exits + device->Thread::cancel(); + } return 0; } diff --git a/hvirtual/cinelerra/audioalsa.h b/hvirtual/cinelerra/audioalsa.h index 38379c25..51224028 100644 --- a/hvirtual/cinelerra/audioalsa.h +++ b/hvirtual/cinelerra/audioalsa.h @@ -20,11 +20,13 @@ public: int write_buffer(char *buffer, int size); int read_buffer(char *buffer, int size); int close_all(); + int close_input(); int64_t device_position(); int flush_device(); int interrupt_playback(); private: + int close_output(); void translate_name(char *output, char *input); snd_pcm_format_t translate_format(int format); void set_params(snd_pcm_t *dsp, @@ -36,6 +38,11 @@ private: snd_pcm_t* get_output(); snd_pcm_t* get_input(); snd_pcm_t *dsp_in, *dsp_out, *dsp_duplex; + int64_t samples_written; + Timer *timer; + int delay; + Mutex *timer_lock; + int interrupted; }; #endif diff --git a/hvirtual/cinelerra/audiodevice.C b/hvirtual/cinelerra/audiodevice.C index 5306f58d..b93eb50e 100644 --- a/hvirtual/cinelerra/audiodevice.C +++ b/hvirtual/cinelerra/audiodevice.C @@ -1,7 +1,7 @@ #include "audio1394.h" +#include "audioalsa.h" #include "audioconfig.h" #include "audiodevice.h" -#include "audioalsa.h" #include "audioesound.h" #include "audiooss.h" #include "condition.h" @@ -10,7 +10,7 @@ #include "playbackconfig.h" #include "preferences.h" #include "recordconfig.h" - +#include "sema.h" @@ -32,15 +32,16 @@ AudioDevice::AudioDevice() : Thread(1, 0, 0) { initialize(); - this->out_config = new AudioOutConfig(0, 0, 0); + this->out_config = new AudioOutConfig(0); this->in_config = new AudioInConfig; + this->vconfig = new VideoInConfig; startup_lock = new Condition(0, "AudioDevice::startup_lock"); duplex_lock = new Condition(0, "AudioDevice::duplex_lock"); timer_lock = new Mutex("AudioDevice::timer_lock"); for(int i = 0; i < TOTAL_BUFFERS; i++) { - play_lock[i] = new Condition(0, "AudioDevice::play_lock"); - arm_lock[i] = new Condition(1, "AudioDevice::arm_lock"); + play_lock[i] = new Sema(0, "AudioDevice::play_lock"); + arm_lock[i] = new Sema(1, "AudioDevice::arm_lock"); } } @@ -48,6 +49,7 @@ AudioDevice::~AudioDevice() { delete out_config; delete in_config; + delete vconfig; delete startup_lock; delete duplex_lock; delete timer_lock; @@ -131,11 +133,15 @@ int AudioDevice::create_lowlevel(AudioLowLevel* &lowlevel, int driver) return 0; } -int AudioDevice::open_input(AudioInConfig *config, int rate, int samples) +int AudioDevice::open_input(AudioInConfig *config, + VideoInConfig *vconfig, + int rate, + int samples) { r = 1; duplex_init = 0; - *this->in_config = *config; + this->in_config->copy_from(config); + this->vconfig->copy_from(vconfig); //printf("AudioDevice::open_input %s\n", this->in_config->oss_in_device[0]); in_samplerate = rate; in_samples = samples; diff --git a/hvirtual/cinelerra/audiodevice.h b/hvirtual/cinelerra/audiodevice.h index b6b15486..d471427c 100644 --- a/hvirtual/cinelerra/audiodevice.h +++ b/hvirtual/cinelerra/audiodevice.h @@ -7,12 +7,13 @@ #include #include +#include "audio1394.inc" #include "audioalsa.inc" #include "audioconfig.inc" #include "audiodevice.inc" -#include "audio1394.inc" #include "audioesound.inc" #include "audiooss.inc" +#include "bctimer.h" #include "binary.h" #include "condition.inc" #include "dcoffset.inc" @@ -21,8 +22,8 @@ #include "mutex.inc" #include "preferences.inc" #include "recordgui.inc" +#include "sema.inc" #include "thread.h" -#include "bctimer.h" #include "vdevice1394.inc" #include "videodevice.inc" @@ -60,7 +61,10 @@ public: friend class VDevice1394; friend class Device1394Output; - int open_input(AudioInConfig *config, int rate, int samples); + int open_input(AudioInConfig *config, + VideoInConfig *vconfig, + int rate, + int samples); int open_output(AudioOutConfig *config, int rate, int samples, int realtime); int open_duplex(AudioOutConfig *config, int rate, int samples, int realtime); int close_all(); @@ -167,8 +171,8 @@ private: int last_buffer[TOTAL_BUFFERS]; // not written to device // formatted buffers for output char *buffer[TOTAL_BUFFERS], *input_buffer; - Condition *play_lock[TOTAL_BUFFERS]; - Condition *arm_lock[TOTAL_BUFFERS]; + Sema *play_lock[TOTAL_BUFFERS]; + Sema *arm_lock[TOTAL_BUFFERS]; Mutex *timer_lock; int arm_buffer_num; @@ -187,6 +191,8 @@ private: AudioOutConfig *out_config; AudioInConfig *in_config; +// Extra configuration if shared with video + VideoInConfig *vconfig; private: int thread_buffer_num, thread_result; diff --git a/hvirtual/cinelerra/audioodevice.C b/hvirtual/cinelerra/audioodevice.C index 09e58056..799016a4 100644 --- a/hvirtual/cinelerra/audioodevice.C +++ b/hvirtual/cinelerra/audioodevice.C @@ -1,6 +1,7 @@ #include "audiodevice.h" #include "condition.h" #include "mutex.h" +#include "sema.h" #include @@ -241,17 +242,15 @@ int AudioDevice::interrupt_playback() // cancel thread is_playing_back = 0; get_lowlevel_out()->interrupt_playback(); -// Thread::cancel(); // Completion is waited for in arender } // unlock everything for(int i = 0; i < TOTAL_BUFFERS; i++) { -// play_lock[i].reset(); -// Caused a crash when run() was waiting on it in original versions. -// This is required now since thread cancelation is only possible during -// write(). +// When TRACE_LOCKS is enabled, this +// locks up when run() is waiting on it at just the right time. +// Seems there may be a cancel after the trace lock is locked. play_lock[i]->unlock(); arm_lock[i]->unlock(); } @@ -356,8 +355,9 @@ void AudioDevice::run() timer_lock->unlock(); -// write buffer - thread_result = get_lowlevel_out()->write_buffer(buffer[thread_buffer_num], buffer_size[thread_buffer_num]); +// write converted buffer synchronously + thread_result = get_lowlevel_out()->write_buffer(buffer[thread_buffer_num], + buffer_size[thread_buffer_num]); // allow writing to the buffer arm_lock[thread_buffer_num]->unlock(); diff --git a/hvirtual/cinelerra/autoconf.C b/hvirtual/cinelerra/autoconf.C new file mode 100644 index 00000000..84e21940 --- /dev/null +++ b/hvirtual/cinelerra/autoconf.C @@ -0,0 +1,102 @@ +#include "autoconf.h" +#include "defaults.h" +#include "filexml.h" + +int AutoConf::load_defaults(Defaults* defaults) +{ + fade = defaults->get("SHOW_FADE", 0); + pan = defaults->get("SHOW_PAN", 1); + mute = defaults->get("SHOW_MUTE", 0); + transitions = defaults->get("SHOW_TRANSITIONS", 1); + plugins = defaults->get("SHOW_PLUGINS", 1); + camera = defaults->get("SHOW_CAMERA", 1); + projector = defaults->get("SHOW_PROJECTOR", 1); + mode = defaults->get("SHOW_MODE", 1); + mask = defaults->get("SHOW_MASK", 0); + czoom = defaults->get("SHOW_CZOOM", 0); + pzoom = defaults->get("SHOW_PZOOM", 0); + return 0; +} + +void AutoConf::load_xml(FileXML *file) +{ + fade = file->tag.get_property("SHOW_FADE", 0); + pan = file->tag.get_property("SHOW_PAN", 0); + mute = file->tag.get_property("SHOW_MUTE", 0); + transitions = file->tag.get_property("SHOW_TRANSITIONS", 1); + plugins = file->tag.get_property("SHOW_PLUGINS", 1); + camera = file->tag.get_property("SHOW_CAMERA", 1); + projector = file->tag.get_property("SHOW_PROJECTOR", 1); + mode = file->tag.get_property("SHOW_MODE", 1); + mask = file->tag.get_property("SHOW_MASK", 0); + czoom = file->tag.get_property("SHOW_CZOOM", 0); + pzoom = file->tag.get_property("SHOW_PZOOM", 0); +} + +int AutoConf::save_defaults(Defaults* defaults) +{ + defaults->update("SHOW_FADE", fade); + defaults->update("SHOW_PAN", pan); + defaults->update("SHOW_MUTE", mute); + defaults->update("SHOW_TRANSITIONS", transitions); + defaults->update("SHOW_PLUGINS", plugins); + defaults->update("SHOW_CAMERA", camera); + defaults->update("SHOW_PROJECTOR", projector); + defaults->update("SHOW_MODE", mode); + defaults->update("SHOW_MASK", mask); + defaults->update("SHOW_CZOOM", czoom); + defaults->update("SHOW_PZOOM", pzoom); + return 0; +} + +void AutoConf::save_xml(FileXML *file) +{ + file->tag.set_property("SHOW_FADE", fade); + file->tag.set_property("SHOW_PAN", pan); + file->tag.set_property("SHOW_MUTE", mute); + file->tag.set_property("SHOW_TRANSITIONS", transitions); + file->tag.set_property("SHOW_PLUGINS", plugins); + file->tag.set_property("SHOW_CAMERA", camera); + file->tag.set_property("SHOW_PROJECTOR", projector); + file->tag.set_property("SHOW_MODE", mode); + file->tag.set_property("SHOW_MASK", mask); + file->tag.set_property("SHOW_CZOOM", czoom); + file->tag.set_property("SHOW_PZOOM", pzoom); +} + +int AutoConf::set_all() +{ + fade = 1; + pan = 1; + mute = 1; + transitions = 1; + plugins = 1; + camera = 1; + projector = 1; + mode = 1; + mask = 1; + czoom = 1; + pzoom = 1; + return 0; +} + +AutoConf& AutoConf::operator=(AutoConf &that) +{ + copy_from(&that); + return *this; +} + +void AutoConf::copy_from(AutoConf *src) +{ + fade = src->fade; + pan = src->pan; + mute = src->mute; + transitions = src->transitions; + plugins = src->plugins; + camera = src->camera; + projector = src->projector; + mode = src->mode; + mask = src->mask; + czoom = src->czoom; + pzoom = src->pzoom; +} diff --git a/hvirtual/cinelerra/autoconf.h b/hvirtual/cinelerra/autoconf.h new file mode 100644 index 00000000..908029b4 --- /dev/null +++ b/hvirtual/cinelerra/autoconf.h @@ -0,0 +1,36 @@ +#ifndef AUTOCONF_H +#define AUTOCONF_H + +#include "defaults.inc" +#include "filexml.inc" +#include "maxchannels.h" +#include "module.inc" + +class AutoConf +{ +public: + AutoConf() {}; + ~AutoConf() {}; + + AutoConf& operator=(AutoConf &that); + void copy_from(AutoConf *src); + int load_defaults(Defaults* defaults); + int save_defaults(Defaults* defaults); + void load_xml(FileXML *file); + void save_xml(FileXML *file); + int set_all(); // set all parameters to 1 + + int fade; + int pan; + int mute; + int transitions; + int plugins; + int camera; + int projector; + int mode; + int mask; + int czoom; + int pzoom; +}; + +#endif diff --git a/hvirtual/cinelerra/autos.C b/hvirtual/cinelerra/autos.C index ca828d5a..d3868fec 100644 --- a/hvirtual/cinelerra/autos.C +++ b/hvirtual/cinelerra/autos.C @@ -224,18 +224,8 @@ int Autos::auto_exists_for_editing(double position) { double unit_position = position; unit_position = edl->align_to_frame(unit_position, 0); - unit_position = track->to_units(unit_position, 0); - - for(Auto *current = first; - current; - current = NEXT) - { - if(edl->equivalent(current->position, unit_position)) - { - result = 1; - break; - } - } + if (get_auto_at_position(unit_position)) + result = 1; } else { @@ -245,6 +235,23 @@ int Autos::auto_exists_for_editing(double position) return result; } +Auto* Autos::get_auto_at_position(double position) +{ + int64_t unit_position = track->to_units(position, 0); + + for(Auto *current = first; + current; + current = NEXT) + { + if(edl->equivalent(current->position, unit_position)) + { + return current; + } + } + return 0; +} + + Auto* Autos::get_auto_for_editing(double position) { if(position < 0) diff --git a/hvirtual/cinelerra/autos.h b/hvirtual/cinelerra/autos.h index 7740b20d..91185621 100644 --- a/hvirtual/cinelerra/autos.h +++ b/hvirtual/cinelerra/autos.h @@ -37,6 +37,8 @@ public: Auto* get_next_auto(int64_t position, int direction, Auto* ¤t, int use_default = 1); // Determine if a keyframe exists before creating it. int auto_exists_for_editing(double position); +// Returns auto at exact position, null if non-existent. ignores autokeyframming and align on frames + Auto* get_auto_at_position(double position = -1); // Get keyframe for editing with automatic creation if enabled Auto* get_auto_for_editing(double position = -1); // Insert keyframe at the point if it doesn't exist diff --git a/hvirtual/cinelerra/batch.C b/hvirtual/cinelerra/batch.C index b3b99436..55185a97 100644 --- a/hvirtual/cinelerra/batch.C +++ b/hvirtual/cinelerra/batch.C @@ -83,7 +83,7 @@ void Batch::calculate_news() // File open if(record->get_current_batch() == this && record->file) { - sprintf(news, "Open"); + sprintf(news, _("Open")); } else { @@ -92,11 +92,11 @@ void Batch::calculate_news() if(test) { - sprintf(news, "File exists"); + sprintf(news, _("File exists")); fclose(test); } else - sprintf(news, "OK"); + sprintf(news, _("OK")); } } @@ -147,10 +147,10 @@ char* Batch::mode_to_text(int record_mode) switch(record_mode) { case RECORD_INFINITE: - return "Untimed"; + return _("Untimed"); break; case RECORD_TIMED: - return "Timed"; + return _("Timed"); break; // case RECORD_LOOP: // return "Loop"; @@ -159,7 +159,7 @@ char* Batch::mode_to_text(int record_mode) // return "Scene to scene"; // break; } - return "Unknown"; + return _("Unknown"); } Asset* Batch::get_current_asset() @@ -180,10 +180,15 @@ Channel* Batch::get_current_channel_struct() char* Batch::get_source_text() { - // Driver sensitive +// Driver sensitive Channel *channel = get_current_channel_struct(); + + if(channel) + { +printf("Batch::get_source_text 1 %s\n", channel->title); return channel->title; + } else return ""; } diff --git a/hvirtual/cinelerra/browsebutton.C b/hvirtual/cinelerra/browsebutton.C index 66f075e7..9a2c0fd3 100644 --- a/hvirtual/cinelerra/browsebutton.C +++ b/hvirtual/cinelerra/browsebutton.C @@ -28,12 +28,12 @@ BrowseButton::BrowseButton(MWindow *mwindow, this->mwindow = mwindow; set_tooltip(_("Look for file")); gui = 0; - startup_lock = new Mutex; + startup_lock = new Mutex("BrowseButton::startup_lock"); } BrowseButton::~BrowseButton() { - startup_lock->lock(); + startup_lock->lock("BrowseButton::~BrowseButton"); if(gui) { gui->lock_window(); @@ -58,12 +58,12 @@ int BrowseButton::handle_event() return 1; } - x = parent_window->get_abs_cursor_x(); - y = parent_window->get_abs_cursor_y(); - startup_lock->lock(); + x = parent_window->get_abs_cursor_x(0); + y = parent_window->get_abs_cursor_y(0); + startup_lock->lock("BrowseButton::handle_event 1"); Thread::start(); - startup_lock->lock(); + startup_lock->lock("BrowseButton::handle_event 2"); startup_lock->unlock(); return 1; } @@ -97,7 +97,7 @@ void BrowseButton::run() parent_window->flush(); textbox->handle_event(); } - startup_lock->lock(); + startup_lock->lock("BrowseButton::run"); gui = 0; startup_lock->unlock(); } diff --git a/hvirtual/cinelerra/builddate.h b/hvirtual/cinelerra/builddate.h index 58b235a8..23115591 100644 --- a/hvirtual/cinelerra/builddate.h +++ b/hvirtual/cinelerra/builddate.h @@ -1 +1 @@ -#define BUILDDATE "Mon May 10 22:25:09 PDT 2004" +#define BUILDDATE "Sun Aug 8 13:45:49 EDT 2004" diff --git a/hvirtual/cinelerra/channeledit.C b/hvirtual/cinelerra/channeledit.C index a6aab4e7..d49c475d 100644 --- a/hvirtual/cinelerra/channeledit.C +++ b/hvirtual/cinelerra/channeledit.C @@ -121,8 +121,8 @@ ChannelEditWindow::ChannelEditWindow(MWindow *mwindow, ChannelEditThread *thread, ChannelPicker *channel_picker) : BC_Window(PROGRAM_NAME ": Channels", - mwindow->gui->get_abs_cursor_x() - 330, - mwindow->gui->get_abs_cursor_y(), + mwindow->gui->get_abs_cursor_x(1) - 330, + mwindow->gui->get_abs_cursor_y(1), 330, 330, 330, @@ -699,8 +699,8 @@ ChannelEditEditWindow::ChannelEditEditWindow(ChannelEditEditThread *thread, ChannelEditWindow *window, ChannelPicker *channel_picker) : BC_Window(PROGRAM_NAME ": Edit Channel", - channel_picker->mwindow->gui->get_abs_cursor_x(), - channel_picker->mwindow->gui->get_abs_cursor_y(), + channel_picker->mwindow->gui->get_abs_cursor_x(1), + channel_picker->mwindow->gui->get_abs_cursor_y(1), 390, 270, 390, @@ -1041,8 +1041,8 @@ int ChannelEditPictureThread::close_threads() ChannelEditPictureWindow::ChannelEditPictureWindow(ChannelEditPictureThread *thread, ChannelPicker *channel_picker) : BC_Window(PROGRAM_NAME ": Picture", - channel_picker->mwindow->gui->get_abs_cursor_x() - 200, - channel_picker->mwindow->gui->get_abs_cursor_y() - 220, + channel_picker->mwindow->gui->get_abs_cursor_x(1) - 200, + channel_picker->mwindow->gui->get_abs_cursor_y(1) - 220, 200, 250, 200, diff --git a/hvirtual/cinelerra/channelpicker.C b/hvirtual/cinelerra/channelpicker.C index 3c0bfec6..b4e59332 100644 --- a/hvirtual/cinelerra/channelpicker.C +++ b/hvirtual/cinelerra/channelpicker.C @@ -438,6 +438,7 @@ ChannelText::ChannelText(MWindow *mwindow, 150, 300) { + this->channel_picker = channel_picker; this->mwindow = mwindow; } diff --git a/hvirtual/cinelerra/clipedit.C b/hvirtual/cinelerra/clipedit.C index 8468f4f3..b12c84c1 100644 --- a/hvirtual/cinelerra/clipedit.C +++ b/hvirtual/cinelerra/clipedit.C @@ -124,8 +124,8 @@ void ClipEdit::run() ClipEditWindow::ClipEditWindow(MWindow *mwindow, ClipEdit *thread) : BC_Window(PROGRAM_NAME ": Clip Info", - mwindow->gui->get_abs_cursor_x() - 400 / 2, - mwindow->gui->get_abs_cursor_y() - 350 / 2, + mwindow->gui->get_abs_cursor_x(1) - 400 / 2, + mwindow->gui->get_abs_cursor_y(1) - 350 / 2, 400, 350, 400, diff --git a/hvirtual/cinelerra/commonrender.C b/hvirtual/cinelerra/commonrender.C index baf43e8a..ce302b2c 100644 --- a/hvirtual/cinelerra/commonrender.C +++ b/hvirtual/cinelerra/commonrender.C @@ -20,7 +20,7 @@ #include "virtualconsole.h" CommonRender::CommonRender(RenderEngine *renderengine) - : Thread() + : Thread(1, 0, 0) { this->renderengine = renderengine; reset_parameters(); @@ -42,7 +42,6 @@ CommonRender::~CommonRender() void CommonRender::reset_parameters() { total_modules = 0; - set_synchronous(1); modules = 0; vconsole = 0; done = 0; diff --git a/hvirtual/cinelerra/commonrender.h b/hvirtual/cinelerra/commonrender.h index 1afe69a9..bea8fef7 100644 --- a/hvirtual/cinelerra/commonrender.h +++ b/hvirtual/cinelerra/commonrender.h @@ -60,7 +60,7 @@ public: int data_type; // If a VirtualConsole was created need to start plugins int restart_plugins; - + diff --git a/hvirtual/cinelerra/confirmquit.C b/hvirtual/cinelerra/confirmquit.C index f65f917e..1c9d95bf 100644 --- a/hvirtual/cinelerra/confirmquit.C +++ b/hvirtual/cinelerra/confirmquit.C @@ -10,8 +10,8 @@ ConfirmQuitWindow::ConfirmQuitWindow(MWindow *mwindow) : BC_Window(PROGRAM_NAME ": Question", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), 375, 160) { diff --git a/hvirtual/cinelerra/confirmsave.C b/hvirtual/cinelerra/confirmsave.C index 356ceb77..027f5c75 100644 --- a/hvirtual/cinelerra/confirmsave.C +++ b/hvirtual/cinelerra/confirmsave.C @@ -83,8 +83,8 @@ int ConfirmSave::test_files(MWindow *mwindow, ConfirmSaveWindow::ConfirmSaveWindow(MWindow *mwindow, ArrayList *list) : BC_Window(PROGRAM_NAME ": File Exists", - mwindow->gui->get_abs_cursor_x() - 160, - mwindow->gui->get_abs_cursor_y() - 120, + mwindow->gui->get_abs_cursor_x(1) - 160, + mwindow->gui->get_abs_cursor_y(1) - 120, 320, 240) { diff --git a/hvirtual/cinelerra/cplayback.C b/hvirtual/cinelerra/cplayback.C index d48f1591..e3b67d13 100644 --- a/hvirtual/cinelerra/cplayback.C +++ b/hvirtual/cinelerra/cplayback.C @@ -18,10 +18,9 @@ CPlayback::CPlayback(MWindow *mwindow, CWindow *cwindow, Canvas *output) this->cwindow = cwindow; } -int CPlayback::create_render_engines() +int CPlayback::create_render_engine() { - command->get_edl()->session->playback_strategy = PLAYBACK_LOCALHOST; - return PlaybackEngine::create_render_engines(); + return PlaybackEngine::create_render_engine(); } void CPlayback::init_cursor() diff --git a/hvirtual/cinelerra/cplayback.h b/hvirtual/cinelerra/cplayback.h new file mode 100644 index 00000000..43adc0c1 --- /dev/null +++ b/hvirtual/cinelerra/cplayback.h @@ -0,0 +1,20 @@ +#ifndef CPLAYBACK_H +#define CPLAYBACK_H + +#include "cwindow.inc" +#include "playbackengine.h" + +class CPlayback : public PlaybackEngine +{ +public: + CPlayback(MWindow *mwindow, CWindow *cwindow, Canvas *output); + + int create_render_engine(); + void init_cursor(); + void stop_cursor(); + int brender_available(long position); + + CWindow *cwindow; +}; + +#endif diff --git a/hvirtual/cinelerra/ctracking.C b/hvirtual/cinelerra/ctracking.C index bf95fbcd..c2fe5c91 100644 --- a/hvirtual/cinelerra/ctracking.C +++ b/hvirtual/cinelerra/ctracking.C @@ -112,32 +112,25 @@ void CTracking::update_tracker(double position) { int updated_scroll = 0; // Update cwindow slider -//TRACE("CTracking::update_tracker 1"); cwindow->gui->lock_window("CTracking::update_tracker 1"); -//TRACE("CTracking::update_tracker 2"); cwindow->gui->slider->update(position); // This is going to boost the latency but we need to update the timebar cwindow->gui->timebar->draw_range(); cwindow->gui->timebar->flash(); cwindow->gui->unlock_window(); -//TRACE("CTracking::update_tracker 3"); // Update mwindow cursor mwindow->gui->lock_window("CTracking::update_tracker 2"); -//TRACE("CTracking::update_tracker 4"); mwindow->edl->local_session->selectionstart = mwindow->edl->local_session->selectionend = position; updated_scroll = update_scroll(position); -//TRACE("CTracking::update_tracker 5"); mwindow->gui->mainclock->update(position); -//TRACE("CTracking::update_tracker 5.5"); mwindow->gui->patchbay->update(); -//TRACE("CTracking::update_tracker 6"); if(!updated_scroll) { @@ -149,15 +142,12 @@ void CTracking::update_tracker(double position) mwindow->gui->flush(); } mwindow->gui->unlock_window(); -//TRACE("CTracking::update_tracker 7"); // Plugin GUI's hold lock on mwindow->gui here during user interface handlers. mwindow->update_plugin_guis(); -//TRACE("CTracking::update_tracker 8"); update_meters((int64_t)(position * mwindow->edl->session->sample_rate)); -//TRACE("CTracking::update_tracker 9"); } void CTracking::draw() diff --git a/hvirtual/cinelerra/cwindowtool.C b/hvirtual/cinelerra/cwindowtool.C index 179b05ce..66468cad 100644 --- a/hvirtual/cinelerra/cwindowtool.C +++ b/hvirtual/cinelerra/cwindowtool.C @@ -489,7 +489,15 @@ void CWindowCameraGUI::handle_event() else if(zoom_keyframe) { - zoom_keyframe->value = atof(z->get_text()); + float zoom = atof(z->get_text()); + if(zoom > 10) zoom = 10; + else + if(zoom < 0) zoom = 0; +// Doesn't allow user to enter from scratch +// if(zoom != atof(z->get_text())) +// z->update(zoom); + + zoom_keyframe->value = zoom; mwindow->gui->lock_window("CWindowCameraGUI::handle_event"); mwindow->gui->canvas->draw_overlays(); mwindow->gui->canvas->flash(); @@ -872,7 +880,13 @@ void CWindowProjectorGUI::handle_event() else if(zoom_keyframe) { - zoom_keyframe->value = atof(z->get_text()); + float zoom = atof(z->get_text()); + if(zoom > 10000) zoom = 10000; + else + if(zoom < 0) zoom = 0; +// if (zoom != atof(z->get_text())) +// z->update(zoom); + zoom_keyframe->value = zoom; mwindow->gui->lock_window("CWindowProjectorGUI::handle_event"); mwindow->gui->canvas->draw_overlays(); mwindow->gui->canvas->flash(); diff --git a/hvirtual/cinelerra/deleteallindexes.C b/hvirtual/cinelerra/deleteallindexes.C index 03dd693f..9c0011e0 100644 --- a/hvirtual/cinelerra/deleteallindexes.C +++ b/hvirtual/cinelerra/deleteallindexes.C @@ -70,8 +70,8 @@ void DeleteAllIndexes::run() ConfirmDeleteAllIndexes::ConfirmDeleteAllIndexes(MWindow *mwindow, char *string) : BC_Window(PROGRAM_NAME ": Delete All Indexes", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), 340, 140) { diff --git a/hvirtual/cinelerra/drivesync.C b/hvirtual/cinelerra/drivesync.C index fb210961..3fe58fda 100644 --- a/hvirtual/cinelerra/drivesync.C +++ b/hvirtual/cinelerra/drivesync.C @@ -21,9 +21,7 @@ void DriveSync::run() // Task switching too slow on alpha while(!done) { -//printf("DriveSync::run 1\n"); sync(); -//printf("DriveSync::run 10\n"); sleep(1); } } diff --git a/hvirtual/cinelerra/edits.C b/hvirtual/cinelerra/edits.C index 7832a3a0..762327df 100644 --- a/hvirtual/cinelerra/edits.C +++ b/hvirtual/cinelerra/edits.C @@ -246,6 +246,13 @@ void Edits::resample(double old_rate, double new_rate) if(!NEXT) current->length = Units::to_int64((double)current->length / old_rate * new_rate); + if(current->transition) + { + current->transition->length = Units::to_int64( + (double)current->transition->length / + old_rate * + new_rate); + } current->resample(old_rate, new_rate); } } diff --git a/hvirtual/cinelerra/edl.C b/hvirtual/cinelerra/edl.C index bb1a4a3e..ca3b062b 100644 --- a/hvirtual/cinelerra/edl.C +++ b/hvirtual/cinelerra/edl.C @@ -39,6 +39,7 @@ EDL::EDL(EDL *parent_edl) new_folder(CLIP_FOLDER); new_folder(MEDIA_FOLDER); id = next_id(); + project_path[0] = 0; } @@ -163,7 +164,7 @@ int EDL::load_xml(ArrayList *plugindb, // The parent_edl test is required to make EDL loading work because // when loading an EDL the EDL tag is already read by the parent. - if(!parent_edl /* && (load_flags & LOAD_ALL) == LOAD_ALL */) + if(!parent_edl) { do{ result = file->read_tag(); @@ -174,6 +175,10 @@ int EDL::load_xml(ArrayList *plugindb, if(!result) { +// Get path for backups + project_path[0] = 0; + file->tag.get_property("PROJECT_PATH", project_path); + // Erase everything if((load_flags & LOAD_ALL) == LOAD_ALL || (load_flags & LOAD_EDITS) == LOAD_EDITS) @@ -371,6 +376,8 @@ void EDL::copy_assets(EDL *edl) void EDL::copy_session(EDL *edl) { + strcpy(this->project_path, edl->project_path); + folders.remove_all_objects(); for(int i = 0; i < edl->folders.total; i++) { @@ -461,7 +468,14 @@ int EDL::copy(double start, if(is_vwindow) file->tag.set_title("VWINDOW_EDL"); else + { file->tag.set_title("EDL"); +// Save path for restoration of the project title from a backup. + if(this->project_path[0]) + { + file->tag.set_property("PROJECT_PATH", project_path); + } + } file->append_tag(); file->append_newline(); @@ -651,6 +665,11 @@ double EDL::equivalent_output(EDL *edl) } +void EDL::set_project_path(char *path) +{ + strcpy(this->project_path, path); +} + void EDL::set_inpoint(double position) { if(equivalent(local_session->in_point, position) && local_session->in_point >= 0) diff --git a/hvirtual/cinelerra/edl.h b/hvirtual/cinelerra/edl.h index c18dfb82..a36eebcb 100644 --- a/hvirtual/cinelerra/edl.h +++ b/hvirtual/cinelerra/edl.h @@ -95,6 +95,8 @@ public: // If they're completely equivalent, -1 is returned; // This is used by BRender. double equivalent_output(EDL *edl); +// Set project path for saving a backup + void set_project_path(char *path); // Set points and labels void set_inpoint(double position); void set_outpoint(double position); @@ -195,11 +197,17 @@ public: Tracks *tracks; Labels *labels; Presentations *presentations; -// Shared between all EDLs in a tree +// Shared between all EDLs in a tree, for projects. EDLSession *session; -// Specific to this EDL +// Specific to this EDL, for clips. LocalSession *local_session; +// In the top EDL, this is the path it was loaded from. Restores +// project titles from backups. This is only used for loading backups. +// All other loads keep the path in mainsession->filename. +// This can't use the output_path argument to save_xml because that points +// to the backup file, not the project file. + char project_path[BCTEXTLEN]; diff --git a/hvirtual/cinelerra/edlsession.C b/hvirtual/cinelerra/edlsession.C index 3c558cb2..c07a9410 100644 --- a/hvirtual/cinelerra/edlsession.C +++ b/hvirtual/cinelerra/edlsession.C @@ -18,19 +18,14 @@ EDLSession::EDLSession(EDL *edl) highlighted_track = 0; playback_cursor_visible = 0; aconfig_in = new AudioInConfig; - aconfig_duplex = new AudioOutConfig(PLAYBACK_LOCALHOST, 0, 1); + aconfig_duplex = new AudioOutConfig(1); vconfig_in = new VideoInConfig; - playback_strategy = PLAYBACK_LOCALHOST; interpolation_type = CUBIC_LINEAR; test_playback_edits = 1; brender_start = 0.0; mpeg4_deblock = 1; - for(int i = 0; i < PLAYBACK_STRATEGIES; i++) - { - PlaybackConfig *config = new PlaybackConfig(i, 0); - playback_config[i].append(config); - } + playback_config = new PlaybackConfig; auto_conf = new AutoConf; vwindow_folder[0] = 0; } @@ -41,41 +36,20 @@ EDLSession::~EDLSession() delete aconfig_duplex; delete auto_conf; delete vconfig_in; - for(int i = 0; i < PLAYBACK_STRATEGIES; i++) - { - for(int j = 0; j < playback_config[i].total; j++) - delete playback_config[i].values[j]; - playback_config[i].remove_all(); - } + delete playback_config; } char* EDLSession::get_cwindow_display() { - if(playback_config[PLAYBACK_LOCALHOST].values[0]->vconfig->x11_host[0]) - return playback_config[PLAYBACK_LOCALHOST].values[0]->vconfig->x11_host; + if(playback_config->vconfig->x11_host[0]) + return playback_config->vconfig->x11_host; else return 0; } -PlaybackConfig* EDLSession::get_playback_config(int strategy, int head) -{ - return playback_config[strategy].values[head]; -} - -ArrayList* EDLSession::get_playback_config(int strategy) -{ - return &playback_config[strategy]; -} - -int EDLSession::get_playback_heads(int strategy) -{ - return playback_config[strategy].total; -} - - void EDLSession::equivalent_output(EDLSession *session, double *result) { if(session->output_w != output_w || @@ -165,27 +139,17 @@ int EDLSession::load_defaults(Defaults *defaults) plugins_follow_edits = defaults->get("PLUGINS_FOLLOW_EDITS", 1); auto_keyframes = defaults->get("AUTO_KEYFRAMES", 0); meter_format = defaults->get("METER_FORMAT", METER_DB); - min_meter_db = defaults->get("MIN_METER_DB", (float)-85); + min_meter_db = defaults->get("MIN_METER_DB", -85); + max_meter_db = defaults->get("MAX_METER_DB", 6); mpeg4_deblock = defaults->get("MPEG4_DEBLOCK", mpeg4_deblock); output_w = defaults->get("OUTPUTW", 720); output_h = defaults->get("OUTPUTH", 480); playback_buffer = defaults->get("PLAYBACK_BUFFER", 4096); playback_preload = defaults->get("PLAYBACK_PRELOAD", 0); playback_software_position = defaults->get("PLAYBACK_SOFTWARE_POSITION", 0); - playback_strategy = defaults->get("PLAYBACK_STRATEGY", playback_strategy); - for(int i = 0; i < 1 /* PLAYBACK_STRATEGIES */; i++) - { - playback_config[i].remove_all_objects(); - - sprintf(string, "PLAYBACK_CONFIGS_%d", i); - int playback_configs = defaults->get(string, 1); - for(int j = 0; j < playback_configs; j++) - { - PlaybackConfig *config = new PlaybackConfig(i, j); - playback_config[i].append(config); - config->load_defaults(defaults); - } - } + delete playback_config; + playback_config = new PlaybackConfig; + playback_config->load_defaults(defaults); real_time_playback = defaults->get("PLAYBACK_REALTIME", 0); real_time_record = defaults->get("REALTIME_RECORD", 0); record_software_position = defaults->get("RECORD_SOFTWARE_POSITION", 1); @@ -219,6 +183,7 @@ int EDLSession::load_defaults(Defaults *defaults) vwindow_folder[0] = 0; vwindow_source = -1; vwindow_zoom = defaults->get("VWINDOW_ZOOM", (float)1); + boundaries(); return 0; } @@ -283,22 +248,14 @@ int EDLSession::save_defaults(Defaults *defaults) defaults->update("AUTO_KEYFRAMES", auto_keyframes); defaults->update("METER_FORMAT", meter_format); defaults->update("MIN_METER_DB", min_meter_db); + defaults->update("MAX_METER_DB", max_meter_db); defaults->update("MPEG4_DEBLOCK", mpeg4_deblock); defaults->update("OUTPUTW", output_w); defaults->update("OUTPUTH", output_h); defaults->update("PLAYBACK_BUFFER", playback_buffer); defaults->update("PLAYBACK_PRELOAD", playback_preload); defaults->update("PLAYBACK_SOFTWARE_POSITION", playback_software_position); - defaults->update("PLAYBACK_STRATEGY", playback_strategy); - for(int i = 0; i < 1 /* PLAYBACK_STRATEGIES */; i++) - { - sprintf(string, "PLAYBACK_CONFIGS_%d", i); - defaults->update(string, (int32_t)playback_config[i].total); - for(int j = 0; j < playback_config[i].total; j++) - { - playback_config[i].values[j]->save_defaults(defaults); - } - } + playback_config->save_defaults(defaults); defaults->update("PLAYBACK_REALTIME", real_time_playback); defaults->update("REALTIME_RECORD", real_time_record); defaults->update("RECORD_SOFTWARE_POSITION", record_software_position); @@ -346,7 +303,8 @@ void EDLSession::boundaries() Workarounds::clamp(video_tracks, 0, (int)BC_INFINITY); Workarounds::clamp(video_channels, 1, MAXCHANNELS - 1); Workarounds::clamp(frame_rate, 1.0, (double)BC_INFINITY); - Workarounds::clamp(min_meter_db, -100, -1); + Workarounds::clamp(min_meter_db, -80, -20); + Workarounds::clamp(max_meter_db, 0, 10); Workarounds::clamp(frames_per_foot, 1, 32); Workarounds::clamp(output_w, 16, (int)BC_INFINITY); Workarounds::clamp(output_h, 16, (int)BC_INFINITY); @@ -472,6 +430,7 @@ int EDLSession::load_xml(FileXML *file, file->tag.get_property("VWINDOW_FOLDER", vwindow_folder); vwindow_source = file->tag.get_property("VWINDOW_SOURCE", vwindow_source); vwindow_zoom = file->tag.get_property("VWINDOW_ZOOM", vwindow_zoom); + boundaries(); } return 0; @@ -587,15 +546,15 @@ int EDLSession::copy(EDLSession *session) { achannel_positions[i] = session->achannel_positions[i]; } - *aconfig_duplex = *session->aconfig_duplex; - *aconfig_in = *session->aconfig_in; + aconfig_duplex->copy_from(session->aconfig_duplex); + aconfig_in->copy_from(session->aconfig_in); actual_frame_rate = session->actual_frame_rate; for(int i = 0; i < ASSET_COLUMNS; i++) { asset_columns[i] = session->asset_columns[i]; } assetlist_format = session->assetlist_format; - *auto_conf = *session->auto_conf; + auto_conf->copy_from(session->auto_conf); aspect_w = session->aspect_w; aspect_h = session->aspect_h; audio_channels = session->audio_channels; @@ -636,24 +595,17 @@ int EDLSession::copy(EDLSession *session) // last_playback_position = session->last_playback_position; meter_format = session->meter_format; min_meter_db = session->min_meter_db; + max_meter_db = session->max_meter_db; mpeg4_deblock = session->mpeg4_deblock; output_w = session->output_w; output_h = session->output_h; playback_buffer = session->playback_buffer; - for(int i = 0; i < PLAYBACK_STRATEGIES; i++) - { - playback_config[i].remove_all_objects(); - for(int j = 0; j < session->playback_config[i].total; j++) - { - PlaybackConfig *config; - playback_config[i].append(config = new PlaybackConfig(i, j)); - *config = *session->playback_config[i].values[j]; - } - } + delete playback_config; + playback_config = new PlaybackConfig; + playback_config->copy_from(session->playback_config); playback_cursor_visible = session->playback_cursor_visible; playback_preload = session->playback_preload; playback_software_position = session->playback_software_position; - playback_strategy = session->playback_strategy; real_time_playback = session->real_time_playback; real_time_record = session->real_time_record; record_software_position = session->record_software_position; diff --git a/hvirtual/cinelerra/edlsession.h b/hvirtual/cinelerra/edlsession.h index 593bc45e..c930e0fe 100644 --- a/hvirtual/cinelerra/edlsession.h +++ b/hvirtual/cinelerra/edlsession.h @@ -31,9 +31,9 @@ public: char* get_cwindow_display(); void boundaries(); - PlaybackConfig* get_playback_config(int strategy, int head); - ArrayList* get_playback_config(int strategy); - int get_playback_heads(int strategy); +// PlaybackConfig* get_playback_config(int strategy, int head); +// ArrayList* get_playback_config(int strategy); +// int get_playback_heads(int strategy); void equivalent_output(EDLSession *session, double *result); void dump(); @@ -107,14 +107,15 @@ public: int mpeg4_deblock; int plugins_follow_edits; int meter_format; - float min_meter_db; + int min_meter_db; + int max_meter_db; int output_w; int output_h; int64_t playback_buffer; int playback_cursor_visible; int64_t playback_preload; int playback_software_position; - int playback_strategy; +// int playback_strategy; // Play audio in realtime priority int real_time_playback; int real_time_record; @@ -161,13 +162,14 @@ public: float vwindow_zoom; // Global ID counter static int current_id; + PlaybackConfig* playback_config; private: // Global playback. This is loaded from defaults but not from XML probably // because it was discovered to be the most convenient. // It is part of the EDL probably because the playback setting was // going to be bound to the EDL. - ArrayList playback_config[PLAYBACK_STRATEGIES]; +// ArrayList playback_config[PLAYBACK_STRATEGIES]; }; diff --git a/hvirtual/cinelerra/fadeengine.C b/hvirtual/cinelerra/fadeengine.C index fbd7006a..37d1a01e 100644 --- a/hvirtual/cinelerra/fadeengine.C +++ b/hvirtual/cinelerra/fadeengine.C @@ -22,11 +22,18 @@ FadeUnit::~FadeUnit() } -#define APPLY_FADE(equivalent, input_rows, output_rows, max, type, int_type, chroma_zero, components) \ +#define APPLY_FADE(equivalent, \ + input_rows, \ + output_rows, \ + max, \ + type, \ + temp_type, \ + chroma_zero, \ + components) \ { \ - int_type opacity = (int_type)(alpha * max); \ - int_type transparency = (int_type)(max - opacity); \ - int_type product = (int_type) (chroma_zero * transparency); \ + temp_type opacity = (temp_type)(alpha * max); \ + temp_type transparency = (temp_type)(max - opacity); \ + temp_type product = (temp_type) (chroma_zero * transparency); \ \ for(int i = row1; i < row2; i++) \ { \ @@ -38,12 +45,12 @@ FadeUnit::~FadeUnit() if(components == 3) \ { \ out_row[0] = \ - (type)((int_type)in_row[0] * opacity / max); \ + (type)((temp_type)in_row[0] * opacity / max); \ out_row[1] = \ - (type)(((int_type)in_row[1] * opacity + \ + (type)(((temp_type)in_row[1] * opacity + \ product) / max); \ out_row[2] = \ - (type)(((int_type)in_row[2] * opacity + \ + (type)(((temp_type)in_row[2] * opacity + \ product) / max); \ } \ else \ @@ -59,7 +66,7 @@ FadeUnit::~FadeUnit() out_row[3] = opacity; \ else \ out_row[3] = \ - (type)((int_type)in_row[3] * opacity / max); \ + (type)((temp_type)in_row[3] * opacity / max); \ } \ } \ } \ @@ -89,6 +96,12 @@ void FadeUnit::process_package(LoadPackage *package) case BC_RGBA8888: APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 4); break; + case BC_RGB_FLOAT: + APPLY_FADE(1, out_rows, in_rows, 1.0, float, float, 0x0, 3); + break; + case BC_RGBA_FLOAT: + APPLY_FADE(1, out_rows, in_rows, 1.0, float, float, 0x0, 4); + break; case BC_RGB161616: APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 3); break; @@ -119,6 +132,12 @@ void FadeUnit::process_package(LoadPackage *package) case BC_RGBA8888: APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 4); break; + case BC_RGB_FLOAT: + APPLY_FADE(0, out_rows, in_rows, 1.0, float, float, 0x0, 3); + break; + case BC_RGBA_FLOAT: + APPLY_FADE(0, out_rows, in_rows, 1.0, float, float, 0x0, 4); + break; case BC_RGB161616: APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 3); break; diff --git a/hvirtual/cinelerra/file.C b/hvirtual/cinelerra/file.C index 0cc962a0..6eb29e39 100644 --- a/hvirtual/cinelerra/file.C +++ b/hvirtual/cinelerra/file.C @@ -9,6 +9,7 @@ #include "fileac3.h" #include "fileavi.h" #include "filebase.h" +#include "fileexr.h" #include "filexml.h" #include "filejpeg.h" #include "filemov.h" @@ -51,7 +52,7 @@ File::~File() if(temp_frame) delete temp_frame; - close_file(); + close_file(0); reset_parameters(); delete asset; delete format_completion; @@ -170,6 +171,14 @@ int File::get_options(BC_WindowBase *parent_window, audio_options, video_options); break; + case FILE_EXR: + case FILE_EXR_LIST: + FileEXR::get_parameters(parent_window, + asset, + format_window, + audio_options, + video_options); + break; case FILE_PNG: case FILE_PNG_LIST: FilePNG::get_parameters(parent_window, @@ -208,8 +217,8 @@ int File::get_options(BC_WindowBase *parent_window, if(!format_window) { ErrorBox *errorbox = new ErrorBox(PROGRAM_NAME ": Error", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y()); + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1)); format_window = errorbox; getting_options = 1; if(audio_options) @@ -319,6 +328,13 @@ int File::open_file(ArrayList *plugindb, file = new FileJPEG(this->asset, this); } else + if(FileEXR::check_sig(this->asset, test)) + { +// JPEG file + fclose(stream); + file = new FileEXR(this->asset, this); + } + else if(FileTGA::check_sig(this->asset)) { // TGA file @@ -395,6 +411,11 @@ int File::open_file(ArrayList *plugindb, file = new FileJPEG(this->asset, this); break; + case FILE_EXR: + case FILE_EXR_LIST: + file = new FileEXR(this->asset, this); + break; + case FILE_TGA_LIST: case FILE_TGA: file = new FileTGA(this->asset, this); @@ -697,6 +718,7 @@ int File::set_video_position(int64_t position, float base_framerate) asset->frame_rate + 0.5); + if(current_frame != position && file) { current_frame = position; @@ -864,6 +886,7 @@ int File::read_frame(VFrame *frame) if(file) { int supported_colormodel = colormodel_supported(frame->get_color_model()); + int advance_position = 1; // Test cache @@ -872,7 +895,8 @@ int File::read_frame(VFrame *frame) current_frame, asset->frame_rate)) { - ; +// Can't advance position if cache used. + advance_position = 0; } else // Need temp @@ -881,6 +905,8 @@ int File::read_frame(VFrame *frame) frame->get_w() != asset->width || frame->get_h() != asset->height)) { + +// Can't advance position here because it needs to be added to cache if(temp_frame) { if(!temp_frame->params_match(asset->width, asset->height, supported_colormodel)) @@ -923,14 +949,16 @@ int File::read_frame(VFrame *frame) } else { +// Can't advance position here because it needs to be added to cache file->read_frame(frame); } + if(use_cache) frame_cache->put_frame(frame, current_frame, asset->frame_rate, 1); - current_frame++; + if(advance_position) current_frame++; return 0; } else @@ -983,6 +1011,10 @@ int File::strtoformat(ArrayList *plugindb, char *format) else if(!strcasecmp(format, _(JPEG_LIST_NAME))) return FILE_JPEG_LIST; else + if(!strcasecmp(format, _(EXR_NAME))) return FILE_EXR; + else + if(!strcasecmp(format, _(EXR_LIST_NAME))) return FILE_EXR_LIST; + else if(!strcasecmp(format, _(MPEG_NAME))) return FILE_MPEG; else if(!strcasecmp(format, _(AMPEG_NAME))) return FILE_AMPEG; @@ -1049,6 +1081,12 @@ char* File::formattostr(ArrayList *plugindb, int format) case FILE_JPEG_LIST: return _(JPEG_LIST_NAME); break; + case FILE_EXR: + return _(EXR_NAME); + break; + case FILE_EXR_LIST: + return _(EXR_LIST_NAME); + break; case FILE_MPEG: return _(MPEG_NAME); break; @@ -1211,6 +1249,11 @@ int File::get_best_colormodel(Asset *asset, int driver) return FileJPEG::get_best_colormodel(asset, driver); break; + case FILE_EXR: + case FILE_EXR_LIST: + return FileEXR::get_best_colormodel(asset, driver); + break; + case FILE_PNG: case FILE_PNG_LIST: return FilePNG::get_best_colormodel(asset, driver); @@ -1276,6 +1319,8 @@ int File::supports_video(int format) case FILE_MOV: case FILE_JPEG: case FILE_JPEG_LIST: + case FILE_EXR: + case FILE_EXR_LIST: case FILE_PNG: case FILE_PNG_LIST: case FILE_TGA: diff --git a/hvirtual/cinelerra/file.inc b/hvirtual/cinelerra/file.inc index 02429371..d9924ce0 100644 --- a/hvirtual/cinelerra/file.inc +++ b/hvirtual/cinelerra/file.inc @@ -36,6 +36,8 @@ #define FILE_VMPEG 17 // For encoding only #define FILE_VORBIS 18 #define FILE_WAV 2 +#define FILE_EXR 26 +#define FILE_EXR_LIST 27 // For formats supported by plugins, the format number is the plugin number in the // plugin list ORed with 0x8000. @@ -65,6 +67,8 @@ N_("TIFF") N_("TIFF Sequence") N_("MPEG Video") // For encoding only N_("OGG Vorbis") +N_("EXR") +N_("EXR List") #endif #define AC3_NAME "AC3" @@ -91,6 +95,8 @@ N_("OGG Vorbis") #define TIFF_LIST_NAME "TIFF Sequence" #define VMPEG_NAME "MPEG Video" // For encoding only #define VORBIS_NAME "OGG Vorbis" +#define EXR_NAME "EXR" +#define EXR_LIST_NAME "EXR List" #define BITSLINEAR8 8 #define BITSLINEAR16 16 diff --git a/hvirtual/cinelerra/fileavi.C b/hvirtual/cinelerra/fileavi.C index 05b5aff9..2090f141 100644 --- a/hvirtual/cinelerra/fileavi.C +++ b/hvirtual/cinelerra/fileavi.C @@ -720,8 +720,8 @@ int FileAVI::write_samples(double **buffer, int64_t len) AVIConfigAudio::AVIConfigAudio(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Audio compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), calculate_w(asset->format), calculate_h(asset->format)) { @@ -852,8 +852,8 @@ AVIConfigVideo::AVIConfigVideo(BC_WindowBase *parent_window, Asset *asset, int lock_compressor) : BC_Window(PROGRAM_NAME ": Video Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), calculate_w(asset->format), calculate_h(asset->format)) { diff --git a/hvirtual/cinelerra/fileformat.C b/hvirtual/cinelerra/fileformat.C index 9b443415..7cb8274d 100644 --- a/hvirtual/cinelerra/fileformat.C +++ b/hvirtual/cinelerra/fileformat.C @@ -13,8 +13,8 @@ FileFormat::FileFormat(MWindow *mwindow) : BC_Window(PROGRAM_NAME ": File Format", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), 375, 300, 375, diff --git a/hvirtual/cinelerra/filejpeg.C b/hvirtual/cinelerra/filejpeg.C index 659e1b9a..2b0acb32 100644 --- a/hvirtual/cinelerra/filejpeg.C +++ b/hvirtual/cinelerra/filejpeg.C @@ -204,11 +204,9 @@ int FileJPEG::read_frame_header(char *path) int FileJPEG::read_frame(VFrame *output, VFrame *input) { -//printf("FileJPEG::read_frame 1\n"); if(!decompressor) decompressor = mjpeg_new(asset->width, asset->height, 1); -//printf("FileJPEG::read_frame 1\n"); mjpeg_decompress((mjpeg_t*)decompressor, input->get_data(), input->get_compressed_size(), @@ -219,8 +217,6 @@ int FileJPEG::read_frame(VFrame *output, VFrame *input) output->get_v(), output->get_color_model(), 1); -//printf("FileJPEG::read_frame 1\n"); -//printf("FileJPEG::read_frame 2\n"); return 0; @@ -255,8 +251,8 @@ JPEGUnit::~JPEGUnit() JPEGConfigVideo::JPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Video Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 400, 100) { diff --git a/hvirtual/cinelerra/filelist.C b/hvirtual/cinelerra/filelist.C index f5099742..60914db3 100644 --- a/hvirtual/cinelerra/filelist.C +++ b/hvirtual/cinelerra/filelist.C @@ -1,4 +1,5 @@ #include "asset.h" +#include "bcsignals.h" #include "file.h" #include "filelist.h" #include "guicast.h" @@ -28,7 +29,7 @@ FileList::FileList(Asset *asset, this->file_extension = file_extension; this->frame_type = frame_type; this->list_type = list_type; - table_lock = new Mutex; + table_lock = new Mutex("FileList::table_lock"); } FileList::~FileList() @@ -292,14 +293,12 @@ int FileList::read_frame(VFrame *frame) else { -//printf("FileList::read_frame 1\n"); // Allocate and decompress once into temporary if(!temp || temp->get_color_model() != frame->get_color_model()) { if(temp) delete temp; temp = 0; -//printf("FileList::read_frame 2\n"); FILE *fd = fopen(asset->path, "rb"); if(fd) { @@ -325,7 +324,6 @@ int FileList::read_frame(VFrame *frame) break; } -//printf("FileList::read_frame 3\n"); fclose(fd); } else @@ -335,7 +333,6 @@ int FileList::read_frame(VFrame *frame) } } -//printf("FileList::read_frame 4\n"); if(!temp) return result; if(frame->get_color_model() == temp->get_color_model()) @@ -380,6 +377,7 @@ int FileList::write_frames(VFrame ***frames, int len) { return_value = 0; +//printf("FileList::write_frames 1\n"); if(frames[0][0]->get_color_model() == BC_COMPRESSED) { for(int i = 0; i < asset->layers && !return_value; i++) @@ -408,7 +406,9 @@ int FileList::write_frames(VFrame ***frames, int len) } else { +//printf("FileList::write_frames 2\n"); writer->write_frames(frames, len); +//printf("FileList::write_frames 100\n"); } return return_value; } @@ -423,7 +423,7 @@ int FileList::write_frames(VFrame ***frames, int len) void FileList::add_return_value(int amount) { - table_lock->lock(); + table_lock->lock("FileList::add_return_value"); return_value += amount; table_lock->unlock(); } @@ -461,7 +461,7 @@ char* FileList::create_path(int number_override) { if(asset->format != list_type) return asset->path; - table_lock->lock(); + table_lock->lock("FileList::create_path"); @@ -511,6 +511,16 @@ int FileList::get_memory_usage() return result; } +int FileList::get_units() +{ + if(writer) return writer->get_total_clients(); + return 0; +} + +FrameWriterUnit* FileList::get_unit(int number) +{ + if(writer) return (FrameWriterUnit*)writer->get_client(number); +} @@ -551,11 +561,12 @@ FrameWriterUnit::~FrameWriterUnit() void FrameWriterUnit::process_package(LoadPackage *package) { +//printf("FrameWriterUnit::process_package 1\n"); FrameWriterPackage *ptr = (FrameWriterPackage*)package; FILE *file; -//printf("FrameWriterUnit::process_package 1 %s\n", ptr->path); +//printf("FrameWriterUnit::process_package 2 %s\n", ptr->path); if(!(file = fopen(ptr->path, "wb"))) { printf("FrameWriterUnit::process_package %s: %s\n", @@ -563,14 +574,19 @@ void FrameWriterUnit::process_package(LoadPackage *package) strerror(errno)); return; } - - +//printf("FrameWriterUnit::process_package 3"); + + int result = server->file->write_frame(ptr->input, output, this); +//printf("FrameWriterUnit::process_package 4"); if(!result) result = !fwrite(output->get_data(), output->get_compressed_size(), 1, file); +//TRACE("FrameWriterUnit::process_package 4"); fclose(file); - +//TRACE("FrameWriterUnit::process_package 5"); + server->file->add_return_value(result); +//TRACE("FrameWriterUnit::process_package 6"); } diff --git a/hvirtual/cinelerra/filelist.h b/hvirtual/cinelerra/filelist.h index a3fb7907..a3af682b 100644 --- a/hvirtual/cinelerra/filelist.h +++ b/hvirtual/cinelerra/filelist.h @@ -47,7 +47,11 @@ public: int write_list_header(); int write_frames(VFrame ***frames, int len); VFrame* read_frame(int use_alpha, int use_float); - int get_memory_usage(); + virtual int get_memory_usage(); +// Get the total writer units for calculating memory usage + int get_units(); +// Get a writer unit for retrieving temporary usage. + FrameWriterUnit* get_unit(int number); virtual FrameWriterUnit* new_writer_unit(FrameWriter *writer); diff --git a/hvirtual/cinelerra/filemov.C b/hvirtual/cinelerra/filemov.C index 3e434621..3a280637 100644 --- a/hvirtual/cinelerra/filemov.C +++ b/hvirtual/cinelerra/filemov.C @@ -42,6 +42,8 @@ N_("MP3") #endif #define DIVX_NAME "MPEG-4" +#define MP4V_NAME "MPEG-4 Video" +#define H263_NAME "H.263" #define HV60_NAME "Heroine 60" #define DIV3_NAME "Microsoft MPEG-4" #define DV_NAME "DV" @@ -378,6 +380,8 @@ int FileMOV::get_best_colormodel(Asset *asset, int driver) if(match4(asset->vcodec, QUICKTIME_DV)) return BC_YUV422; if(match4(asset->vcodec, QUICKTIME_HV60)) return BC_YUV420P; if(match4(asset->vcodec, QUICKTIME_DIVX)) return BC_YUV420P; + if(match4(asset->vcodec, QUICKTIME_MP4V)) return BC_YUV420P; + if(match4(asset->vcodec, QUICKTIME_H263)) return BC_YUV420P; if(match4(asset->vcodec, QUICKTIME_DIV3)) return BC_YUV420P; break; case PLAYBACK_DV1394: @@ -408,6 +412,8 @@ int FileMOV::get_best_colormodel(Asset *asset, int driver) else if(!strncasecmp(asset->vcodec, QUICKTIME_DIVX, 4)) return BC_YUV420P; else + if(!strncasecmp(asset->vcodec, QUICKTIME_H263, 4)) return BC_YUV420P; + else if(!strncasecmp(asset->vcodec, QUICKTIME_DIV3, 4)) return BC_YUV420P; break; case CAPTURE_BUZ: @@ -557,6 +563,7 @@ int FileMOV::write_samples(double **buffer, int64_t len) int FileMOV::write_frames(VFrame ***frames, int len) { +//printf("FileMOV::write_frames 1\n"); int i, j, k, result = 0; int default_compressor = 1; if(!fd) return 0; @@ -582,6 +589,7 @@ int FileMOV::write_frames(VFrame ***frames, int len) // Determine keyframe status. // Write VOL header in the first frame if none exists if(!strcmp(asset->vcodec, QUICKTIME_DIVX) || + !strcmp(asset->vcodec, QUICKTIME_H263) || !strcmp(asset->vcodec, QUICKTIME_HV60)) { if(quicktime_mpeg4_is_key(frame->get_data(), @@ -601,7 +609,7 @@ int FileMOV::write_frames(VFrame ***frames, int len) int bytes = quicktime_mpeg4_write_vol(temp_frame->get_data(), asset->width, asset->height, - 30000, + 60000, asset->frame_rate); memcpy(temp_frame->get_data() + bytes, frame->get_data(), @@ -641,6 +649,7 @@ int FileMOV::write_frames(VFrame ***frames, int len) if(!strcmp(asset->vcodec, QUICKTIME_MJPA)) { long field2_offset; + // Create extra space for markers if(frame->get_compressed_allocated() - frame->get_compressed_size() < 0x100) frame->allocate_compressed_data(frame->get_compressed_size() + 0x100); @@ -698,7 +707,6 @@ int FileMOV::write_frames(VFrame ***frames, int len) VFrame *frame = frames[i][j]; //printf("FileMOV::write_frames 1 %d\n", frame->get_color_model()); quicktime_set_cmodel(fd, frame->get_color_model()); -//printf("FileMOV::write_frames 1 %d\n", cmodel_is_planar(frame->get_color_model())); if(cmodel_is_planar(frame->get_color_model())) { unsigned char *planes[3]; @@ -792,15 +800,11 @@ int FileMOV::write_frames(VFrame ***frames, int len) planes[0] = frame->get_y(); planes[1] = frame->get_u(); planes[2] = frame->get_v(); -//printf("FileMOV::write_frames 6\n"); result = quicktime_encode_video(fd, planes, i); -//printf("FileMOV::write_frames 7\n"); } else { -//printf("FileMOV::write_frames 8\n"); result = quicktime_encode_video(fd, frame->get_rows(), i); -//printf("FileMOV::write_frames 9\n"); } } } @@ -808,6 +812,7 @@ int FileMOV::write_frames(VFrame ***frames, int len) } +//printf("FileMOV::write_frames 100\n"); return result; } @@ -818,7 +823,6 @@ int FileMOV::read_frame(VFrame *frame) if(!fd) return 1; int result = 0; -//printf("FileMOV::read_frame 1\n"); switch(frame->get_color_model()) { case BC_COMPRESSED: @@ -848,7 +852,6 @@ int FileMOV::read_frame(VFrame *frame) // Packed default: quicktime_set_cmodel(fd, frame->get_color_model()); -//printf("FileMOV::read_frame 100 %p %p\n", frame->get_color_model(), frame->get_rows()[0]); result = quicktime_decode_video(fd, frame->get_rows(), file->current_layer); @@ -858,7 +861,6 @@ int FileMOV::read_frame(VFrame *frame) -//printf("FileMOV::read_frame 100\n"); return result; } @@ -979,6 +981,8 @@ int FileMOV::read_samples(double *buffer, int64_t len) char* FileMOV::strtocompression(char *string) { if(!strcasecmp(string, _(DIVX_NAME))) return QUICKTIME_DIVX; + if(!strcasecmp(string, _(MP4V_NAME))) return QUICKTIME_MP4V; + if(!strcasecmp(string, _(H263_NAME))) return QUICKTIME_H263; if(!strcasecmp(string, _(HV60_NAME))) return QUICKTIME_HV60; if(!strcasecmp(string, _(DIV3_NAME))) return QUICKTIME_DIV3; if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DV; @@ -1009,7 +1013,9 @@ char* FileMOV::strtocompression(char *string) char* FileMOV::compressiontostr(char *string) { + if(match4(string, QUICKTIME_H263)) return _(H263_NAME); if(match4(string, QUICKTIME_DIVX)) return _(DIVX_NAME); + if(match4(string, QUICKTIME_MP4V)) return _(MP4V_NAME); if(match4(string, QUICKTIME_HV60)) return _(HV60_NAME); if(match4(string, QUICKTIME_DIV3)) return _(DIV3_NAME); if(match4(string, QUICKTIME_DV)) return _(DV_NAME); @@ -1186,8 +1192,8 @@ void FileMOVThread::run() MOVConfigAudio::MOVConfigAudio(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Audio Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 350, 250) { @@ -1453,8 +1459,8 @@ MOVConfigVideo::MOVConfigVideo(BC_WindowBase *parent_window, Asset *asset, int lock_compressor) : BC_Window(PROGRAM_NAME ": Video Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 420, 420) { @@ -1478,7 +1484,8 @@ int MOVConfigVideo::create_objects() if(asset->format == FILE_MOV) { - compression_items.append(new BC_ListBoxItem(_(DIVX_NAME))); +// compression_items.append(new BC_ListBoxItem(_(DIVX_NAME))); + compression_items.append(new BC_ListBoxItem(_(MP4V_NAME))); compression_items.append(new BC_ListBoxItem(_(HV60_NAME))); compression_items.append(new BC_ListBoxItem(_(DIV3_NAME))); compression_items.append(new BC_ListBoxItem(_(DV_NAME))); @@ -1649,6 +1656,7 @@ void MOVConfigVideo::update_parameters() else // OpenDivx parameters if(!strcmp(asset->vcodec, QUICKTIME_DIVX) || + !strcmp(asset->vcodec, QUICKTIME_H263) || !strcmp(asset->vcodec, QUICKTIME_HV60)) { int x = param_x, y = param_y; diff --git a/hvirtual/cinelerra/filempeg.C b/hvirtual/cinelerra/filempeg.C index c6d76773..eab84612 100644 --- a/hvirtual/cinelerra/filempeg.C +++ b/hvirtual/cinelerra/filempeg.C @@ -799,8 +799,8 @@ void FileMPEGAudio::run() MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Audio Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 310, 120, -1, @@ -986,8 +986,8 @@ char* MPEGABitrate::bitrate_to_string(char *string, int bitrate) MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Video Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 500, 300, -1, diff --git a/hvirtual/cinelerra/filepng.C b/hvirtual/cinelerra/filepng.C index a9048e8e..6ca6e5db 100644 --- a/hvirtual/cinelerra/filepng.C +++ b/hvirtual/cinelerra/filepng.C @@ -2,26 +2,21 @@ #include "edit.h" #include "file.h" #include "filepng.h" +#include "language.h" #include "mwindow.inc" #include "quicktime.h" #include "vframe.h" #include "videodevice.inc" #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) FilePNG::FilePNG(Asset *asset, File *file) : FileList(asset, file, "PNGLIST", ".png", FILE_PNG, FILE_PNG_LIST) { - temp = 0; } FilePNG::~FilePNG() { - if(temp) delete temp; } @@ -136,8 +131,20 @@ int FilePNG::read_frame_header(char *path) //printf("FilePNG::read_frame_header 1\n"); asset->width = png_get_image_width(png_ptr, info_ptr); asset->height = png_get_image_height(png_ptr, info_ptr); + int png_color_type = png_get_color_type(png_ptr, info_ptr); + +// gray to rgb conversion is done automatically in read_frame + switch (png_color_type) + { + case PNG_COLOR_TYPE_GRAY: + png_color_type = PNG_COLOR_TYPE_RGB; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_color_type = PNG_COLOR_TYPE_RGB_ALPHA; + break; + } native_cmodel = - png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB_ALPHA ? + png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ? BC_RGBA8888 : BC_RGB888; @@ -218,7 +225,10 @@ int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) native_cmodel = asset->png_use_alpha ? BC_RGBA8888 : BC_RGB888; if(frame->get_color_model() != native_cmodel) { - if(!png_unit->temp_frame) png_unit->temp_frame = new VFrame(0, asset->width, asset->height, native_cmodel); + if(!png_unit->temp_frame) png_unit->temp_frame = new VFrame(0, + asset->width, + asset->height, + native_cmodel); cmodel_transfer(png_unit->temp_frame->get_rows(), /* Leave NULL if non existent */ frame->get_rows(), @@ -274,7 +284,13 @@ int FilePNG::read_frame(VFrame *output, VFrame *input) info_ptr = png_create_info_struct(png_ptr); png_set_read_fn(png_ptr, input, (png_rw_ptr)read_function); png_read_info(png_ptr, info_ptr); -//printf("FilePNG::read_frame 2 %d\n", output->get_color_model()); + + int png_color_type = png_get_color_type(png_ptr, info_ptr); + if (png_color_type == PNG_COLOR_TYPE_GRAY || + png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + png_set_gray_to_rgb(png_ptr); + } /* read the image */ png_read_image(png_ptr, output->get_rows()); @@ -324,9 +340,9 @@ PNGUnit::~PNGUnit() PNGConfigVideo::PNGConfigVideo(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Video Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), - 400, + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), + 200, 100) { this->parent_window = parent_window; diff --git a/hvirtual/cinelerra/filesndfile.C b/hvirtual/cinelerra/filesndfile.C index 3938e0cc..2374a434 100644 --- a/hvirtual/cinelerra/filesndfile.C +++ b/hvirtual/cinelerra/filesndfile.C @@ -370,8 +370,8 @@ void FileSndFile::get_parameters(BC_WindowBase *parent_window, SndFileConfig::SndFileConfig(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Audio Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 250, 200) { diff --git a/hvirtual/cinelerra/filetga.C b/hvirtual/cinelerra/filetga.C index 938c2403..b5901b20 100644 --- a/hvirtual/cinelerra/filetga.C +++ b/hvirtual/cinelerra/filetga.C @@ -169,7 +169,7 @@ FrameWriterUnit* FileTGA::new_writer_unit(FrameWriter *writer) int FileTGA::get_memory_usage() { - int result = FileBase::get_memory_usage(); + int result = FileList::get_memory_usage(); if(temp) result += temp->get_data_size(); return result; } @@ -881,8 +881,8 @@ TGAUnit::~TGAUnit() TGAConfigVideo::TGAConfigVideo(BC_WindowBase *gui, Asset *asset) : BC_Window(PROGRAM_NAME ": Video Compression", - gui->get_abs_cursor_x(), - gui->get_abs_cursor_y(), + gui->get_abs_cursor_x(1), + gui->get_abs_cursor_y(1), 400, 100) { diff --git a/hvirtual/cinelerra/filethread.C b/hvirtual/cinelerra/filethread.C index fbbfd992..43268a07 100644 --- a/hvirtual/cinelerra/filethread.C +++ b/hvirtual/cinelerra/filethread.C @@ -108,15 +108,12 @@ TRACE("FileThread::run 5"); result = 0; if(compressed) { -TRACE("FileThread::run 6"); for(j = 0; j < file->asset->layers && !result; j++) for(i = 0; i < output_size[local_buffer] && !result; i++) result = file->write_compressed_frame(video_buffer[local_buffer][j][i]); -TRACE("FileThread::run 7"); } else { -//printf("FileThread::run 1 %d %p %p\n", local_buffer, video_buffer, video_buffer[local_buffer]); result = file->write_frames(video_buffer[local_buffer], output_size[local_buffer]); } @@ -156,7 +153,7 @@ int FileThread::stop_writing() swap_buffer(); // wait for thread to finish - join(); + Thread::join(); // delete buffers file_lock->lock("FileThread::stop_writing 2"); diff --git a/hvirtual/cinelerra/filetiff.C b/hvirtual/cinelerra/filetiff.C index fa7a5e5a..2b1043e8 100644 --- a/hvirtual/cinelerra/filetiff.C +++ b/hvirtual/cinelerra/filetiff.C @@ -2,15 +2,12 @@ #include "edit.h" #include "file.h" #include "filetiff.h" +#include "language.h" #include "vframe.h" #include #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) FileTIFF::FileTIFF(Asset *asset, File *file) : FileList(asset, file, "TIFFLIST", ".tif", FILE_TIFF, FILE_TIFF_LIST) @@ -66,6 +63,36 @@ int FileTIFF::check_sig(Asset *asset) return 0; } +char* FileTIFF::compression_to_str(int value) +{ + switch(value) + { + case FileTIFF::NONE: return "None"; break; + case FileTIFF::LZW: return "LZW"; break; + case FileTIFF::PACK_BITS: return "Pack Bits"; break; + case FileTIFF::DEFLATE: return "Deflate"; break; + case FileTIFF::JPEG: return "JPEG"; break; + default: + return "None"; + break; + } +} + +char* FileTIFF::cmodel_to_str(int value) +{ + switch(value) + { + case FileTIFF::RGB_888: return "RGB-8 Bit"; break; + case FileTIFF::RGBA_8888: return "RGBA-8 Bit"; break; + case FileTIFF::RGB_FLOAT: return "RGB-FLOAT"; break; + case FileTIFF::RGBA_FLOAT: return "RGBA-FLOAT"; break; + default: + return "RGB-8 Bit"; + break; + } +} + + int FileTIFF::can_copy_from(Edit *edit, int64_t position) { if(edit->asset->format == FILE_TIFF_LIST || @@ -75,8 +102,6 @@ int FileTIFF::can_copy_from(Edit *edit, int64_t position) return 0; } -#define TIFF_RGB "rgb " -#define TIFF_RGBA "rgba" int FileTIFF::read_frame_header(char *path) @@ -92,15 +117,26 @@ int FileTIFF::read_frame_header(char *path) TIFFGetField(stream, TIFFTAG_IMAGEWIDTH, &(asset->width)); TIFFGetField(stream, TIFFTAG_IMAGELENGTH, &(asset->height)); - int depth = 3; -// TIFFGetField(stream, TIFFTAG_IMAGEDEPTH, &depth); - TIFFGetField(stream, TIFFTAG_SAMPLESPERPIXEL, &depth); - if(depth == 3) - strcpy(asset->vcodec, TIFF_RGB); + int components = 0; + TIFFGetField(stream, TIFFTAG_SAMPLESPERPIXEL, &components); + int bitspersample = 0; + TIFFGetField(stream, TIFFTAG_BITSPERSAMPLE, &bitspersample); + int sampleformat = 0; + TIFFGetField(stream, TIFFTAG_SAMPLEFORMAT, &sampleformat); + + if(bitspersample == 8 && components == 3) + asset->tiff_cmodel = FileTIFF::RGB_888; + else + if(bitspersample == 8 && components == 4) + asset->tiff_cmodel = FileTIFF::RGBA_8888; else - strcpy(asset->vcodec, TIFF_RGBA); + if(bitspersample == 32 && components == 3) + asset->tiff_cmodel = FileTIFF::RGB_FLOAT; + else + if(bitspersample == 32 && components == 4) + asset->tiff_cmodel = FileTIFF::RGBA_FLOAT; -//printf("FileTIFF::read_frame_header 1 %d\n", depth); +//printf("%d %d %d\n", bitspersample, components, asset->tiff_cmodel); TIFFClose(stream); @@ -109,18 +145,26 @@ int FileTIFF::read_frame_header(char *path) int FileTIFF::colormodel_supported(int colormodel) { - if(!strcmp(asset->vcodec, TIFF_RGB)) - return BC_RGB888; - else - return BC_RGBA8888; + switch(asset->tiff_cmodel) + { + case FileTIFF::RGB_888: return BC_RGB888; break; + case FileTIFF::RGBA_8888: return BC_RGBA8888; break; + case FileTIFF::RGB_FLOAT: return BC_RGB_FLOAT; break; + case FileTIFF::RGBA_FLOAT: return BC_RGBA_FLOAT; break; + default: return BC_RGB888; break; + } } int FileTIFF::get_best_colormodel(Asset *asset, int driver) { - if(!strcmp(asset->vcodec, TIFF_RGB)) - return BC_RGB888; - else - return BC_RGBA8888; + switch(asset->tiff_cmodel) + { + case FileTIFF::RGB_888: return BC_RGB888; break; + case FileTIFF::RGBA_8888: return BC_RGBA8888; break; + case FileTIFF::RGB_FLOAT: return BC_RGB_FLOAT; break; + case FileTIFF::RGBA_FLOAT: return BC_RGBA_FLOAT; break; + default: return BC_RGB888; break; + } } @@ -137,7 +181,6 @@ static tsize_t tiff_read(thandle_t ptr, tdata_t buf, tsize_t size) static tsize_t tiff_write(thandle_t ptr, tdata_t buf, tsize_t size) { FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr; -//printf("tiff_write 1 %d\n", size); if(tiff_unit->data->get_compressed_allocated() < tiff_unit->offset + size) { tiff_unit->data->allocate_compressed_data((tiff_unit->offset + size) * 2); @@ -150,14 +193,12 @@ static tsize_t tiff_write(thandle_t ptr, tdata_t buf, tsize_t size) buf, size); tiff_unit->offset += size; -//printf("tiff_write 2\n"); return size; } static toff_t tiff_seek(thandle_t ptr, toff_t off, int whence) { FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr; -//printf("tiff_seek 1 %d %d\n", off, whence); switch(whence) { case SEEK_SET: @@ -170,7 +211,6 @@ static toff_t tiff_seek(thandle_t ptr, toff_t off, int whence) tiff_unit->offset = tiff_unit->data->get_compressed_size() + off; break; } -//printf("tiff_seek 2\n"); return tiff_unit->offset; } @@ -187,11 +227,9 @@ static toff_t tiff_size(thandle_t ptr) static int tiff_mmap(thandle_t ptr, tdata_t* pbase, toff_t* psize) { -//printf("tiff_mmap 1\n"); FileTIFFUnit *tiff_unit = (FileTIFFUnit*)ptr; *pbase = tiff_unit->data->get_data(); *psize = tiff_unit->data->get_compressed_size(); -//printf("tiff_mmap 10\n"); return 0; } @@ -217,21 +255,9 @@ int FileTIFF::read_frame(VFrame *output, VFrame *input) tiff_mmap, tiff_unmap); -//printf("FileTIFF::read_frame 1 %d\n", output->get_color_model()); - if(output->get_color_model() == BC_RGBA8888 || - output->get_color_model() == BC_RGB888) + for(int i = 0; i < asset->height; i++) { -//printf("FileTIFF::read_frame 2\n"); - for(int i = 0; i < asset->height; i++) - { - TIFFReadScanline(stream, output->get_rows()[i], i, 0); - } -//printf("FileTIFF::read_frame 4\n"); - } - else - { - printf("FileTIFF::read_frame color model = %d\n", - output->get_color_model()); + TIFFReadScanline(stream, output->get_rows()[i], i, 0); } TIFFClose(stream); @@ -249,9 +275,6 @@ int FileTIFF::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) tiff_unit->data = data; tiff_unit->data->set_compressed_size(0); -//printf("FileTIFF::write_frame 1\n"); - TIFFConfigVideo::fix_codec(asset->vcodec); -//printf("FileTIFF::write_frame 1\n"); stream = TIFFClientOpen("FileTIFF", "w", (void*)tiff_unit, @@ -263,42 +286,93 @@ int FileTIFF::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) tiff_mmap, tiff_unmap); -//printf("FileTIFF::write_frame 1\n"); - int depth, color_model; - if(!strcmp(asset->vcodec, TIFF_RGBA)) + int components, color_model, bits, type, compression; + int sampleformat = SAMPLEFORMAT_UINT; + int bytesperrow; + switch(asset->tiff_cmodel) { - depth = 32; - color_model = BC_RGBA8888; + case FileTIFF::RGB_888: + components = 3; + color_model = BC_RGB888; + bits = 8; + type = TIFF_BYTE; + bytesperrow = 3 * asset->width; + break; + case FileTIFF::RGBA_8888: + components = 4; + color_model = BC_RGBA8888; + bits = 8; + type = TIFF_BYTE; + bytesperrow = 4 * asset->width; + break; + case FileTIFF::RGB_FLOAT: + components = 3; + color_model = BC_RGB_FLOAT; + bits = 32; + type = TIFF_FLOAT; + sampleformat = SAMPLEFORMAT_IEEEFP; + bytesperrow = 12 * asset->width; + break; + case FileTIFF::RGBA_FLOAT: + components = 4; + color_model = BC_RGBA_FLOAT; + bits = 32; + type = TIFF_FLOAT; + sampleformat = SAMPLEFORMAT_IEEEFP; + bytesperrow = 16 * asset->width; + break; + default: + components = 3; + color_model = BC_RGB888; + bits = 8; + type = TIFF_BYTE; + bytesperrow = 3 * asset->width; + break; } - else + + + switch(asset->tiff_compression) { - depth = 24; - color_model = BC_RGB888; + case FileTIFF::LZW: + compression = COMPRESSION_LZW; + break; + case FileTIFF::PACK_BITS: + compression = COMPRESSION_PACKBITS; + break; + case FileTIFF::DEFLATE: + compression = COMPRESSION_DEFLATE; + break; + case FileTIFF::JPEG: + compression = COMPRESSION_JPEG; + break; + default: + compression = COMPRESSION_NONE; + break; } -//printf("FileTIFF::write_frame 1\n"); TIFFSetField(stream, TIFFTAG_IMAGEWIDTH, asset->width); TIFFSetField(stream, TIFFTAG_IMAGELENGTH, asset->height); TIFFSetField(stream, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(stream, TIFFTAG_SAMPLESPERPIXEL, depth / 8); - TIFFSetField(stream, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(stream, TIFFTAG_SAMPLESPERPIXEL, components); + TIFFSetField(stream, TIFFTAG_BITSPERSAMPLE, bits); + TIFFSetField(stream, TIFFTAG_SAMPLEFORMAT, sampleformat); + TIFFSetField(stream, TIFFTAG_COMPRESSION, compression); TIFFSetField(stream, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(stream, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(stream, (uint32_t)-1)); + TIFFSetField(stream, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(stream, (uint32_t)-1)); +// TIFFSetField(stream, TIFFTAG_ROWSPERSTRIP, +// (8 * 1024) / bytesperrow); TIFFSetField(stream, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); -//printf("FileTIFF::write_frame 1\n"); if(frame->get_color_model() == color_model) { for(int i = 0; i < asset->height; i++) { -//printf("FileTIFF::write_frame 2 %d\n", i); TIFFWriteScanline(stream, frame->get_rows()[i], i, 0); -//printf("FileTIFF::write_frame 3\n"); } } else { -//printf("FileTIFF::write_frame 2\n"); if(tiff_unit->temp && tiff_unit->temp->get_color_model() != color_model) { @@ -312,7 +386,7 @@ int FileTIFF::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) asset->height, color_model); } -//printf("FileTIFF::write_frame 3 %d %d\n", color_model, frame->get_color_model()); + cmodel_transfer(tiff_unit->temp->get_rows(), frame->get_rows(), tiff_unit->temp->get_y(), @@ -334,19 +408,13 @@ int FileTIFF::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit) 0, frame->get_w(), frame->get_w()); -//printf("FileTIFF::write_frame 5\n"); for(int i = 0; i < asset->height; i++) { TIFFWriteScanline(stream, tiff_unit->temp->get_rows()[i], i, 0); } -//printf("FileTIFF::write_frame 6\n"); } -//printf("FileTIFF::write_frame 7\n"); -//sleep(1); -//printf("FileTIFF::write_frame 71\n"); TIFFClose(stream); -//printf("FileTIFF::write_frame 8\n"); return result; } @@ -388,10 +456,10 @@ FileTIFFUnit::~FileTIFFUnit() TIFFConfigVideo::TIFFConfigVideo(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Video Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + 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; @@ -405,8 +473,15 @@ int TIFFConfigVideo::create_objects() { int x = 10, y = 10; - fix_codec(asset->vcodec); - add_subwindow(new TIFFConfigAlpha(this, x, y)); + add_subwindow(new BC_Title(x, y, "Colorspace:")); + TIFFColorspace *menu1; + add_subwindow(menu1 = new TIFFColorspace(this, x + 150, y, 200)); + menu1->create_objects(); + y += 40; + add_subwindow(new BC_Title(x, y, "Compression:")); + TIFFCompression *menu2; + add_subwindow(menu2 = new TIFFCompression(this, x + 150, y, 200)); + menu2->create_objects(); add_subwindow(new BC_OKButton(this)); return 0; @@ -418,49 +493,83 @@ int TIFFConfigVideo::close_event() return 1; } -char* TIFFConfigVideo::alpha_to_codec(int use_alpha) + + + + + +TIFFColorspace::TIFFColorspace(TIFFConfigVideo *gui, int x, int y, int w) + : BC_PopupMenu(x, + y, + w, + FileTIFF::cmodel_to_str(gui->asset->tiff_cmodel)) { - if(use_alpha) - return TIFF_RGBA; - else - return TIFF_RGB; + this->gui = gui; } - -int TIFFConfigVideo::codec_to_alpha(char *codec) +int TIFFColorspace::handle_event() { - if(!strcmp(codec, TIFF_RGBA)) - return 1; - else - return 0; + return 1; } - -void TIFFConfigVideo::fix_codec(char *codec) +void TIFFColorspace::create_objects() { - if(strcmp(codec, TIFF_RGB) && - strcmp(codec, TIFF_RGBA)) - strcpy(codec, TIFF_RGB); + add_item(new TIFFColorspaceItem(gui, FileTIFF::RGB_888)); + add_item(new TIFFColorspaceItem(gui, FileTIFF::RGBA_8888)); + add_item(new TIFFColorspaceItem(gui, FileTIFF::RGB_FLOAT)); + add_item(new TIFFColorspaceItem(gui, FileTIFF::RGBA_FLOAT)); } -TIFFConfigAlpha::TIFFConfigAlpha(TIFFConfigVideo *gui, int x, int y) - : BC_CheckBox(x, - y, - TIFFConfigVideo::codec_to_alpha(gui->asset->vcodec), - _("Use alpha")) +TIFFColorspaceItem::TIFFColorspaceItem(TIFFConfigVideo *gui, int value) + : BC_MenuItem(FileTIFF::cmodel_to_str(value)) { this->gui = gui; + this->value = value; } +int TIFFColorspaceItem::handle_event() +{ + gui->asset->tiff_cmodel = value; + return 0; +} + + -int TIFFConfigAlpha::handle_event() + + + + +TIFFCompression::TIFFCompression(TIFFConfigVideo *gui, int x, int y, int w) + : BC_PopupMenu(x, y, w, FileTIFF::compression_to_str(gui->asset->tiff_compression)) +{ + this->gui = gui; +} +int TIFFCompression::handle_event() { - if(TIFFConfigVideo::codec_to_alpha(gui->asset->vcodec)) - { - strcpy(gui->asset->vcodec, TIFF_RGB); - } - else - strcpy(gui->asset->vcodec, TIFF_RGBA); - - update(TIFFConfigVideo::codec_to_alpha(gui->asset->vcodec)); return 1; } +void TIFFCompression::create_objects() +{ + add_item(new TIFFCompressionItem(gui, FileTIFF::NONE)); +// add_item(new TIFFCompressionItem(gui, FileTIFF::LZW)); + add_item(new TIFFCompressionItem(gui, FileTIFF::PACK_BITS)); +// add_item(new TIFFCompressionItem(gui, FileTIFF::DEFLATE)); +// add_item(new TIFFCompressionItem(gui, FileTIFF::JPEG)); +} + + + + + +TIFFCompressionItem::TIFFCompressionItem(TIFFConfigVideo *gui, int value) + : BC_MenuItem(FileTIFF::compression_to_str(value)) +{ + this->gui = gui; + this->value = value; +} +int TIFFCompressionItem::handle_event() +{ + gui->asset->tiff_compression = value; + return 0; +} + + diff --git a/hvirtual/cinelerra/filetiff.h b/hvirtual/cinelerra/filetiff.h index 44aa85a9..fdc78ad4 100644 --- a/hvirtual/cinelerra/filetiff.h +++ b/hvirtual/cinelerra/filetiff.h @@ -23,6 +23,8 @@ public: int audio_options, int video_options); static int check_sig(Asset *asset); + static char* compression_to_str(int value); + static char* cmodel_to_str(int value); int can_copy_from(Edit *edit, int64_t position); int colormodel_supported(int colormodel); int get_best_colormodel(Asset *asset, int driver); @@ -31,6 +33,23 @@ public: int write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit); FrameWriterUnit* new_writer_unit(FrameWriter *writer); + enum + { + NONE, +// values stored in Asset::tiff_cmodel +// Data types + RGB_888, + RGBA_8888, + RGB_FLOAT, + RGBA_FLOAT, +// values stored in Asset::tiff_compression +// Compression types + LZW, + PACK_BITS, + DEFLATE, + JPEG + }; + Mutex *unit_lock; }; @@ -62,22 +81,49 @@ public: int close_event(); static char* alpha_to_codec(int use_alpha); static int codec_to_alpha(char *codec); - static void fix_codec(char *codec); BC_WindowBase *parent_window; Asset *asset; }; -class TIFFConfigAlpha : public BC_CheckBox +class TIFFColorspace : public BC_PopupMenu { public: - TIFFConfigAlpha(TIFFConfigVideo *gui, int x, int y); - + TIFFColorspace(TIFFConfigVideo *gui, int x, int y, int w); + void create_objects(); int handle_event(); - TIFFConfigVideo *gui; }; +class TIFFColorspaceItem : public BC_MenuItem +{ +public: + TIFFColorspaceItem(TIFFConfigVideo *gui, int value); + int handle_event(); + TIFFConfigVideo *gui; + int value; +}; + + + + +class TIFFCompression : public BC_PopupMenu +{ +public: + TIFFCompression(TIFFConfigVideo *gui, int x, int y, int w); + void create_objects(); + int handle_event(); + TIFFConfigVideo *gui; +}; + +class TIFFCompressionItem : public BC_MenuItem +{ +public: + TIFFCompressionItem(TIFFConfigVideo *gui, int value); + int handle_event(); + TIFFConfigVideo *gui; + int value; +}; diff --git a/hvirtual/cinelerra/filevorbis.C b/hvirtual/cinelerra/filevorbis.C index c9ff8649..5b3459ae 100644 --- a/hvirtual/cinelerra/filevorbis.C +++ b/hvirtual/cinelerra/filevorbis.C @@ -4,16 +4,13 @@ #include "file.h" #include "filevorbis.h" #include "guicast.h" +#include "language.h" #include "mwindow.inc" #include #include #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) FileVorbis::FileVorbis(Asset *asset, File *file) : FileBase(asset, file) @@ -402,8 +399,8 @@ int FileVorbis::read_samples(double *buffer, int64_t len) VorbisConfigAudio::VorbisConfigAudio(BC_WindowBase *parent_window, Asset *asset) : BC_Window(PROGRAM_NAME ": Audio Compression", - parent_window->get_abs_cursor_x(), - parent_window->get_abs_cursor_y(), + parent_window->get_abs_cursor_x(1), + parent_window->get_abs_cursor_y(1), 350, 170, -1, diff --git a/hvirtual/cinelerra/formatpopup.C b/hvirtual/cinelerra/formatpopup.C index 3481a70e..c4cc1447 100644 --- a/hvirtual/cinelerra/formatpopup.C +++ b/hvirtual/cinelerra/formatpopup.C @@ -50,6 +50,7 @@ int FormatPopup::create_objects() if(!use_brender) { format_items.append(new BC_ListBoxItem(_(AVI_NAME))); + format_items.append(new BC_ListBoxItem(_(EXR_NAME))); format_items.append(new BC_ListBoxItem(_(WAV_NAME))); format_items.append(new BC_ListBoxItem(_(MOV_NAME))); format_items.append(new BC_ListBoxItem(_(AMPEG_NAME))); diff --git a/hvirtual/cinelerra/indexfile.C b/hvirtual/cinelerra/indexfile.C index 1dd0f454..e9e09002 100644 --- a/hvirtual/cinelerra/indexfile.C +++ b/hvirtual/cinelerra/indexfile.C @@ -266,22 +266,10 @@ int IndexFile::create_index(Asset *asset, MainProgressBar *progress) if(open_source(&source)) return 1; asset->index_zoom = get_required_scale(&source); -//printf("IndexFile::create_index 1 %d %s\n", asset->index_zoom, asset->path); // Indexes are now built for everything since it takes too long to draw // from CDROM source. -// too small to build an index for. -// if(asset->index_zoom == 0) -// { -// source.close_file(); -// asset->index_status = INDEX_TOOSMALL; -// // Update the EDL and timeline -// redraw_edits(1); -// //printf("IndexFile::create_index 2\n"); -// return 1; -// } -//printf("IndexFile::create_index 2\n"); // total length of input file int64_t length_source = source.get_audio_length(0); @@ -308,45 +296,40 @@ int IndexFile::create_index(Asset *asset, MainProgressBar *progress) length_source); index_thread->start_build(); - int64_t position = 0; // current sample in source file +// current sample in source file + int64_t position = 0; int64_t fragment_size = buffersize; int current_buffer = 0; -//printf("IndexFile::create_index 3\n"); + // pass through file once while(position < length_source && !result) { if(length_source - position < fragment_size && fragment_size == buffersize) fragment_size = length_source - position; -//printf("IndexFile::create_index 1 %d\n", position); index_thread->input_lock[current_buffer]->lock("IndexFile::create_index 1"); index_thread->input_len[current_buffer] = fragment_size; -//printf("IndexFile::create_index 2 %d\n", position); int cancelled = progress->update(position); -//printf("IndexFile::create_index 3 %d\n", position); if(cancelled || index_thread->interrupt_flag || interrupt_flag) { - result = 3; // user cancelled + result = 3; } -//printf("IndexFile::create_index 4 %d\n", position); for(int channel = 0; !result && channel < asset->channels; channel++) { source.set_audio_position(position, 0); source.set_channel(channel); -// couldn't read -//printf("IndexFile::create_index 5\n"); +// Read from source file if(source.read_samples(index_thread->buffer_in[current_buffer][channel], fragment_size, 0)) result = 1; -//printf("IndexFile::create_index 6\n"); } -//printf("IndexFile::create_index 7 %d\n", position); +// Release buffer to thread if(!result) { index_thread->output_lock[current_buffer]->unlock(); @@ -358,9 +341,7 @@ int IndexFile::create_index(Asset *asset, MainProgressBar *progress) { index_thread->input_lock[current_buffer]->unlock(); } -//printf("IndexFile::create_index 8 %d\n", position); } -//printf("IndexFile::create_index 10\n"); // end thread cleanly index_thread->input_lock[current_buffer]->lock("IndexFile::create_index 2"); diff --git a/hvirtual/cinelerra/indexthread.C b/hvirtual/cinelerra/indexthread.C index 3a984e53..c00d7450 100644 --- a/hvirtual/cinelerra/indexthread.C +++ b/hvirtual/cinelerra/indexthread.C @@ -5,6 +5,7 @@ #include "filexml.h" #include "indexfile.h" #include "indexthread.h" +#include "language.h" #include "mwindow.h" #include "mwindowgui.h" #include "preferences.h" @@ -12,11 +13,6 @@ #include "trackcanvas.h" #include "tracks.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - // Read data from buffers and calculate peaks IndexThread::IndexThread(MWindow *mwindow, diff --git a/hvirtual/cinelerra/interfaceprefs.C b/hvirtual/cinelerra/interfaceprefs.C index 6340cd19..ba4552d6 100644 --- a/hvirtual/cinelerra/interfaceprefs.C +++ b/hvirtual/cinelerra/interfaceprefs.C @@ -1,16 +1,12 @@ #include "deleteallindexes.h" #include "edl.h" #include "edlsession.h" +#include "language.h" #include "mwindow.h" #include "preferences.h" #include "preferencesthread.h" #include "interfaceprefs.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #if 0 N_("Drag all following edits") N_("Drag only one edit") @@ -163,9 +159,20 @@ int InterfacePrefs::create_objects() text->create_objects(); y += 40; - add_subwindow(new BC_Title(x, y, _("Min DB for meter:"))); - sprintf(string, "%.0f", pwindow->thread->edl->session->min_meter_db); - add_subwindow(min_db = new MeterMinDB(pwindow, string, y)); + int x1 = x; + BC_Title *title; + add_subwindow(title = new BC_Title(x, y + 5, _("Min DB for meter:"))); + x += title->get_w() + 10; + sprintf(string, "%d", pwindow->thread->edl->session->min_meter_db); + add_subwindow(min_db = new MeterMinDB(pwindow, string, x, y)); + + x += min_db->get_w() + 10; + add_subwindow(title = new BC_Title(x, y + 5, _("Max DB:"))); + x += title->get_w() + 10; + sprintf(string, "%d", pwindow->thread->edl->session->max_meter_db); + add_subwindow(max_db = new MeterMaxDB(pwindow, string, x, y)); + + x = x1; y += 30; // add_subwindow(new BC_Title(x, y, _("Format for meter:"))); // add_subwindow(vu_db = new MeterVUDB(pwindow, _("DB"), y)); @@ -225,6 +232,7 @@ InterfacePrefs::~InterfacePrefs() delete hex; delete feet; delete min_db; + delete max_db; // delete vu_db; // delete vu_int; delete thumbnails; @@ -437,9 +445,11 @@ int ViewBehaviourItem::handle_event() -MeterMinDB::MeterMinDB(PreferencesWindow *pwindow, char *text, int y) - : BC_TextBox(145, y, 50, 1, text) -{ this->pwindow = pwindow; } +MeterMinDB::MeterMinDB(PreferencesWindow *pwindow, char *text, int x, int y) + : BC_TextBox(x, y, 50, 1, text) +{ + this->pwindow = pwindow; +} int MeterMinDB::handle_event() { @@ -451,6 +461,21 @@ int MeterMinDB::handle_event() +MeterMaxDB::MeterMaxDB(PreferencesWindow *pwindow, char *text, int x, int y) + : BC_TextBox(x, y, 50, 1, text) +{ + this->pwindow = pwindow; +} + +int MeterMaxDB::handle_event() +{ + pwindow->thread->redraw_meters = 1; + pwindow->thread->edl->session->max_meter_db = atol(get_text()); + return 0; +} + + + MeterVUDB::MeterVUDB(PreferencesWindow *pwindow, char *text, int y) diff --git a/hvirtual/cinelerra/interfaceprefs.h b/hvirtual/cinelerra/interfaceprefs.h index b08e56b3..7a899eda 100644 --- a/hvirtual/cinelerra/interfaceprefs.h +++ b/hvirtual/cinelerra/interfaceprefs.h @@ -11,6 +11,7 @@ class TimeFormatFrames; class TimeFormatHex; class TimeFormatFeet; class MeterMinDB; +class MeterMaxDB; class MeterVUDB; class MeterVUInt; class ViewBehaviourText; @@ -47,6 +48,7 @@ public: TimeFormatFeet *feet; MeterMinDB *min_db; + MeterMaxDB *max_db; MeterVUDB *vu_db; // MeterVUInt *vu_int; ViewBehaviourText *button1, *button2, *button3; @@ -147,7 +149,16 @@ public: class MeterMinDB : public BC_TextBox { public: - MeterMinDB(PreferencesWindow *pwindow, char *text, int y); + MeterMinDB(PreferencesWindow *pwindow, char *text, int x, int y); + int handle_event(); + PreferencesWindow *pwindow; +}; + + +class MeterMaxDB : public BC_TextBox +{ +public: + MeterMaxDB(PreferencesWindow *pwindow, char *text, int x, int y); int handle_event(); PreferencesWindow *pwindow; }; diff --git a/hvirtual/cinelerra/loadbalance.C b/hvirtual/cinelerra/loadbalance.C index 749df414..42832c34 100644 --- a/hvirtual/cinelerra/loadbalance.C +++ b/hvirtual/cinelerra/loadbalance.C @@ -1,3 +1,5 @@ +#include "condition.h" +#include "mutex.h" #include "loadbalance.h" @@ -5,10 +7,11 @@ LoadPackage::LoadPackage() { - completion_lock.lock(); + completion_lock = new Condition(0, "LoadPackage::completion_lock"); } LoadPackage::~LoadPackage() { + delete completion_lock; } @@ -26,15 +29,17 @@ LoadClient::LoadClient(LoadServer *server) this->server = server; done = 0; package_number = 0; - input_lock.lock(); - completion_lock.lock(); + input_lock = new Condition(0, "LoadClient::input_lock"); + completion_lock = new Condition(0, "LoadClient::completion_lock"); } LoadClient::~LoadClient() { done = 1; - input_lock.unlock(); + input_lock->unlock(); Thread::join(); + delete input_lock; + delete completion_lock; } int LoadClient::get_package_number() @@ -47,7 +52,7 @@ void LoadClient::run() { while(!done) { - input_lock.lock(); + input_lock->lock("LoadClient::run"); if(!done) { @@ -55,22 +60,22 @@ void LoadClient::run() LoadPackage *package; - server->client_lock.lock(); + server->client_lock->lock("LoadClient::run"); if(server->current_package < server->total_packages) { package_number = server->current_package; package = server->packages[server->current_package++]; - server->client_lock.unlock(); - input_lock.unlock(); + server->client_lock->unlock(); + input_lock->unlock(); process_package(package); - package->completion_lock.unlock(); + package->completion_lock->unlock(); } else { - completion_lock.unlock(); - server->client_lock.unlock(); + completion_lock->unlock(); + server->client_lock->unlock(); } } } @@ -92,12 +97,14 @@ LoadServer::LoadServer(int total_clients, int total_packages) current_package = 0; clients = 0; packages = 0; + client_lock = new Mutex("LoadServer::client_lock"); } LoadServer::~LoadServer() { delete_clients(); delete_packages(); + delete client_lock; } void LoadServer::delete_clients() @@ -187,19 +194,19 @@ void LoadServer::process_packages() // Start all clients for(int i = 0; i < total_clients; i++) { - clients[i]->input_lock.unlock(); + clients[i]->input_lock->unlock(); } // Wait for packages to get finished for(int i = 0; i < total_packages; i++) { - packages[i]->completion_lock.lock(); + packages[i]->completion_lock->lock("LoadServer::process_packages 1"); } // Wait for clients to finish before allowing changes to packages for(int i = 0; i < total_clients; i++) { - clients[i]->completion_lock.lock(); + clients[i]->completion_lock->lock("LoadServer::process_packages 2"); } } diff --git a/hvirtual/cinelerra/loadbalance.h b/hvirtual/cinelerra/loadbalance.h index fc38a3b0..221788d5 100644 --- a/hvirtual/cinelerra/loadbalance.h +++ b/hvirtual/cinelerra/loadbalance.h @@ -1,7 +1,8 @@ #ifndef LOADBALANCE_H #define LOADBALANCE_H -#include "mutex.h" +#include "condition.inc" +#include "mutex.inc" #include "thread.h" @@ -22,7 +23,7 @@ public: LoadPackage(); virtual ~LoadPackage(); - Mutex completion_lock; + Condition *completion_lock; }; @@ -38,7 +39,8 @@ public: int done; int package_number; - Mutex input_lock, completion_lock; + Condition *input_lock; + Condition *completion_lock; LoadServer *server; }; @@ -84,7 +86,7 @@ public: int total_packages; LoadClient **clients; int total_clients; - Mutex client_lock; + Mutex *client_lock; }; diff --git a/hvirtual/cinelerra/loadfile.C b/hvirtual/cinelerra/loadfile.C index afb9a8e0..3780077b 100644 --- a/hvirtual/cinelerra/loadfile.C +++ b/hvirtual/cinelerra/loadfile.C @@ -147,8 +147,8 @@ void LoadFileThread::run() LoadFileWindow::LoadFileWindow(MWindow *mwindow, LoadFileThread *thread, char *init_directory) - : BC_FileBox(mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y() - BC_WindowBase::get_resources()->filebox_h / 2, + : BC_FileBox(mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1) - BC_WindowBase::get_resources()->filebox_h / 2, init_directory, PROGRAM_NAME ": Load", _("Select files to load:"), @@ -290,8 +290,8 @@ int ResourcesOnly::handle_event() LocateFileWindow::LocateFileWindow(MWindow *mwindow, char *init_directory, char *old_filename) - : BC_FileBox(mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + : BC_FileBox(mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), init_directory, PROGRAM_NAME ": Locate file", old_filename) @@ -379,9 +379,11 @@ int LoadBackup::handle_event() strcpy(out_path, string); mwindow->undo->update_undo_before(_("load backup"), LOAD_ALL); - mwindow->load_filenames(&path_list, LOAD_REPLACE); + mwindow->load_filenames(&path_list, LOAD_REPLACE, 0); mwindow->edl->local_session->clip_title[0] = 0; - mwindow->set_filename(""); +// This is unique to backups since the path of the backup is different than the +// path of the project. + mwindow->set_filename(mwindow->edl->project_path); path_list.remove_all_objects(); mwindow->undo->update_undo_after(); mwindow->save_backup(); diff --git a/hvirtual/cinelerra/localsession.C b/hvirtual/cinelerra/localsession.C index c0a4552f..060ab6ac 100644 --- a/hvirtual/cinelerra/localsession.C +++ b/hvirtual/cinelerra/localsession.C @@ -20,6 +20,8 @@ LocalSession::LocalSession(EDL *edl) clipboard_length = 0; preview_start = preview_end = 0; loop_playback = 0; + view_start = 0; + track_start = 0; } LocalSession::~LocalSession() @@ -133,13 +135,11 @@ int LocalSession::load_defaults(Defaults *defaults) loop_end = defaults->get("LOOP_END", (double)0); selectionstart = defaults->get("SELECTIONSTART", selectionstart); selectionend = defaults->get("SELECTIONEND", selectionend); - track_start = defaults->get("TRACK_START", 0); - view_start = defaults->get("VIEW_START", 0); +// track_start = defaults->get("TRACK_START", 0); +// view_start = defaults->get("VIEW_START", 0); zoom_sample = defaults->get("ZOOM_SAMPLE", 1); zoom_y = defaults->get("ZOOMY", 64); zoom_track = defaults->get("ZOOM_TRACK", 64); -// preview_start = defaults->get("PREVIEW_START", preview_start); -// preview_end = defaults->get("PREVIEW_END", preview_end); return 0; } diff --git a/hvirtual/cinelerra/localsession.h b/hvirtual/cinelerra/localsession.h index 054e84ce..d6b6a0f1 100644 --- a/hvirtual/cinelerra/localsession.h +++ b/hvirtual/cinelerra/localsession.h @@ -61,7 +61,7 @@ public: double loop_end; // Vertical start of track view int64_t track_start; -// Start of view in pixels. This has to be pixels since either +// Horizontal start of view in pixels. This has to be pixels since either // samples or seconds would require drawing in fractional pixels. int64_t view_start; // Zooming of the timeline. Number of samples per pixel. diff --git a/hvirtual/cinelerra/main.C b/hvirtual/cinelerra/main.C index c368eaf2..2c8ea6ce 100644 --- a/hvirtual/cinelerra/main.C +++ b/hvirtual/cinelerra/main.C @@ -96,8 +96,10 @@ int main(int argc, char *argv[]) if(argc > i + 1) { if(atol(argv[i + 1]) > 0) + { deamon_port = atol(argv[i + 1]); - i++; + i++; + } } } else diff --git a/hvirtual/cinelerra/maincursor.C b/hvirtual/cinelerra/maincursor.C index 5f85cd82..be1d01bf 100644 --- a/hvirtual/cinelerra/maincursor.C +++ b/hvirtual/cinelerra/maincursor.C @@ -1,3 +1,4 @@ +#include "bcsignals.h" #include "edl.h" #include "edlsession.h" #include "localsession.h" @@ -59,7 +60,6 @@ void MainCursor::deactivate() int MainCursor::repeat_event(int64_t duration) { if(!active || !gui->get_has_focus()) return 0; -//printf("MainCursor::repeat_event 1 %d\n", duration); if(duration != BC_WindowBase::get_resources()->blink_rate) return 0; // Only flash a single sample selection @@ -71,7 +71,6 @@ int MainCursor::repeat_event(int64_t duration) flash(); } } -//printf("MainCursor::repeat_event 2 %d\n", duration); return 1; } @@ -122,6 +121,7 @@ void MainCursor::update() void MainCursor::flash() { gui->canvas->flash(pixel1, 0, pixel2 - pixel1 + 1, gui->canvas->get_h()); + gui->flush(); } void MainCursor::hide() diff --git a/hvirtual/cinelerra/mainindexes.C b/hvirtual/cinelerra/mainindexes.C index 655c3e70..36ec75c9 100644 --- a/hvirtual/cinelerra/mainindexes.C +++ b/hvirtual/cinelerra/mainindexes.C @@ -131,12 +131,9 @@ void MainIndexes::run() // Wait for new assets to be released input_lock->lock("MainIndexes::run 1"); if(done) return; - interrupt_lock->lock("MainIndexes::run 2"); -//printf("MainIndexes::run 1 %d\n", next_assets.total); load_next_assets(); interrupt_flag = 0; -//printf("MainIndexes::run 2 %d\n", current_assets.total); @@ -194,7 +191,6 @@ void MainIndexes::run() } //printf("MainIndexes::run 9\n"); } -//printf("MainIndexes::run 10\n"); if(progress) // progress box is only created when an index is built { @@ -209,7 +205,6 @@ void MainIndexes::run() -//printf("MainIndexes::run 11\n"); interrupt_lock->unlock(); } diff --git a/hvirtual/cinelerra/mainprogress.C b/hvirtual/cinelerra/mainprogress.C index a4cc42eb..b6dcc121 100644 --- a/hvirtual/cinelerra/mainprogress.C +++ b/hvirtual/cinelerra/mainprogress.C @@ -219,8 +219,8 @@ MainProgressBar* MainProgress::start_progress(char *text, long total_length) { result = new MainProgressBar(mwindow, this); progress_bars.append(result); - result->progress_box = new BC_ProgressBox(gui->get_abs_cursor_x(), - gui->get_abs_cursor_y(), + result->progress_box = new BC_ProgressBox(gui->get_abs_cursor_x(1), + gui->get_abs_cursor_y(1), text, total_length); } diff --git a/hvirtual/cinelerra/mainsession.C b/hvirtual/cinelerra/mainsession.C index e29325e5..fead81e9 100644 --- a/hvirtual/cinelerra/mainsession.C +++ b/hvirtual/cinelerra/mainsession.C @@ -8,6 +8,7 @@ #include "meterpanel.h" #include "mwindow.h" #include "mwindowgui.h" +#include "auto.h" MainSession::MainSession(MWindow *mwindow) { @@ -26,6 +27,7 @@ MainSession::MainSession(MWindow *mwindow) drag_pluginservers = new ArrayList; drag_plugin = 0; drag_assets = new ArrayList; + drag_auto_gang = new ArrayList; drag_clips = new ArrayList; drag_edits = new ArrayList; drag_edit = 0; @@ -38,6 +40,7 @@ MainSession::~MainSession() { delete drag_pluginservers; delete drag_assets; + delete drag_auto_gang; delete drag_clips; delete drag_edits; } diff --git a/hvirtual/cinelerra/mainsession.h b/hvirtual/cinelerra/mainsession.h index e56db29d..6de942c4 100644 --- a/hvirtual/cinelerra/mainsession.h +++ b/hvirtual/cinelerra/mainsession.h @@ -52,6 +52,7 @@ public: ArrayList *drag_assets; ArrayList *drag_clips; Auto *drag_auto; + ArrayList *drag_auto_gang; // Edit whose handle is being dragged Edit *drag_edit; diff --git a/hvirtual/cinelerra/maskengine.C b/hvirtual/cinelerra/maskengine.C index 9064945a..fc84e531 100644 --- a/hvirtual/cinelerra/maskengine.C +++ b/hvirtual/cinelerra/maskengine.C @@ -1,3 +1,4 @@ +#include "condition.h" #include "clip.h" #include "maskauto.h" #include "maskautos.h" @@ -11,7 +12,7 @@ MaskPackage::MaskPackage() { - apply_mutex = new Mutex; + apply_mutex = new Condition(1, "MaskPackage::apply_mutex"); } MaskPackage::~MaskPackage() @@ -56,32 +57,6 @@ MaskUnit::~MaskUnit() -#define DRAW_LINE_CLAMPED(type, value) \ -{ \ - type **rows = (type**)frame->get_rows(); \ - \ - if(draw_y2 != draw_y1) \ - { \ - float slope = ((float)draw_x2 - draw_x1) / ((float)draw_y2 - draw_y1); \ - int w = frame->get_w() - 1; \ - int h = frame->get_h(); \ - \ - for(float y = draw_y1; y < draw_y2; y++) \ - { \ - if(y >= 0 && y < h) \ - { \ - int x = (int)((y - draw_y1) * slope + draw_x1); \ - int y_i = (int)y; \ - int x_i = CLIP(x, 0, w); \ - \ - if(rows[y_i][x_i] == value) \ - rows[y_i][x_i] = 0; \ - else \ - rows[y_i][x_i] = value; \ - } \ - } \ - } \ -} @@ -92,7 +67,6 @@ void MaskUnit::draw_line_clamped(VFrame *frame, int y2, unsigned char k) { -//printf("MaskUnit::draw_line_clamped 1 %d %d %d %d\n", x1, y1, x2, y2); int draw_x1; int draw_y1; int draw_x2; @@ -114,15 +88,28 @@ void MaskUnit::draw_line_clamped(VFrame *frame, draw_y2 = y2; } - switch(frame->get_color_model()) + unsigned char **rows = (unsigned char**)frame->get_rows(); + + if(draw_y2 != draw_y1) { - case BC_A8: - DRAW_LINE_CLAMPED(unsigned char, k); - break; - - case BC_A16: - DRAW_LINE_CLAMPED(uint16_t, k); - break; + float slope = ((float)draw_x2 - draw_x1) / ((float)draw_y2 - draw_y1); + int w = frame->get_w() - 1; + int h = frame->get_h(); + + for(float y = draw_y1; y < draw_y2; y++) + { + if(y >= 0 && y < h) + { + int x = (int)((y - draw_y1) * slope + draw_x1); + int y_i = (int)y; + int x_i = CLIP(x, 0, w); + + if(rows[y_i][x_i] == k) + rows[y_i][x_i] = 0; + else + rows[y_i][x_i] = k; + } + } } } @@ -358,6 +345,10 @@ void MaskUnit::do_feather(VFrame *output, case BC_A16: DO_FEATHER(uint16_t, 0xffff); break; + + case BC_A_FLOAT: + DO_FEATHER(float, 1); + break; } @@ -372,7 +363,6 @@ void MaskUnit::process_package(LoadPackage *package) if(engine->recalculate && ptr->part == RECALCULATE_PART) { VFrame *mask; -//printf("MaskUnit::process_package 1 %d\n", get_package_number()); if(engine->feather > 0) mask = engine->temp_mask; else @@ -471,48 +461,35 @@ void MaskUnit::process_package(LoadPackage *package) -#define FILL_ROWS(type) \ -for(int i = 0; i < oversampled_package_h; i++) \ -{ \ - type *row = (type*)temp->get_rows()[i]; \ - int value = 0x0; \ - int total = 0; \ - \ - for(int j = 0; j < oversampled_package_w; j++) \ - if(row[j] == max) total++; \ - \ - if(total > 1) \ - { \ - if(total & 0x1) total--; \ - for(int j = 0; j < oversampled_package_w; j++) \ - { \ - if(row[j] == max && total > 0) \ - { \ - if(value) \ - value = 0x0; \ - else \ - value = max; \ - total--; \ - } \ - else \ - { \ - if(value) row[j] = value; \ - } \ - } \ - } \ -} - - // Fill in the polygon in the horizontal direction - switch(temp->get_color_model()) + for(int i = 0; i < oversampled_package_h; i++) { - case BC_A8: - FILL_ROWS(unsigned char); - break; + unsigned char *row = (unsigned char*)temp->get_rows()[i]; + int value = 0x0; + int total = 0; - case BC_A16: - FILL_ROWS(uint16_t); - break; + for(int j = 0; j < oversampled_package_w; j++) + if(row[j] == max) total++; + + if(total > 1) + { + if(total & 0x1) total--; + for(int j = 0; j < oversampled_package_w; j++) + { + if(row[j] == max && total > 0) + { + if(value) + value = 0x0; + else + value = max; + total--; + } + else + { + if(value) row[j] = value; + } + } + } } } @@ -522,8 +499,7 @@ for(int i = 0; i < oversampled_package_h; i++) \ - -#define DOWNSAMPLE(type, value) \ +#define DOWNSAMPLE(type, temp_type, value) \ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ { \ type *output_row = (type*)mask->get_rows()[i + ptr->row1]; \ @@ -532,7 +508,7 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ \ for(int j = 0; j < mask_w; j++) \ { \ - int64_t total = 0; \ + temp_type total = 0; \ \ /* Accumulate pixel */ \ for(int k = 0; k < OVERSAMPLE; k++) \ @@ -545,16 +521,7 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ } \ \ /* Divide pixel */ \ - if(OVERSAMPLE == 8) \ - total >>= 6; \ - else \ - if(OVERSAMPLE == 4) \ - total >>= 2; \ - else \ - if(OVERSAMPLE == 2) \ - total >>= 2; \ - else \ - total /= OVERSAMPLE * OVERSAMPLE; \ + total /= OVERSAMPLE * OVERSAMPLE; \ \ output_row[j] = total; \ } \ @@ -568,7 +535,7 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ { unsigned char value; value = (int)((float)engine->value / 100 * 0xff); - DOWNSAMPLE(unsigned char, value); + DOWNSAMPLE(unsigned char, int64_t, value); break; } @@ -576,11 +543,18 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ { uint16_t value; value = (int)((float)engine->value / 100 * 0xffff); - DOWNSAMPLE(uint16_t, value); + DOWNSAMPLE(uint16_t, int64_t, value); break; } - } + case BC_A_FLOAT: + { + float value; + value = (float)engine->value / 100; + DOWNSAMPLE(float, double, value); + break; + } + } } @@ -601,12 +575,11 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ } -//printf("MaskUnit::process_package 2\n"); if(ptr->part == APPLY_PART) { //printf("MaskUnit::process_package 2.1\n"); - ptr->apply_mutex->lock(); + ptr->apply_mutex->lock("MaskUnit::process_package"); ptr->apply_mutex->unlock(); //printf("MaskUnit::process_package 2.2\n"); @@ -633,7 +606,7 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ { \ type *output_row = (type*)engine->output->get_rows()[i]; \ type *mask_row = (type*)engine->mask->get_rows()[i]; \ - int chroma_offset = (max + 1) / 2; \ + int chroma_offset = (int)(max + 1) / 2; \ \ for(int j = 0; j < mask_w; j++) \ { \ @@ -661,7 +634,7 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ { \ type *output_row = (type*)engine->output->get_rows()[i]; \ type *mask_row = (type*)engine->mask->get_rows()[i]; \ - int chroma_offset = (max + 1) / 2; \ + int chroma_offset = (int)(max + 1) / 2; \ \ for(int j = 0; j < mask_w; j++) \ { \ @@ -699,10 +672,18 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ case BC_RGB888: APPLY_MASK_MULTIPLY_ALPHA(unsigned char, 0xff, 3, 0); break; + case BC_RGB_FLOAT: + APPLY_MASK_MULTIPLY_ALPHA(float, 1.0, 3, 0); + break; case BC_YUV888: APPLY_MASK_MULTIPLY_ALPHA(unsigned char, 0xff, 3, 1); break; + case BC_RGBA_FLOAT: + APPLY_MASK_MULTIPLY_ALPHA(float, 1.0, 4, 0); + break; case BC_YUVA8888: + APPLY_MASK_MULTIPLY_ALPHA(unsigned char, 0xff, 4, 1); + break; case BC_RGBA8888: APPLY_MASK_MULTIPLY_ALPHA(unsigned char, 0xff, 4, 0); break; @@ -713,6 +694,8 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ APPLY_MASK_MULTIPLY_ALPHA(uint16_t, 0xffff, 3, 1); break; case BC_YUVA16161616: + APPLY_MASK_MULTIPLY_ALPHA(uint16_t, 0xffff, 4, 1); + break; case BC_RGBA16161616: APPLY_MASK_MULTIPLY_ALPHA(uint16_t, 0xffff, 4, 0); break; @@ -725,29 +708,38 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ case BC_RGB888: APPLY_MASK_SUBTRACT_ALPHA(unsigned char, 0xff, 3, 0); break; + case BC_RGB_FLOAT: + APPLY_MASK_SUBTRACT_ALPHA(float, 1.0, 3, 0); + break; + case BC_RGBA_FLOAT: + APPLY_MASK_SUBTRACT_ALPHA(float, 1.0, 4, 0); + break; + case BC_RGBA8888: + APPLY_MASK_SUBTRACT_ALPHA(unsigned char, 0xff, 4, 0); + break; case BC_YUV888: APPLY_MASK_SUBTRACT_ALPHA(unsigned char, 0xff, 3, 1); break; case BC_YUVA8888: - case BC_RGBA8888: - APPLY_MASK_SUBTRACT_ALPHA(unsigned char, 0xff, 4, 0); + APPLY_MASK_SUBTRACT_ALPHA(unsigned char, 0xff, 4, 1); break; case BC_RGB161616: APPLY_MASK_SUBTRACT_ALPHA(uint16_t, 0xffff, 3, 0); break; + case BC_RGBA16161616: + APPLY_MASK_SUBTRACT_ALPHA(uint16_t, 0xffff, 4, 0); + break; case BC_YUV161616: APPLY_MASK_SUBTRACT_ALPHA(uint16_t, 0xffff, 3, 1); break; case BC_YUVA16161616: - case BC_RGBA16161616: - APPLY_MASK_SUBTRACT_ALPHA(uint16_t, 0xffff, 4, 0); + APPLY_MASK_SUBTRACT_ALPHA(uint16_t, 0xffff, 4, 1); break; } break; } } } -//printf("MaskUnit::process_package 4 %d\n", get_package_number()); } @@ -756,7 +748,7 @@ for(int i = 0; i < ptr->row2 - ptr->row1; i++) \ MaskEngine::MaskEngine(int cpus) : LoadServer(cpus, cpus * OVERSAMPLE * 2) -// : LoadServer(1, 2) +// : LoadServer(1, OVERSAMPLE * 2) { mask = 0; } @@ -831,6 +823,11 @@ void MaskEngine::do_mask(VFrame *output, recalculate = 0; switch(output->get_color_model()) { + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + new_color_model = BC_A_FLOAT; + break; + case BC_RGB888: case BC_RGBA8888: case BC_YUV888: @@ -931,7 +928,6 @@ void MaskEngine::do_mask(VFrame *output, process_packages(); -//printf("MaskEngine::do_mask 6\n"); } void MaskEngine::init_packages() @@ -955,7 +951,7 @@ void MaskEngine::init_packages() part2->row2 = part1->row2 = output->get_h(); } - part2->apply_mutex->lock(); + part2->apply_mutex->lock("MaskEngine::init_packages"); part1->part = RECALCULATE_PART; part2->part = APPLY_PART; diff --git a/hvirtual/cinelerra/maskengine.h b/hvirtual/cinelerra/maskengine.h index d8083383..8bb32afb 100644 --- a/hvirtual/cinelerra/maskengine.h +++ b/hvirtual/cinelerra/maskengine.h @@ -2,6 +2,7 @@ #define MASKENGINE_H +#include "condition.inc" #include "loadbalance.h" #include "maskautos.inc" #include "maskauto.inc" @@ -27,7 +28,7 @@ public: int row1, row2; int part; - Mutex *apply_mutex; + Condition *apply_mutex; }; class MaskUnit : public LoadClient diff --git a/hvirtual/cinelerra/menueffects.C b/hvirtual/cinelerra/menueffects.C index 98abe3c0..d02eb2a5 100644 --- a/hvirtual/cinelerra/menueffects.C +++ b/hvirtual/cinelerra/menueffects.C @@ -538,8 +538,8 @@ MenuEffectWindow::MenuEffectWindow(MWindow *mwindow, ArrayList *plugin_list, Asset *asset) : BC_Window(PROGRAM_NAME ": Render effect", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y() - mwindow->session->menueffect_h / 2, + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1) - mwindow->session->menueffect_h / 2, mwindow->session->menueffect_w, mwindow->session->menueffect_h, 580, @@ -726,8 +726,8 @@ int MenuEffectWindowList::handle_event() MenuEffectPrompt::MenuEffectPrompt(MWindow *mwindow) : BC_Window(PROGRAM_NAME ": Effect Prompt", - mwindow->gui->get_abs_cursor_x() - 260 / 2, - mwindow->gui->get_abs_cursor_y() - 300, + mwindow->gui->get_abs_cursor_x(1) - 260 / 2, + mwindow->gui->get_abs_cursor_y(1) - 300, 260, 80, 260, diff --git a/hvirtual/cinelerra/meterpanel.C b/hvirtual/cinelerra/meterpanel.C index 3e43799a..ba5faeca 100644 --- a/hvirtual/cinelerra/meterpanel.C +++ b/hvirtual/cinelerra/meterpanel.C @@ -1,15 +1,12 @@ #include "edl.h" #include "edlsession.h" +#include "language.h" #include "meterpanel.h" #include "mwindow.h" #include "preferences.h" #include "theme.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) MeterPanel::MeterPanel(MWindow *mwindow, @@ -18,7 +15,8 @@ MeterPanel::MeterPanel(MWindow *mwindow, int y, int h, int meter_count, - int use_meters) + int use_meters, + int use_recording) { this->subwindow = subwindow; this->mwindow = mwindow; @@ -27,6 +25,7 @@ MeterPanel::MeterPanel(MWindow *mwindow, this->h = h; this->meter_count = meter_count; this->use_meters = use_meters; + this->use_recording = use_recording; } @@ -159,11 +158,14 @@ void MeterPanel::reset_meters() } -void MeterPanel::change_format(int mode, float min) +void MeterPanel::change_format(int mode, int min, int max) { for(int i = 0; i < meters.total; i++) { - meters.values[i]->change_format(mode, min); + if(use_recording) + meters.values[i]->change_format(mode, min, 0); + else + meters.values[i]->change_format(mode, min, max); } } @@ -208,8 +210,11 @@ MeterMeter::MeterMeter(MWindow *mwindow, METER_VERT, h, mwindow->edl->session->min_meter_db, + panel->use_recording ? 0 : mwindow->edl->session->max_meter_db, mwindow->edl->session->meter_format, - titles) + titles, + TRACKING_RATE * 10, + TRACKING_RATE) { this->mwindow = mwindow; this->panel = panel; diff --git a/hvirtual/cinelerra/meterpanel.h b/hvirtual/cinelerra/meterpanel.h new file mode 100644 index 00000000..7ecc28dd --- /dev/null +++ b/hvirtual/cinelerra/meterpanel.h @@ -0,0 +1,80 @@ +#ifndef METERPANEL_H +#define METERPANEL_H + +#include "guicast.h" +#include "mwindow.inc" + +class MeterReset; +class MeterMeter; + +class MeterPanel +{ +public: + MeterPanel(MWindow *mwindow, + BC_WindowBase *subwindow, + int x, + int y, + int h, + int meter_count, + int use_meters, + int use_recording = 0); + ~MeterPanel(); + + int create_objects(); + int set_meters(int meter_count, int use_meters); + static int get_meters_width(int meter_count, int use_meters); + void reposition_window(int x, int y, int h); + int get_reset_x(); + int get_reset_y(); + int get_meter_h(); + int get_meter_w(int number); + void update(double *levels); + void stop_meters(); + void change_format(int mode, int min, int max); + virtual int change_status_event(); + void reset_meters(); + + MWindow *mwindow; + BC_WindowBase *subwindow; + ArrayList meters; + MeterReset *reset; + int meter_count; + int use_meters; + int x, y, h; + int use_recording; +}; + + +class MeterReset : public BC_Button +{ +public: + MeterReset(MWindow *mwindow, MeterPanel *panel, int x, int y); + ~MeterReset(); + int handle_event(); + MWindow *mwindow; + MeterPanel *panel; +}; + +class MeterShow : public BC_Toggle +{ +public: + MeterShow(MWindow *mwindow, MeterPanel *panel, int x, int y); + ~MeterShow(); + int handle_event(); + MWindow *mwindow; + MeterPanel *panel; +}; + +class MeterMeter : public BC_Meter +{ +public: + MeterMeter(MWindow *mwindow, MeterPanel *panel, int x, int y, int h, int titles); + ~MeterMeter(); + + int button_press_event(); + + MWindow *mwindow; + MeterPanel *panel; +}; + +#endif diff --git a/hvirtual/cinelerra/module.C b/hvirtual/cinelerra/module.C index eea943ab..d1464a3b 100644 --- a/hvirtual/cinelerra/module.C +++ b/hvirtual/cinelerra/module.C @@ -223,6 +223,7 @@ void Module::update_transition(int64_t current_position, if(transition && !this->transition) { this->transition = transition; + if(renderengine) { PluginServer *plugin_server = renderengine->scan_plugindb(transition->title, @@ -264,10 +265,7 @@ void Module::dump() printf(" Plugins total_attachments=%d\n", total_attachments); for(int i = 0; i < total_attachments; i++) { - if(attachments[i]) - attachments[i]->dump(); - else - printf(" No Plugin\n"); + attachments[i]->dump(); } } diff --git a/hvirtual/cinelerra/mwindow.C b/hvirtual/cinelerra/mwindow.C index a8e19e38..508665b8 100644 --- a/hvirtual/cinelerra/mwindow.C +++ b/hvirtual/cinelerra/mwindow.C @@ -338,11 +338,15 @@ void MWindow::init_plugins(Preferences *preferences, if(splash_window) splash_window->progress->update_length(total); // Cinelerra +#ifndef DO_STATIC init_plugin_path(preferences, plugindb, &cinelerra_fs, splash_window, &counter); +#else +// Call automatically generated routine to get plugins +#endif // LAD for(int i = 0; i < lad_fs.total; i++) @@ -574,10 +578,14 @@ void MWindow::init_menus() colormodels.append(new ColormodelItem(string, BC_RGB888)); cmodel_to_text(string, BC_RGBA8888); colormodels.append(new ColormodelItem(string, BC_RGBA8888)); - cmodel_to_text(string, BC_RGB161616); - colormodels.append(new ColormodelItem(string, BC_RGB161616)); - cmodel_to_text(string, BC_RGBA16161616); - colormodels.append(new ColormodelItem(string, BC_RGBA16161616)); +// cmodel_to_text(string, BC_RGB161616); +// colormodels.append(new ColormodelItem(string, BC_RGB161616)); +// cmodel_to_text(string, BC_RGBA16161616); +// colormodels.append(new ColormodelItem(string, BC_RGBA16161616)); + cmodel_to_text(string, BC_RGB_FLOAT); + colormodels.append(new ColormodelItem(string, BC_RGB_FLOAT)); + cmodel_to_text(string, BC_RGBA_FLOAT); + colormodels.append(new ColormodelItem(string, BC_RGBA_FLOAT)); cmodel_to_text(string, BC_YUV888); colormodels.append(new ColormodelItem(string, BC_YUV888)); cmodel_to_text(string, BC_YUVA8888); @@ -681,12 +689,13 @@ void MWindow::set_brender_start() -int MWindow::load_filenames(ArrayList *filenames, int load_mode) +int MWindow::load_filenames(ArrayList *filenames, + int load_mode, + int update_filename) { TRACE("MWindow::load_filenames 1"); ArrayList new_edls; ArrayList new_assets; -//printf("load_filenames 1\n"); // Need to stop playback since tracking depends on the EDL not getting // deleted. @@ -713,39 +722,37 @@ TRACE("MWindow::load_filenames 1"); EDL *new_edl = new EDL; char string[BCTEXTLEN]; -//printf("load_filenames 1\n"); new_edl->create_objects(); -//printf("load_filenames 1\n"); new_edl->copy_session(edl); -//printf("load_filenames 1\n"); sprintf(string, "Loading %s", new_asset->path); -//printf("load_filenames 1\n"); gui->show_message(string, BLACK); -//printf("load_filenames 1\n"); result = new_file->open_file(plugindb, new_asset, 1, 0, 0, 0); -//printf("load_filenames 2\n"); switch(result) { // Convert media file to EDL case FILE_OK: -//printf("load_filenames 1.1\n"); if(load_mode != LOAD_RESOURCESONLY) { asset_to_edl(new_edl, new_asset); -//printf("load_filenames 1.2\n"); new_edls.append(new_edl); delete new_asset; } else -//printf("load_filenames 1.3\n"); { new_assets.append(new_asset); } + +// Set filename to nothing for assets since save EDL would overwrite them. if(load_mode == LOAD_REPLACE || load_mode == LOAD_REPLACE_CONCATENATE) + { set_filename(""); +// Reset timeline position + new_edl->local_session->view_start = 0; + new_edl->local_session->track_start = 0; + } result = 0; break; @@ -850,50 +857,39 @@ TRACE("MWindow::load_filenames 1"); case FILE_IS_XML: { -//printf("load_filenames 2\n"); FileXML xml_file; xml_file.read_from_file(filenames->values[i]); // Load EDL for pasting -//printf("load_filenames 3\n"); new_edl->load_xml(plugindb, &xml_file, LOAD_ALL); -//printf("load_filenames 3\n"); if(load_mode == LOAD_REPLACE || load_mode == LOAD_REPLACE_CONCATENATE) { strcpy(session->filename, filenames->values[i]); strcpy(new_edl->local_session->clip_title, filenames->values[i]); - set_filename(new_edl->local_session->clip_title); + if(update_filename) + set_filename(new_edl->local_session->clip_title); } -//new_edl->dump(); -//printf("load_filenames 2\n"); + new_edls.append(new_edl); -//printf("load_filenames 4\n"); result = 0; break; } } -//printf("load_filenames 4\n"); if(result) { delete new_edl; delete new_asset; } -//printf("load_filenames 5\n"); delete new_file; -//printf("load_filenames 6\n"); - } -//printf("MWindow::load_filenames 5 %d\n", new_edls.total); -//sleep(10); if(!result) gui->statusbar->default_message(); -//printf("MWindow::load_filenames 7 %d\n", new_edls.total); @@ -930,9 +926,6 @@ TRACE("MWindow::load_filenames 1"); -//printf("MWindow::load_filenames 8 %d\n", new_edls.total); -//sleep(10); - if(new_assets.total) { for(int i = 0; i < new_assets.total; i++) @@ -1227,7 +1220,7 @@ void MWindow::show_plugin(Plugin *plugin) { int done = 0; //printf("MWindow::show_plugin 1\n"); - plugin_gui_lock->lock(); + plugin_gui_lock->lock("MWindow::show_plugin"); for(int i = 0; i < plugin_guis->total; i++) { // Pointer comparison @@ -1266,14 +1259,12 @@ void MWindow::show_plugin(Plugin *plugin) void MWindow::hide_plugin(Plugin *plugin, int lock) { - if(lock) plugin_gui_lock->lock(); + if(lock) plugin_gui_lock->lock("MWindow::hide_plugin"); plugin->show = 0; for(int i = 0; i < plugin_guis->total; i++) { -//printf("MWindow::hide_plugin 1 %p %p\n", plugin, plugin_guis->values[i]->plugin); if(plugin_guis->values[i]->plugin == plugin) { -//printf("MWindow::hide_plugin 2\n"); PluginServer *ptr = plugin_guis->values[i]; plugin_guis->remove(ptr); if(lock) plugin_gui_lock->unlock(); @@ -1287,14 +1278,14 @@ void MWindow::hide_plugin(Plugin *plugin, int lock) void MWindow::hide_plugins() { - plugin_gui_lock->lock(); + plugin_gui_lock->lock("MWindow::hide_plugins"); plugin_guis->remove_all_objects(); plugin_gui_lock->unlock(); } void MWindow::update_plugin_guis() { - plugin_gui_lock->lock(); + plugin_gui_lock->lock("MWindow::update_plugin_guis"); for(int i = 0; i < plugin_guis->total; i++) { @@ -1305,13 +1296,11 @@ void MWindow::update_plugin_guis() void MWindow::render_plugin_gui(void *data, Plugin *plugin) { -//printf("MWindow::render_plugin_gui 1\n"); - plugin_gui_lock->lock(); + plugin_gui_lock->lock("MWindow::render_plugin_gui"); for(int i = 0; i < plugin_guis->total; i++) { if(plugin_guis->values[i]->plugin->identical_location(plugin)) { -//printf("MWindow::render_plugin_gui 2\n"); plugin_guis->values[i]->render_gui(data); break; } @@ -1321,13 +1310,11 @@ void MWindow::render_plugin_gui(void *data, Plugin *plugin) void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin) { -//printf("MWindow::render_plugin_gui 1\n"); - plugin_gui_lock->lock(); + plugin_gui_lock->lock("MWindow::render_plugin_gui"); for(int i = 0; i < plugin_guis->total; i++) { if(plugin_guis->values[i]->plugin->identical_location(plugin)) { -//printf("MWindow::render_plugin_gui 2\n"); plugin_guis->values[i]->render_gui(data, size); break; } @@ -1339,7 +1326,7 @@ void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin) void MWindow::update_plugin_states() { int result = 0; - plugin_gui_lock->lock(); + plugin_gui_lock->lock("MWindow::update_plugin_states"); for(int i = 0; i < plugin_guis->total; i++) { // Get a plugin GUI @@ -1530,6 +1517,7 @@ void MWindow::rebuild_indices() void MWindow::save_backup() { FileXML file; + edl->set_project_path(session->filename); edl->save_xml(plugindb, &file, BACKUP_PATH, diff --git a/hvirtual/cinelerra/mwindow.h b/hvirtual/cinelerra/mwindow.h index 25feb3e2..fcd1f2e4 100644 --- a/hvirtual/cinelerra/mwindow.h +++ b/hvirtual/cinelerra/mwindow.h @@ -136,7 +136,10 @@ public: int load_filenames(ArrayList *filenames, - int load_mode = LOAD_REPLACE); + int load_mode = LOAD_REPLACE, +// Cause the project filename on the top of the window to be updated. +// Not wanted for loading backups. + int update_filename = 1); int interrupt_indexes(); // Stop index building diff --git a/hvirtual/cinelerra/mwindow.inc b/hvirtual/cinelerra/mwindow.inc index ff9ebb44..c801e8c2 100644 --- a/hvirtual/cinelerra/mwindow.inc +++ b/hvirtual/cinelerra/mwindow.inc @@ -2,7 +2,7 @@ #define MWINDOW_INC #define PROGRAM_NAME "Cinelerra" -#define CINELERRA_VERSION "1.2.0" +#define CINELERRA_VERSION "1.2.1" #define DEFAULT_THEME "Blond" #define CONFIG_FILE "Cinelerra_rc" #define PLUGIN_DIR "/usr/lib/cinelerra" diff --git a/hvirtual/cinelerra/mwindowgui.C b/hvirtual/cinelerra/mwindowgui.C index f523357b..68b839b8 100644 --- a/hvirtual/cinelerra/mwindowgui.C +++ b/hvirtual/cinelerra/mwindowgui.C @@ -164,6 +164,8 @@ void MWindowGUI::get_scrollbars() int MWindowGUI::create_objects() { +//set_repeat(100); + //printf("MWindowGUI::create_objects 1\n"); set_icon(mwindow->theme->mwindow_icon); @@ -300,19 +302,19 @@ void MWindowGUI::update(int scrollbars, int clock, int buttonbar) { -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); mwindow->edl->tracks->update_y_pixels(mwindow->theme); -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(scrollbars) this->get_scrollbars(); -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(timebar) this->timebar->update(); -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(zoombar) this->zoombar->update(); -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(patchbay) this->patchbay->update(); -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(clock) this->mainclock->update(mwindow->edl->local_session->selectionstart); -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(canvas) { this->canvas->draw(canvas == 2); @@ -320,9 +322,9 @@ TRACE("MWindowGUI::update 1"); this->canvas->flash(); this->canvas->activate(); } -TRACE("MWindowGUI::update 1"); +//TRACE("MWindowGUI::update 1"); if(buttonbar) mbuttons->update(); -TRACE("MWindowGUI::update 100"); +//TRACE("MWindowGUI::update 100"); } int MWindowGUI::visible(int64_t x1, int64_t x2, int64_t view_x1, int64_t view_x2) @@ -430,6 +432,8 @@ void MWindowGUI::default_positions() int MWindowGUI::repeat_event(int64_t duration) { +// if(duration == 100) +// mwindow->sync_parameters(CHANGE_ALL); return cursor->repeat_event(duration); } diff --git a/hvirtual/cinelerra/new.C b/hvirtual/cinelerra/new.C index e1db1e84..a8dab1df 100644 --- a/hvirtual/cinelerra/new.C +++ b/hvirtual/cinelerra/new.C @@ -11,6 +11,7 @@ #include "mwindow.h" #include "mwindowgui.h" #include "new.h" +#include "newpresets.h" #include "mainsession.h" #include "patchbay.h" #include "theme.h" @@ -21,6 +22,11 @@ #include + +#define WIDTH 600 +#define HEIGHT 400 + + New::New(MWindow *mwindow) : BC_MenuItem(_("New..."), "n", 'n') { @@ -38,7 +44,14 @@ int New::handle_event() { if(thread->running()) { - thread->nwindow->raise_window(); + thread->window_lock->lock("New::handle_event"); + if(thread->nwindow) + { + thread->nwindow->lock_window("New::handle_event"); + thread->nwindow->raise_window(); + thread->nwindow->unlock_window(); + } + thread->window_lock->unlock(); return 1; } mwindow->edl->save_defaults(mwindow->defaults); @@ -97,10 +110,12 @@ NewThread::NewThread(MWindow *mwindow, New *new_project) { this->mwindow = mwindow; this->new_project = new_project; + window_lock = new Mutex("NewThread::window_lock"); } NewThread::~NewThread() { + delete window_lock; } @@ -109,17 +124,23 @@ void NewThread::run() int result = 0; load_defaults(); - { - nwindow = new NewWindow(mwindow, this); - nwindow->create_objects(); - result = nwindow->run_window(); - delete nwindow; -//printf("NewThread::run 1\n"); - new_project->new_edl->save_defaults(mwindow->defaults); -//printf("NewThread::run 2\n"); - mwindow->defaults->save(); -//printf("NewThread::run 3\n"); - } + int x = mwindow->gui->get_root_w(0, 1) / 2 - WIDTH / 2; + int y = mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2; + + window_lock->lock("NewThread::run 1\n"); + nwindow = new NewWindow(mwindow, this, x, y); + nwindow->create_objects(); + window_lock->unlock(); + + result = nwindow->run_window(); + + window_lock->lock("NewThread::run 2\n"); + delete nwindow; + nwindow = 0; + window_lock->unlock(); + + new_project->new_edl->save_defaults(mwindow->defaults); + mwindow->defaults->save(); if(result) { @@ -166,17 +187,14 @@ int NewThread::update_aspect() -#define WIDTH 600 -#define HEIGHT 400 - #if 0 N_("Cinelerra: New Project"); #endif -NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread) +NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y) : BC_Window(_(PROGRAM_NAME ": New Project"), - mwindow->gui->get_root_w() / 2 - WIDTH / 2, - mwindow->gui->get_root_h() / 2 - HEIGHT / 2, + x, + y, WIDTH, HEIGHT, -1, @@ -188,163 +206,12 @@ NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread) this->mwindow = mwindow; this->new_thread = new_thread; this->new_edl = new_thread->new_project->new_edl; + format_presets = 0; } NewWindow::~NewWindow() { - for(int i = 0; i < preset_items.total; i++) - delete preset_items.values[i]; -} - -void NewWindow::create_presets(int &x, int &y) -{ - NewPresetItem *item; - add_subwindow(new BC_Title(x, y, _("Presets:"))); - int x1 = x; - y += 20; - - item = new NewPresetItem(mwindow, this, _("User Defined")); - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("1080P")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = (double)60000.0 / 1001; -// item->edl->session->track_w = 1920; -// item->edl->session->track_h = 1080; - item->edl->session->output_w = 1920; - item->edl->session->output_h = 1080; - item->edl->session->aspect_w = 16; - item->edl->session->aspect_h = 9; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("1080I")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = (double)30000.0 / 1001; -// item->edl->session->track_w = 1920; -// item->edl->session->track_h = 1080; - item->edl->session->output_w = 1920; - item->edl->session->output_h = 1080; - item->edl->session->aspect_w = 16; - item->edl->session->aspect_h = 9; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("720P")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = (double)60000.0 / 1001; -// item->edl->session->track_w = 1280; -// item->edl->session->track_h = 720; - item->edl->session->output_w = 1280; - item->edl->session->output_h = 720; - item->edl->session->aspect_w = 16; - item->edl->session->aspect_h = 9; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("480P")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = (double)60000.0 / 1001; -// item->edl->session->track_w = 720; -// item->edl->session->track_h = 480; - item->edl->session->output_w = 720; - item->edl->session->output_h = 480; - item->edl->session->aspect_w = 4; - item->edl->session->aspect_h = 3; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("480I")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = (double)30000.0 / 1001; -// item->edl->session->track_w = 720; -// item->edl->session->track_h = 480; - item->edl->session->output_w = 720; - item->edl->session->output_h = 480; - item->edl->session->aspect_w = 4; - item->edl->session->aspect_h = 3; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("Half D-1 NTSC")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = (double)30000.0 / 1001; -// item->edl->session->track_w = 360; -// item->edl->session->track_h = 240; - item->edl->session->output_w = 360; - item->edl->session->output_h = 240; - item->edl->session->aspect_w = 4; - item->edl->session->aspect_h = 3; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("Internet")); - item->edl->session->audio_channels = 1; - item->edl->session->audio_tracks = 1; - item->edl->session->sample_rate = 22050; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 1; - item->edl->session->frame_rate = 15; -// item->edl->session->track_w = 320; -// item->edl->session->track_h = 240; - item->edl->session->output_w = 320; - item->edl->session->output_h = 240; - item->edl->session->aspect_w = 4; - item->edl->session->aspect_h = 3; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("CD Audio")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 44100; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 0; - item->edl->session->frame_rate = (double)30000.0 / 1001; -// item->edl->session->track_w = 720; -// item->edl->session->track_h = 480; - item->edl->session->output_w = 720; - item->edl->session->output_h = 480; - item->edl->session->aspect_w = 4; - item->edl->session->aspect_h = 3; - preset_items.append(item); - - item = new NewPresetItem(mwindow, this, _("DAT Audio")); - item->edl->session->audio_channels = 2; - item->edl->session->audio_tracks = 2; - item->edl->session->sample_rate = 48000; - item->edl->session->video_channels = 1; - item->edl->session->video_tracks = 0; - item->edl->session->frame_rate = (double)30000.0 / 1001; -// item->edl->session->track_w = 720; -// item->edl->session->track_h = 480; - item->edl->session->output_w = 720; - item->edl->session->output_h = 480; - item->edl->session->aspect_w = 4; - item->edl->session->aspect_h = 3; - preset_items.append(item); - - add_subwindow(presets_text = new NewPresetsText(mwindow, this, x, y)); - x += presets_text->get_w(); - add_subwindow(presets = new NewPresetsPulldown(mwindow, this, x, y)); - x = x1; + if(format_presets) delete format_presets; } int NewWindow::create_objects() @@ -356,7 +223,17 @@ int NewWindow::create_objects() add_subwindow(new BC_Title(x, y, _("Parameters for the new project:"))); y += 20; - create_presets(x, y); + + format_presets = new NewPresets(mwindow, + this, + x, + y); + format_presets->create_objects(); + x = format_presets->x; + y = format_presets->y; + + + y += 40; y1 = y; add_subwindow(new BC_Title(x, y, _("Audio"), LARGEFONT)); @@ -483,35 +360,6 @@ int NewWindow::create_objects() return 0; } - -int NewWindow::get_preset(EDL *edl) -{ - - for(int i = 1; i < preset_items.total; i++) - { - NewPresetItem *preset = preset_items.values[i]; - if(edl->session->audio_tracks == preset->edl->session->audio_tracks && - edl->session->audio_channels == preset->edl->session->audio_channels && - edl->session->sample_rate == preset->edl->session->sample_rate && - edl->session->video_tracks == preset->edl->session->video_tracks && - edl->session->frame_rate == preset->edl->session->frame_rate && - edl->session->output_w == preset->edl->session->output_w && - edl->session->output_h == preset->edl->session->output_h && - edl->session->aspect_w == preset->edl->session->aspect_w && - edl->session->aspect_h == preset->edl->session->aspect_h) - return i; - } - return 0; -} - -char* NewWindow::get_preset_text() -{ - int preset_number = get_preset(new_edl); - if(preset_number < preset_items.total) - return preset_items.values[preset_number]->get_text(); - return preset_items.values[0]->get_text(); -} - int NewWindow::update() { char string[BCTEXTLEN]; @@ -531,66 +379,30 @@ int NewWindow::update() -NewPresetsText::NewPresetsText(MWindow *mwindow, NewWindow *window, int x, int y) - : BC_TextBox(x, y, 200, 1, window->get_preset_text()) -{ - this->mwindow = mwindow; - this->window = window; -} -int NewPresetsText::handle_event() -{ - return 1; -} - - - - -NewPresetsPulldown::NewPresetsPulldown(MWindow *mwindow, NewWindow *window, int x, int y) - : BC_ListBox(x, - y, - 200, - 200, - LISTBOX_TEXT, // Display text list or icons - (ArrayList*)&window->preset_items, // Each column has an ArrayList of BC_ListBoxItems. - 0, // Titles for columns. Set to 0 for no titles - 0, // width of each column - 1, // Total columns. - 0, // Pixel of top of window. - 1) +NewPresets::NewPresets(MWindow *mwindow, NewWindow *gui, int x, int y) + : FormatPresets(mwindow, gui, 0, x, y) { - this->mwindow = mwindow; - this->window = window; } -int NewPresetsPulldown::handle_event() + +NewPresets::~NewPresets() { - NewPresetItem *preset = ((NewPresetItem*)get_selection(0, 0)); - window->new_edl->copy_all(preset->edl); - window->update(); - window->presets_text->update(preset->get_text()); - return 1; } -NewPresetItem::NewPresetItem(MWindow *mwindow, NewWindow *window, char *text) - : BC_ListBoxItem(text) +int NewPresets::handle_event() { - this->mwindow = mwindow; - this->window = window; - edl = new EDL; - edl->create_objects(); - edl->copy_all(window->new_edl); + new_gui->update(); + return 1; } -NewPresetItem::~NewPresetItem() +EDL* NewPresets::get_edl() { - delete edl; + return new_gui->new_edl; } - - NewATracks::NewATracks(NewWindow *nwindow, char *text, int x, int y) : BC_TextBox(x, y, 90, 1, text) { @@ -725,13 +537,9 @@ NewVTracksTumbler::NewVTracksTumbler(NewWindow *nwindow, int x, int y) } int NewVTracksTumbler::handle_up_event() { -printf("NewVTracks::handle_event 1 %f\n", nwindow->new_edl->session->frame_rate); nwindow->new_edl->session->video_tracks++; -printf("NewVTracks::handle_event 2 %d %f\n", nwindow->new_edl->session->video_tracks, nwindow->new_edl->session->frame_rate); nwindow->new_edl->boundaries(); -printf("NewVTracks::handle_event 3 %d %f\n", nwindow->new_edl->session->video_tracks, nwindow->new_edl->session->frame_rate); nwindow->update(); -printf("NewVTracks::handle_event 4 %d %f\n", nwindow->new_edl->session->video_tracks, nwindow->new_edl->session->frame_rate); return 1; } int NewVTracksTumbler::handle_down_event() diff --git a/hvirtual/cinelerra/new.h b/hvirtual/cinelerra/new.h index c118babb..0ebcbf1c 100644 --- a/hvirtual/cinelerra/new.h +++ b/hvirtual/cinelerra/new.h @@ -7,11 +7,13 @@ #include "filexml.inc" #include "guicast.h" #include "defaults.inc" +#include "formatpresets.h" #include "mwindow.inc" #include "thread.h" class NewThread; class NewWindow; +class NewPresets; class New : public BC_MenuItem { @@ -48,25 +50,17 @@ public: NewWindow *nwindow; MWindow *mwindow; New *new_project; + Mutex *window_lock; }; -class NewPresetsPulldown; -class NewPresetItem; -class NewPresetsText; - class NewWindow : public BC_Window { public: - NewWindow(MWindow *mwindow, NewThread *new_thread); + NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y); ~NewWindow(); - void create_presets(int &x, int &y); int create_objects(); int update(); -// Match the EDL configuration to a preset for displaying in the preset box. - int get_preset(EDL *edl); -// Get the text for the preset returned by get_preset - char* get_preset_text(); MWindow *mwindow; NewThread *new_thread; @@ -78,46 +72,19 @@ public: BC_TextBox *vchannels; BC_TextBox *frame_rate; BC_TextBox *aspect_w_text, *aspect_h_text; -// BC_TextBox *canvas_w_text, *canvas_h_text; BC_TextBox *output_w_text, *output_h_text; - NewPresetsPulldown *presets; - NewPresetsText *presets_text; - ArrayList preset_items; -}; - - - - -class NewPresetsText : public BC_TextBox -{ -public: - NewPresetsText(MWindow *mwindow, NewWindow *window, int x, int y); - int handle_event(); - MWindow *mwindow; - NewWindow *window; + NewPresets *format_presets; }; -class NewPresetsPulldown : public BC_ListBox +class NewPresets : public FormatPresets { public: - NewPresetsPulldown(MWindow *mwindow, NewWindow *window, int x, int y); + NewPresets(MWindow *mwindow, NewWindow *gui, int x, int y); + ~NewPresets(); int handle_event(); - MWindow *mwindow; - NewWindow *window; + EDL* get_edl(); }; -class NewPresetItem : public BC_ListBoxItem -{ -public: - NewPresetItem(MWindow *mwindow, NewWindow *window, char *text); - ~NewPresetItem(); - - MWindow *mwindow; - NewWindow *window; - EDL *edl; -}; - - diff --git a/hvirtual/cinelerra/newfolder.C b/hvirtual/cinelerra/newfolder.C index ff8cc6de..6b771531 100644 --- a/hvirtual/cinelerra/newfolder.C +++ b/hvirtual/cinelerra/newfolder.C @@ -74,7 +74,7 @@ void NewFolderThread::run() mwindow->new_folder(window->get_text()); } - change_lock.lock(); + change_lock.lock("NewFolderThread::run"); active = 0; change_lock.unlock(); delete window; @@ -83,7 +83,7 @@ void NewFolderThread::run() int NewFolderThread::interrupt() { - change_lock.lock(); + change_lock.lock("NewFolderThread::interrupt"); if(active) { window->lock_window(); @@ -93,22 +93,25 @@ int NewFolderThread::interrupt() change_lock.unlock(); - completion_lock.lock(); + completion_lock.lock("NewFolderThread::interrupt"); completion_lock.unlock(); return 0; } int NewFolderThread::start_new_folder() { - window = new NewFolder(mwindow, awindow, awindow->get_abs_cursor_x(), awindow->get_abs_cursor_y() - 120); + window = new NewFolder(mwindow, + awindow, + awindow->get_abs_cursor_x(1), + awindow->get_abs_cursor_y(1) - 120); window->create_objects(); - change_lock.lock(); + change_lock.lock("NewFolderThread::start_new_folder"); active = 1; change_lock.unlock(); Thread::start(); - completion_lock.lock(); + completion_lock.lock("NewFolderThread::start_new_folder"); return 0; } diff --git a/hvirtual/cinelerra/overlayframe.C b/hvirtual/cinelerra/overlayframe.C index c82a8e28..eacf17b3 100644 --- a/hvirtual/cinelerra/overlayframe.C +++ b/hvirtual/cinelerra/overlayframe.C @@ -3,6 +3,7 @@ #include #include #include +#include #include "clip.h" #include "edl.inc" @@ -10,12 +11,32 @@ #include "overlayframe.h" #include "vframe.h" -#if 1 - #define use_float 1 -#else - #define use_float 0 -#endif +// Easy abstraction of the float and int types. Most of these are never used +// but GCC expects them. +static int my_abs(int32_t x) +{ + return abs(x); +} +static int my_abs(uint32_t x) +{ + return x; +} + +static int my_abs(int64_t x) +{ + return llabs(x); +} + +static int my_abs(uint64_t x) +{ + return x; +} + +static float my_abs(float x) +{ + return fabsf(x); +} @@ -32,13 +53,11 @@ OverlayFrame::OverlayFrame(int cpus) OverlayFrame::~OverlayFrame() { -//printf("OverlayFrame::~OverlayFrame 1\n"); if(temp_frame) delete temp_frame; if(scale_engine) delete scale_engine; if(translate_engine) delete translate_engine; if(blend_engine) delete blend_engine; if(scaletranslate_engine) delete scaletranslate_engine; -//printf("OverlayFrame::~OverlayFrame 2\n"); } @@ -70,8 +89,8 @@ OverlayFrame::~OverlayFrame() r = output[0] ? (((temp_type)input1 * max) / output[0]) : max; \ if(chroma_offset) \ { \ - g = labs((int)input2 - chroma_offset) > labs((temp_type)output[1] - chroma_offset) ? input2 : output[1]; \ - b = labs((int)input3 - chroma_offset) > labs((temp_type)output[2] - chroma_offset) ? input3 : output[2]; \ + g = my_abs((temp_type)input2 - chroma_offset) > my_abs((temp_type)output[1] - chroma_offset) ? input2 : output[1]; \ + b = my_abs((temp_type)input3 - chroma_offset) > my_abs((temp_type)output[2] - chroma_offset) ? input3 : output[2]; \ } \ else \ { \ @@ -86,8 +105,8 @@ OverlayFrame::~OverlayFrame() r = ((temp_type)input1 * output[0]) / max; \ if(chroma_offset) \ { \ - g = labs((temp_type)input2 - chroma_offset) > labs((temp_type)output[1] - chroma_offset) ? input2 : output[1]; \ - b = labs((temp_type)input3 - chroma_offset) > labs((temp_type)output[2] - chroma_offset) ? input3 : output[2]; \ + g = my_abs((temp_type)input2 - chroma_offset) > my_abs((temp_type)output[1] - chroma_offset) ? input2 : output[1]; \ + b = my_abs((temp_type)input3 - chroma_offset) > my_abs((temp_type)output[2] - chroma_offset) ? input3 : output[2]; \ } \ else \ { \ @@ -126,9 +145,18 @@ OverlayFrame::~OverlayFrame() break; \ } \ \ - output[0] = (type)CLIP(r, 0, max); \ - output[1] = (type)CLIP(g, 0, max); \ - output[2] = (type)CLIP(b, 0, max); \ + if(sizeof(type) != 4) \ + { \ + output[0] = (type)CLIP(r, 0, max); \ + output[1] = (type)CLIP(g, 0, max); \ + output[2] = (type)CLIP(b, 0, max); \ + } \ + else \ + { \ + output[0] = r; \ + output[1] = g; \ + output[2] = b; \ + } \ } @@ -154,8 +182,8 @@ OverlayFrame::~OverlayFrame() r = output1 ? (((temp_type)input1 * max) / output1) : max; \ if(chroma_offset) \ { \ - g = labs((int)input2 - chroma_offset) > labs((int)output2 - chroma_offset) ? input2 : output2; \ - b = labs((int)input3 - chroma_offset) > labs((int)output3 - chroma_offset) ? input3 : output3; \ + g = my_abs((temp_type)input2 - chroma_offset) > my_abs((temp_type)output2 - chroma_offset) ? input2 : output2; \ + b = my_abs((temp_type)input3 - chroma_offset) > my_abs((temp_type)output3 - chroma_offset) ? input3 : output3; \ } \ else \ { \ @@ -171,8 +199,8 @@ OverlayFrame::~OverlayFrame() r = ((temp_type)input1 * output1) / max; \ if(chroma_offset) \ { \ - g = labs((temp_type)input2 - chroma_offset) > labs((temp_type)output2 - chroma_offset) ? input2 : output2; \ - b = labs((temp_type)input3 - chroma_offset) > labs((temp_type)output3 - chroma_offset) ? input3 : output3; \ + g = my_abs((temp_type)input2 - chroma_offset) > my_abs((temp_type)output2 - chroma_offset) ? input2 : output2; \ + b = my_abs((temp_type)input3 - chroma_offset) > my_abs((temp_type)output3 - chroma_offset) ? input3 : output3; \ } \ else \ { \ @@ -223,20 +251,24 @@ OverlayFrame::~OverlayFrame() break; \ } \ \ - output[0] = (type)CLIP(r, 0, max); \ - output[1] = (type)CLIP(g, 0, max); \ - output[2] = (type)CLIP(b, 0, max); \ - output[3] = (type)a; \ + if(sizeof(type) != 4) \ + { \ + output[0] = (type)CLIP(r, 0, max); \ + output[1] = (type)CLIP(g, 0, max); \ + output[2] = (type)CLIP(b, 0, max); \ + output[3] = (type)a; \ + } \ + else \ + { \ + output[0] = r; \ + output[1] = g; \ + output[2] = b; \ + output[3] = a; \ + } \ } - - - - - - // Bicubic algorithm using multiprocessors // input -> scale nearest integer boundaries -> temp -> translation -> blend -> output @@ -261,6 +293,14 @@ int OverlayFrame::overlay(VFrame *output, float w_scale = (out_x2 - out_x1) / (in_x2 - in_x1); float h_scale = (out_y2 - out_y1) / (in_y2 - in_y1); + if(isnan(in_x1) || + isnan(in_y1) || + isnan(in_x2) || + isnan(in_y2) || + isnan(out_x1) || + isnan(out_y1) || + isnan(out_x2) || + isnan(out_y2)) return 1; // printf("OverlayFrame::overlay 1 %f %f %f %f -> %f %f %f %f\n", in_x1, // in_y1, // in_x2, @@ -890,10 +930,14 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) { \ bilinear_table_t *x_entry = &x_table[j]; \ /* Load rounding factors */ \ - float temp_f1 = .5; \ - float temp_f2 = .5; \ - float temp_f3 = .5; \ - float temp_f4 = .5; \ + float temp_f1; \ + float temp_f2; \ + float temp_f3; \ + float temp_f4; \ + if(sizeof(type) != 4) \ + temp_f1 = temp_f2 = temp_f3 = temp_f4 = .5; \ + else \ + temp_f1 = temp_f2 = temp_f3 = temp_f4 = 0; \ \ /* First row */ \ float input_scale1 = y_entry->input_fraction1 * x_entry->input_fraction1; \ @@ -924,10 +968,13 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) } \ } \ \ - if(temp_f1 > max) temp_f1 = max; \ - if(temp_f2 > max) temp_f2 = max; \ - if(temp_f3 > max) temp_f3 = max; \ - if(components == 4) if(temp_f4 > max) temp_f4 = max; \ + if(max != 1.0) \ + { \ + if(temp_f1 > max) temp_f1 = max; \ + if(temp_f2 > max) temp_f2 = max; \ + if(temp_f3 > max) temp_f3 = max; \ + if(components == 4) if(temp_f4 > max) temp_f4 = max; \ + } \ out_row[j * components ] = (type)temp_f1; \ out_row[j * components + 1] = (type)temp_f2; \ out_row[j * components + 2] = (type)temp_f3; \ @@ -958,48 +1005,24 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) float *table_frac_x_f, *table_antifrac_x_f, *table_frac_y_f, *table_antifrac_y_f; \ int *table_frac_x_i, *table_antifrac_x_i, *table_frac_y_i, *table_antifrac_y_i; \ \ - if(use_float) \ - { \ - tabulate_blinear_f(table_int_x1, \ - table_int_x2, \ - table_frac_x_f, \ - table_antifrac_x_f, \ - k_x, \ - 0, \ - out_w_int, \ - in_x1_int, \ - in_w_int); \ - tabulate_blinear_f(table_int_y1, \ - table_int_y2, \ - table_frac_y_f, \ - table_antifrac_y_f, \ - k_y, \ - pkg->out_row1, \ - pkg->out_row2, \ - in_y1_int, \ - in_h_int); \ - } \ - else \ - { \ - tabulate_blinear_i(table_int_x1, \ - table_int_x2, \ - table_frac_x_i, \ - table_antifrac_x_i, \ - k_x, \ - 0, \ - out_w_int, \ - in_x1_int, \ - in_w_int); \ - tabulate_blinear_i(table_int_y1, \ - table_int_y2, \ - table_frac_y_i, \ - table_antifrac_y_i, \ - k_y, \ - pkg->out_row1, \ - pkg->out_row2, \ - in_y1_int, \ - in_h_int); \ - } \ + tabulate_blinear_f(table_int_x1, \ + table_int_x2, \ + table_frac_x_f, \ + table_antifrac_x_f, \ + k_x, \ + 0, \ + out_w_int, \ + in_x1_int, \ + in_w_int); \ + tabulate_blinear_f(table_int_y1, \ + table_int_y2, \ + table_frac_y_f, \ + table_antifrac_y_f, \ + k_y, \ + pkg->out_row1, \ + pkg->out_row2, \ + in_y1_int, \ + in_h_int); \ \ for(int i = 0; i < out_h; i++) \ { \ @@ -1009,16 +1032,8 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) float anti_a_f; \ uint64_t a_i; \ uint64_t anti_a_i; \ - if(use_float) \ - { \ - a_f = table_frac_y_f[i]; \ - anti_a_f = table_antifrac_y_f[i]; \ - } \ - else \ - { \ - a_i = table_frac_y_i[i]; \ - anti_a_i = table_antifrac_y_i[i]; \ - } \ + a_f = table_frac_y_f[i]; \ + anti_a_f = table_antifrac_y_f[i]; \ type *in_row1 = in_rows[i_y1]; \ type *in_row2 = in_rows[i_y2]; \ type *out_row = out_rows[i + pkg->out_row1]; \ @@ -1027,112 +1042,56 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) { \ int i_x1 = table_int_x1[j]; \ int i_x2 = table_int_x2[j]; \ - if(use_float) \ - { \ - float output1r, output1g, output1b, output1a; \ - float output2r, output2g, output2b, output2a; \ - float output3r, output3g, output3b, output3a; \ - float output4r, output4g, output4b, output4a; \ - float b_f; \ - float anti_b_f; \ - b_f = table_frac_x_f[j]; \ - anti_b_f = table_antifrac_x_f[j]; \ - \ - output1r = in_row1[i_x1 * components]; \ - output1g = in_row1[i_x1 * components + 1]; \ - output1b = in_row1[i_x1 * components + 2]; \ - if(components == 4) output1a = in_row1[i_x1 * components + 3]; \ - \ - output2r = in_row1[i_x2 * components]; \ - output2g = in_row1[i_x2 * components + 1]; \ - output2b = in_row1[i_x2 * components + 2]; \ - if(components == 4) output2a = in_row1[i_x2 * components + 3]; \ - \ - output3r = in_row2[i_x1 * components]; \ - output3g = in_row2[i_x1 * components + 1]; \ - output3b = in_row2[i_x1 * components + 2]; \ - if(components == 4) output3a = in_row2[i_x1 * components + 3]; \ + float output1r, output1g, output1b, output1a; \ + float output2r, output2g, output2b, output2a; \ + float output3r, output3g, output3b, output3a; \ + float output4r, output4g, output4b, output4a; \ + float b_f; \ + float anti_b_f; \ + b_f = table_frac_x_f[j]; \ + anti_b_f = table_antifrac_x_f[j]; \ \ - output4r = in_row2[i_x2 * components]; \ - output4g = in_row2[i_x2 * components + 1]; \ - output4b = in_row2[i_x2 * components + 2]; \ - if(components == 4) output4a = in_row2[i_x2 * components + 3]; \ - \ - out_row[j * components] = \ - (type)(anti_a_f * (anti_b_f * output1r + \ - b_f * output2r) + \ - a_f * (anti_b_f * output3r + \ - b_f * output4r)); \ - out_row[j * components + 1] = \ - (type)(anti_a_f * (anti_b_f * output1g + \ - b_f * output2g) + \ - a_f * ((anti_b_f * output3g) + \ - b_f * output4g)); \ - out_row[j * components + 2] = \ - (type)(anti_a_f * ((anti_b_f * output1b) + \ - (b_f * output2b)) + \ - a_f * ((anti_b_f * output3b) + \ - b_f * output4b)); \ - if(components == 4) \ - out_row[j * components + 3] = \ - (type)(anti_a_f * ((anti_b_f * output1a) + \ - (b_f * output2a)) + \ - a_f * ((anti_b_f * output3a) + \ - b_f * output4a)); \ - } \ - else \ - { \ - uint64_t output1r, output1g, output1b, output1a; \ - uint64_t output2r, output2g, output2b, output2a; \ - uint64_t output3r, output3g, output3b, output3a; \ - uint64_t output4r, output4g, output4b, output4a; \ - uint64_t b_i; \ - uint64_t anti_b_i; \ - b_i = table_frac_x_i[j]; \ - anti_b_i = table_antifrac_x_i[j]; \ - \ - output1r = in_row1[i_x1 * components]; \ - output1g = in_row1[i_x1 * components + 1]; \ - output1b = in_row1[i_x1 * components + 2]; \ - if(components == 4) output1a = in_row1[i_x1 * components + 3]; \ - \ - output2r = in_row1[i_x2 * components]; \ - output2g = in_row1[i_x2 * components + 1]; \ - output2b = in_row1[i_x2 * components + 2]; \ - if(components == 4) output2a = in_row1[i_x2 * components + 3]; \ - \ - output3r = in_row2[i_x1 * components]; \ - output3g = in_row2[i_x1 * components + 1]; \ - output3b = in_row2[i_x1 * components + 2]; \ - if(components == 4) output3a = in_row2[i_x1 * components + 3]; \ + output1r = in_row1[i_x1 * components]; \ + output1g = in_row1[i_x1 * components + 1]; \ + output1b = in_row1[i_x1 * components + 2]; \ + if(components == 4) output1a = in_row1[i_x1 * components + 3]; \ \ - output4r = in_row2[i_x2 * components]; \ - output4g = in_row2[i_x2 * components + 1]; \ - output4b = in_row2[i_x2 * components + 2]; \ - if(components == 4) output4a = in_row2[i_x2 * components + 3]; \ - \ - out_row[j * components] = \ - (type)((anti_a_i * (anti_b_i * output1r + \ - b_i * output2r) + \ - a_i * (anti_b_i * output3r + \ - b_i * output4r)) / 0xffffffff); \ - out_row[j * components + 1] = \ - (type)((anti_a_i * (anti_b_i * output1g + \ - b_i * output2g) + \ - a_i * (anti_b_i * output3g + \ - b_i * output4g)) / 0xffffffff); \ - out_row[j * components + 2] = \ - (type)((anti_a_i * (anti_b_i * output1b + \ - b_i * output2b) + \ - a_i * (anti_b_i * output3b + \ - b_i * output4b)) / 0xffffffff); \ - if(components == 4) \ - out_row[j * components + 3] = \ - (type)((anti_a_i * (anti_b_i * output1a + \ - b_i * output2a) + \ - a_i * (anti_b_i * output3a + \ - b_i * output4a)) / 0xffffffff); \ - } \ + output2r = in_row1[i_x2 * components]; \ + output2g = in_row1[i_x2 * components + 1]; \ + output2b = in_row1[i_x2 * components + 2]; \ + if(components == 4) output2a = in_row1[i_x2 * components + 3]; \ +\ + output3r = in_row2[i_x1 * components]; \ + output3g = in_row2[i_x1 * components + 1]; \ + output3b = in_row2[i_x1 * components + 2]; \ + if(components == 4) output3a = in_row2[i_x1 * components + 3]; \ +\ + output4r = in_row2[i_x2 * components]; \ + output4g = in_row2[i_x2 * components + 1]; \ + output4b = in_row2[i_x2 * components + 2]; \ + if(components == 4) output4a = in_row2[i_x2 * components + 3]; \ +\ + out_row[j * components] = \ + (type)(anti_a_f * (anti_b_f * output1r + \ + b_f * output2r) + \ + a_f * (anti_b_f * output3r + \ + b_f * output4r)); \ + out_row[j * components + 1] = \ + (type)(anti_a_f * (anti_b_f * output1g + \ + b_f * output2g) + \ + a_f * ((anti_b_f * output3g) + \ + b_f * output4g)); \ + out_row[j * components + 2] = \ + (type)(anti_a_f * ((anti_b_f * output1b) + \ + (b_f * output2b)) + \ + a_f * ((anti_b_f * output3b) + \ + b_f * output4b)); \ + if(components == 4) \ + out_row[j * components + 3] = \ + (type)(anti_a_f * ((anti_b_f * output1a) + \ + (b_f * output2a)) + \ + a_f * ((anti_b_f * output3a) + \ + b_f * output4a)); \ } \ } \ \ @@ -1141,20 +1100,10 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) delete [] table_int_x2; \ delete [] table_int_y1; \ delete [] table_int_y2; \ - if(use_float) \ - { \ - delete [] table_frac_x_f; \ - delete [] table_antifrac_x_f; \ - delete [] table_frac_y_f; \ - delete [] table_antifrac_y_f; \ - } \ - else \ - { \ - delete [] table_frac_x_i; \ - delete [] table_antifrac_x_i; \ - delete [] table_frac_y_i; \ - delete [] table_antifrac_y_i; \ - } \ + delete [] table_frac_x_f; \ + delete [] table_antifrac_x_f; \ + delete [] table_frac_y_f; \ + delete [] table_antifrac_y_f; \ \ /*printf("BILINEAR_ENLARGE 2\n");*/ \ } @@ -1172,42 +1121,21 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) int in_h_int = input->get_h(); \ int in_w_int = input->get_w(); \ \ - if(use_float) \ - { \ - tabulate_bcubic_f(bspline_x_f, \ - in_x_table, \ - k_x, \ - in_x1_int, \ - out_w_int, \ - in_w_int, \ - -1); \ - \ - tabulate_bcubic_f(bspline_y_f, \ - in_y_table, \ - k_y, \ - in_y1_int, \ - out_h_int, \ - in_h_int, \ - 1); \ - } \ - else \ - { \ - tabulate_bcubic_i(bspline_x_i, \ - in_x_table, \ - k_x, \ - in_x1_int, \ - out_w_int, \ - in_w_int, \ - -1); \ - \ - tabulate_bcubic_i(bspline_y_i, \ - in_y_table, \ - k_y, \ - in_y1_int, \ - out_h_int, \ - in_h_int, \ - 1); \ - } \ + tabulate_bcubic_f(bspline_x_f, \ + in_x_table, \ + k_x, \ + in_x1_int, \ + out_w_int, \ + in_w_int, \ + -1); \ + \ + tabulate_bcubic_f(bspline_y_f, \ + in_y_table, \ + k_y, \ + in_y1_int, \ + out_h_int, \ + in_h_int, \ + 1); \ \ for(int i = pkg->out_row1; i < pkg->out_row2; i++) \ { \ @@ -1216,22 +1144,11 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) int i_x = (int)(k_x * j); \ float output1_f, output2_f, output3_f, output4_f; \ uint64_t output1_i, output2_i, output3_i, output4_i; \ - if(use_float) \ - { \ - output1_f = 0; \ - output2_f = 0; \ - output3_f = 0; \ - if(components == 4) \ - output4_f = 0; \ - } \ - else \ - { \ - output1_i = 0; \ - output2_i = 0; \ - output3_i = 0; \ - if(components == 4) \ - output4_i = 0; \ - } \ + output1_f = 0; \ + output2_f = 0; \ + output3_f = 0; \ + if(components == 4) \ + output4_f = 0; \ int table_y = i * 4; \ \ /* Kernel */ \ @@ -1239,10 +1156,7 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) { \ float r1_f; \ uint64_t r1_i; \ - if(use_float) \ - r1_f = bspline_y_f[table_y]; \ - else \ - r1_i = bspline_y_i[table_y]; \ + r1_f = bspline_y_f[table_y]; \ int y = in_y_table[table_y]; \ int table_x = j * 4; \ \ @@ -1250,31 +1164,16 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) { \ float r2_f; \ uint64_t r2_i; \ - if(use_float) \ - r2_f = bspline_x_f[table_x]; \ - else \ - r2_i = bspline_x_i[table_x]; \ + r2_f = bspline_x_f[table_x]; \ int x = in_x_table[table_x]; \ float r_square_f; \ uint64_t r_square_i; \ - if(use_float) \ - { \ - r_square_f = r1_f * r2_f; \ - output1_f += r_square_f * in_rows[y][x * components]; \ - output2_f += r_square_f * in_rows[y][x * components + 1]; \ - output3_f += r_square_f * in_rows[y][x * components + 2]; \ - if(components == 4) \ - output4_f += r_square_f * in_rows[y][x * components + 3]; \ - } \ - else \ - { \ - r_square_i = r1_i * r2_i; \ - output1_i += r_square_i * in_rows[y][x * components]; \ - output2_i += r_square_i * in_rows[y][x * components + 1]; \ - output3_i += r_square_i * in_rows[y][x * components + 2]; \ - if(components == 4) \ - output4_i += r_square_i * in_rows[y][x * components + 3]; \ - } \ + r_square_f = r1_f * r2_f; \ + output1_f += r_square_f * in_rows[y][x * components]; \ + output2_f += r_square_f * in_rows[y][x * components + 1]; \ + output3_f += r_square_f * in_rows[y][x * components + 2]; \ + if(components == 4) \ + output4_f += r_square_f * in_rows[y][x * components + 3]; \ \ table_x++; \ } \ @@ -1282,36 +1181,17 @@ void ScaleUnit::dump_bilinear(bilinear_table_t *table, int total) } \ \ \ - if(use_float) \ - { \ - out_rows[i][j * components] = (type)output1_f; \ - out_rows[i][j * components + 1] = (type)output2_f; \ - out_rows[i][j * components + 2] = (type)output3_f; \ - if(components == 4) \ - out_rows[i][j * components + 3] = (type)output4_f; \ - } \ - else \ - { \ - out_rows[i][j * components] = (type)(output1_i / 0xffffffff); \ - out_rows[i][j * components + 1] = (type)(output2_i / 0xffffffff); \ - out_rows[i][j * components + 2] = (type)(output3_i / 0xffffffff); \ - if(components == 4) \ - out_rows[i][j * components + 3] = (type)(output4_i / 0xffffffff); \ - } \ + out_rows[i][j * components] = (type)output1_f; \ + out_rows[i][j * components + 1] = (type)output2_f; \ + out_rows[i][j * components + 2] = (type)output3_f; \ + if(components == 4) \ + out_rows[i][j * components + 3] = (type)output4_f; \ \ } \ } \ \ - if(use_float) \ - { \ - delete [] bspline_x_f; \ - delete [] bspline_y_f; \ - } \ - else \ - { \ - delete [] bspline_x_i; \ - delete [] bspline_y_i; \ - } \ + delete [] bspline_x_f; \ + delete [] bspline_y_f; \ delete [] in_x_table; \ delete [] in_y_table; \ } @@ -1510,6 +1390,14 @@ void ScaleUnit::process_package(LoadPackage *package) { switch(engine->scale_input->get_color_model()) { + case BC_RGB_FLOAT: + BICUBIC(1.0, float, 3); + break; + + case BC_RGBA_FLOAT: + BICUBIC(1.0, float, 4); + break; + case BC_RGB888: case BC_YUV888: BICUBIC(0xff, unsigned char, 3); @@ -1532,13 +1420,20 @@ void ScaleUnit::process_package(LoadPackage *package) } } else +// Perform bilinear scaling input -> scale_output if(engine->w_scale > 1 && engine->h_scale > 1) -//if(0) -// Perform bilinear scaling input -> scale_output { switch(engine->scale_input->get_color_model()) { + case BC_RGB_FLOAT: + BILINEAR_ENLARGE(1.0, float, 3); + break; + + case BC_RGBA_FLOAT: + BILINEAR_ENLARGE(1.0, float, 4); + break; + case BC_RGB888: case BC_YUV888: BILINEAR_ENLARGE(0xff, unsigned char, 3); @@ -1561,9 +1456,16 @@ void ScaleUnit::process_package(LoadPackage *package) } } else +// Bilinear reduction { switch(engine->scale_input->get_color_model()) { + case BC_RGB_FLOAT: + BILINEAR_REDUCE(1.0, float, 3); + break; + case BC_RGBA_FLOAT: + BILINEAR_REDUCE(1.0, float, 4); + break; case BC_RGB888: case BC_YUV888: BILINEAR_REDUCE(0xff, unsigned char, 3); @@ -1872,13 +1774,17 @@ void TranslateUnit::translation_array_i(transfer_table_i* &table, type **in_rows = (type**)input->get_rows(); \ type **out_rows = (type**)output->get_rows(); \ \ -/* printf("OverlayFrame::translate 1 %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", */ \ -/* (in_x1), in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2); */ \ \ - temp_type master_opacity = (temp_type)(alpha * max + 0.5); \ + temp_type master_opacity; \ + if(sizeof(type) != 4) \ + master_opacity = (temp_type)(alpha * max + 0.5); \ + else \ + master_opacity = (temp_type)(alpha * max); \ temp_type master_transparency = max - master_opacity; \ + float round = 0.0; \ + if(sizeof(type) != 4) \ + round = 0.5; \ \ -/* printf("TRANSLATE %d\n", mode); */ \ \ for(int i = row1; i < row2; i++) \ { \ @@ -1887,25 +1793,11 @@ void TranslateUnit::translation_array_i(transfer_table_i* &table, float y_fraction1_f; \ float y_fraction2_f; \ float y_output_fraction_f; \ - uint64_t y_fraction1_i; \ - uint64_t y_fraction2_i; \ - uint64_t y_output_fraction_i; \ - if(use_float) \ - { \ - in_y1 = y_table_f[i - out_y1_int].in_x1; \ - in_y2 = y_table_f[i - out_y1_int].in_x2; \ - y_fraction1_f = y_table_f[i - out_y1_int].in_fraction1; \ - y_fraction2_f = y_table_f[i - out_y1_int].in_fraction2; \ - y_output_fraction_f = y_table_f[i - out_y1_int].output_fraction; \ - } \ - else \ - { \ - in_y1 = y_table_i[i - out_y1_int].in_x1; \ - in_y2 = y_table_i[i - out_y1_int].in_x2; \ - y_fraction1_i = y_table_i[i - out_y1_int].in_fraction1; \ - y_fraction2_i = y_table_i[i - out_y1_int].in_fraction2; \ - y_output_fraction_i = y_table_i[i - out_y1_int].output_fraction; \ - } \ + in_y1 = y_table_f[i - out_y1_int].in_x1; \ + in_y2 = y_table_f[i - out_y1_int].in_x2; \ + y_fraction1_f = y_table_f[i - out_y1_int].in_fraction1; \ + y_fraction2_f = y_table_f[i - out_y1_int].in_fraction2; \ + y_output_fraction_f = y_table_f[i - out_y1_int].output_fraction; \ type *in_row1 = in_rows[(in_y1)]; \ type *in_row2 = in_rows[(in_y2)]; \ type *out_row = out_rows[i]; \ @@ -1917,138 +1809,70 @@ void TranslateUnit::translation_array_i(transfer_table_i* &table, float x_fraction1_f; \ float x_fraction2_f; \ float x_output_fraction_f; \ - uint64_t x_fraction1_i; \ - uint64_t x_fraction2_i; \ - uint64_t x_output_fraction_i; \ - if(use_float) \ - { \ - in_x1 = x_table_f[j - out_x1_int].in_x1; \ - in_x2 = x_table_f[j - out_x1_int].in_x2; \ - x_fraction1_f = x_table_f[j - out_x1_int].in_fraction1; \ - x_fraction2_f = x_table_f[j - out_x1_int].in_fraction2; \ - x_output_fraction_f = x_table_f[j - out_x1_int].output_fraction; \ - } \ - else \ - { \ - in_x1 = x_table_i[j - out_x1_int].in_x1; \ - in_x2 = x_table_i[j - out_x1_int].in_x2; \ - x_fraction1_i = x_table_i[j - out_x1_int].in_fraction1; \ - x_fraction2_i = x_table_i[j - out_x1_int].in_fraction2; \ - x_output_fraction_i = x_table_i[j - out_x1_int].output_fraction; \ - } \ + in_x1 = x_table_f[j - out_x1_int].in_x1; \ + in_x2 = x_table_f[j - out_x1_int].in_x2; \ + x_fraction1_f = x_table_f[j - out_x1_int].in_fraction1; \ + x_fraction2_f = x_table_f[j - out_x1_int].in_fraction2; \ + x_output_fraction_f = x_table_f[j - out_x1_int].output_fraction; \ type *output = &out_row[j * components]; \ - type input1, input2, input3, input4; \ + temp_type input1, input2, input3, input4; \ + \ + float fraction1 = x_fraction1_f * y_fraction1_f; \ + float fraction2 = x_fraction2_f * y_fraction1_f; \ + float fraction3 = x_fraction1_f * y_fraction2_f; \ + float fraction4 = x_fraction2_f * y_fraction2_f; \ + \ + input1 = (type)(in_row1[in_x1 * components] * fraction1 + \ + in_row1[in_x2 * components] * fraction2 + \ + in_row2[in_x1 * components] * fraction3 + \ + in_row2[in_x2 * components] * fraction4 + round); \ \ - if(use_float) \ - { \ - float fraction1 = x_fraction1_f * y_fraction1_f; \ - float fraction2 = x_fraction2_f * y_fraction1_f; \ - float fraction3 = x_fraction1_f * y_fraction2_f; \ - float fraction4 = x_fraction2_f * y_fraction2_f; \ - \ - input1 = (type)(in_row1[in_x1 * components] * fraction1 + \ - in_row1[in_x2 * components] * fraction2 + \ - in_row2[in_x1 * components] * fraction3 + \ - in_row2[in_x2 * components] * fraction4 + 0.5); \ - \ /* Add chroma to fractional pixels */ \ - if(chroma_offset) \ - { \ - float extra_chroma = (1.0F - \ - fraction1 - \ - fraction2 - \ - fraction3 - \ - fraction4) * chroma_offset; \ - input2 = (type)(in_row1[in_x1 * components + 1] * fraction1 + \ - in_row1[in_x2 * components + 1] * fraction2 + \ - in_row2[in_x1 * components + 1] * fraction3 + \ - in_row2[in_x2 * components + 1] * fraction4 + \ - extra_chroma + 0.5); \ - input3 = (type)(in_row1[in_x1 * components + 2] * fraction1 + \ - in_row1[in_x2 * components + 2] * fraction2 + \ - in_row2[in_x1 * components + 2] * fraction3 + \ - in_row2[in_x2 * components + 2] * fraction4 + \ - extra_chroma + 0.5); \ - } \ - else \ - { \ - input2 = (type)(in_row1[in_x1 * components + 1] * fraction1 + \ - in_row1[in_x2 * components + 1] * fraction2 + \ - in_row2[in_x1 * components + 1] * fraction3 + \ - in_row2[in_x2 * components + 1] * fraction4 + 0.5); \ - input3 = (type)(in_row1[in_x1 * components + 2] * fraction1 + \ - in_row1[in_x2 * components + 2] * fraction2 + \ - in_row2[in_x1 * components + 2] * fraction3 + \ - in_row2[in_x2 * components + 2] * fraction4 + 0.5); \ - } \ - \ - if(components == 4) \ - input4 = (type)(in_row1[in_x1 * components + 3] * fraction1 + \ - in_row1[in_x2 * components + 3] * fraction2 + \ - in_row2[in_x1 * components + 3] * fraction3 + \ - in_row2[in_x2 * components + 3] * fraction4 + 0.5); \ + if(chroma_offset) \ + { \ + float extra_chroma = (1.0F - \ + fraction1 - \ + fraction2 - \ + fraction3 - \ + fraction4) * chroma_offset; \ + input2 = (type)(in_row1[in_x1 * components + 1] * fraction1 + \ + in_row1[in_x2 * components + 1] * fraction2 + \ + in_row2[in_x1 * components + 1] * fraction3 + \ + in_row2[in_x2 * components + 1] * fraction4 + \ + extra_chroma + round); \ + input3 = (type)(in_row1[in_x1 * components + 2] * fraction1 + \ + in_row1[in_x2 * components + 2] * fraction2 + \ + in_row2[in_x1 * components + 2] * fraction3 + \ + in_row2[in_x2 * components + 2] * fraction4 + \ + extra_chroma + round); \ } \ else \ { \ - uint64_t fraction1 = x_fraction1_i * y_fraction1_i; \ - uint64_t fraction2 = x_fraction2_i * y_fraction1_i; \ - uint64_t fraction3 = x_fraction1_i * y_fraction2_i; \ - uint64_t fraction4 = x_fraction2_i * y_fraction2_i; \ - \ - input1 = (type)((in_row1[in_x1 * components] * fraction1 + \ - in_row1[in_x2 * components] * fraction2 + \ - in_row2[in_x1 * components] * fraction3 + \ - in_row2[in_x2 * components] * fraction4) / 0xffffffff); \ - \ -/* Add chroma to fractional pixels */ \ - if(chroma_offset) \ - { \ - uint64_t extra_chroma = (0xffffffff - \ - fraction1 - \ - fraction2 - \ - fraction3 - \ - fraction4) * \ - chroma_offset; \ - input2 = (type)((in_row1[in_x1 * components + 1] * fraction1 + \ - in_row1[in_x2 * components + 1] * fraction2 + \ - in_row2[in_x1 * components + 1] * fraction3 + \ - in_row2[in_x2 * components + 1] * fraction4 + \ - extra_chroma) / 0xffffffff); \ - input3 = (type)((in_row1[in_x1 * components + 2] * fraction1 + \ - in_row1[in_x2 * components + 2] * fraction2 + \ - in_row2[in_x1 * components + 2] * fraction3 + \ - in_row2[in_x2 * components + 2] * fraction4 + \ - extra_chroma) / 0xffffffff); \ - } \ - else \ - { \ - input2 = (type)((in_row1[in_x1 * components + 1] * fraction1 + \ - in_row1[in_x2 * components + 1] * fraction2 + \ - in_row2[in_x1 * components + 1] * fraction3 + \ - in_row2[in_x2 * components + 1] * fraction4) / 0xffffffff); \ - input3 = (type)((in_row1[in_x1 * components + 2] * fraction1 + \ - in_row1[in_x2 * components + 2] * fraction2 + \ - in_row2[in_x1 * components + 2] * fraction3 + \ - in_row2[in_x2 * components + 2] * fraction4) / 0xffffffff); \ - } \ - \ - if(components == 4) \ - input4 = (type)((in_row1[in_x1 * components + 3] * fraction1 + \ - in_row1[in_x2 * components + 3] * fraction2 + \ - in_row2[in_x1 * components + 3] * fraction3 + \ - in_row2[in_x2 * components + 3] * fraction4) / 0xffffffff); \ + input2 = (type)(in_row1[in_x1 * components + 1] * fraction1 + \ + in_row1[in_x2 * components + 1] * fraction2 + \ + in_row2[in_x1 * components + 1] * fraction3 + \ + in_row2[in_x2 * components + 1] * fraction4 + round); \ + input3 = (type)(in_row1[in_x1 * components + 2] * fraction1 + \ + in_row1[in_x2 * components + 2] * fraction2 + \ + in_row2[in_x1 * components + 2] * fraction3 + \ + in_row2[in_x2 * components + 2] * fraction4 + round); \ } \ \ + if(components == 4) \ + input4 = (type)(in_row1[in_x1 * components + 3] * fraction1 + \ + in_row1[in_x2 * components + 3] * fraction2 + \ + in_row2[in_x1 * components + 3] * fraction3 + \ + in_row2[in_x2 * components + 3] * fraction4 + round); \ + \ temp_type opacity; \ - if(use_float) \ + if(sizeof(type) != 4) \ opacity = (temp_type)(master_opacity * \ y_output_fraction_f * \ x_output_fraction_f + 0.5); \ else \ - opacity = (temp_type)((int64_t)master_opacity * \ - y_output_fraction_i * \ - x_output_fraction_i / \ - 0xffffffff); \ + opacity = (temp_type)(master_opacity * \ + y_output_fraction_f * \ + x_output_fraction_f); \ temp_type transparency = max - opacity; \ \ /* printf("TRANSLATE 2 %x %d %d\n", opacity, j, i); */ \ @@ -2102,48 +1926,24 @@ void TranslateUnit::process_package(LoadPackage *package) transfer_table_i *x_table_i; transfer_table_i *y_table_i; - if(use_float) - { - translation_array_f(x_table_f, - out_x1, - out_x2, - in_x1, - in_x2, - in_total_x, - output->get_w(), - out_x1_int, - out_x2_int); - translation_array_f(y_table_f, - out_y1, - out_y2, - in_y1, - in_y2, - in_total_y, - output->get_h(), - out_y1_int, - out_y2_int); - } - else - { - translation_array_i(x_table_i, - out_x1, - out_x2, - in_x1, - in_x2, - in_total_x, - output->get_w(), - out_x1_int, - out_x2_int); - translation_array_i(y_table_i, - out_y1, - out_y2, - in_y1, - in_y2, - in_total_y, - output->get_h(), - out_y1_int, - out_y2_int); - } + translation_array_f(x_table_f, + out_x1, + out_x2, + in_x1, + in_x2, + in_total_x, + output->get_w(), + out_x1_int, + out_x2_int); + translation_array_f(y_table_f, + out_y1, + out_y2, + in_y1, + in_y2, + in_total_y, + output->get_h(), + out_y1_int, + out_y2_int); // printf("TranslateUnit::process_package 1 %d\n", mode); // Timer a; // a.update(); @@ -2158,6 +1958,14 @@ void TranslateUnit::process_package(LoadPackage *package) TRANSLATE(0xff, uint32_t, unsigned char, 4, 0); break; + case BC_RGB_FLOAT: + TRANSLATE(1.0, float, float, 3, 0); + break; + + case BC_RGBA_FLOAT: + TRANSLATE(1.0, float, float, 4, 0); + break; + case BC_RGB161616: TRANSLATE(0xffff, uint64_t, uint16_t, 3, 0); break; @@ -2184,16 +1992,8 @@ void TranslateUnit::process_package(LoadPackage *package) } // printf("blend mode %i, took %li ms\n", mode, a.get_difference()); - if(use_float) - { - delete [] x_table_f; - delete [] y_table_f; - } - else - { - delete [] x_table_i; - delete [] y_table_i; - } + delete [] x_table_f; + delete [] y_table_f; } @@ -2254,7 +2054,11 @@ LoadPackage* TranslateEngine::new_package() #define SCALE_TRANSLATE(max, temp_type, type, components, chroma_offset) \ { \ - temp_type opacity = (temp_type)(alpha * max + 0.5); \ + temp_type opacity; \ + if(sizeof(type) != 4) \ + opacity = (temp_type)(alpha * max + 0.5); \ + else \ + opacity = (temp_type)(alpha * max); \ temp_type transparency = max - opacity; \ \ for(int i = pkg->out_row1; i < pkg->out_row2; i++) \ @@ -2423,6 +2227,10 @@ void ScaleTranslateUnit::process_package(LoadPackage *package) SCALE_TRANSLATE(0xff, uint32_t, uint8_t, 3, 0); break; + case BC_RGB_FLOAT: + SCALE_TRANSLATE(1.0, float, float, 3, 0); + break; + case BC_YUV888: SCALE_TRANSLATE(0xff, int32_t, uint8_t, 3, 0x80); break; @@ -2431,6 +2239,10 @@ void ScaleTranslateUnit::process_package(LoadPackage *package) SCALE_TRANSLATE(0xff, uint32_t, uint8_t, 4, 0); break; + case BC_RGBA_FLOAT: + SCALE_TRANSLATE(1.0, float, float, 4, 0); + break; + case BC_YUVA8888: SCALE_TRANSLATE(0xff, int32_t, uint8_t, 4, 0x80); break; @@ -2540,7 +2352,11 @@ ScaleTranslatePackage::ScaleTranslatePackage() #define BLEND_ONLY(temp_type, type, max, components, chroma_offset) \ { \ - temp_type opacity = (temp_type)(alpha * max + 0.5); \ + temp_type opacity; \ + if(sizeof(type) != 4) \ + opacity = (temp_type)(alpha * max + 0.5); \ + else \ + opacity = (temp_type)(alpha * max); \ temp_type transparency = max - opacity; \ \ type** output_rows = (type**)output->get_rows(); \ @@ -2636,6 +2452,8 @@ ScaleTranslatePackage::ScaleTranslatePackage() } \ } + + // components is always 3 #define BLEND_ONLY_3_NORMAL(temp_type, type, max, chroma_offset) \ { \ @@ -2663,6 +2481,7 @@ ScaleTranslatePackage::ScaleTranslatePackage() } + BlendUnit::BlendUnit(BlendEngine *server, OverlayFrame *overlay) : LoadClient(server) { @@ -2688,6 +2507,12 @@ void BlendUnit::process_package(LoadPackage *package) { switch(input->get_color_model()) { + case BC_RGB_FLOAT: + BLEND_ONLY_TRANSFER_REPLACE(float, 3); + break; + case BC_RGBA_FLOAT: + BLEND_ONLY_TRANSFER_REPLACE(float, 4); + break; case BC_RGB888: case BC_YUV888: BLEND_ONLY_TRANSFER_REPLACE(unsigned char, 3); @@ -2711,6 +2536,66 @@ void BlendUnit::process_package(LoadPackage *package) { switch(input->get_color_model()) { + case BC_RGB_FLOAT: + { + float opacity = alpha; + float transparency = 1.0 - alpha; + + float** output_rows = (float**)output->get_rows(); + float** input_rows = (float**)input->get_rows(); + int w = input->get_w() * 3; + int h = input->get_h(); + + for(int i = pkg->out_row1; i < pkg->out_row2; i++) + { + float* in_row = input_rows[i]; + float* output = output_rows[i]; +/* w = 3x width! */ + for(int j = 0; j < w; j++) + { + *output = *in_row * opacity + *output * transparency; + in_row++; + output++; + } + } + break; + } + case BC_RGBA_FLOAT: + { + float opacity = alpha; + float transparency = 1.0 - alpha; + + float** output_rows = (float**)output->get_rows(); + float** input_rows = (float**)input->get_rows(); + int w = input->get_w(); + int h = input->get_h(); + + for(int i = pkg->out_row1; i < pkg->out_row2; i++) + { + float* in_row = input_rows[i]; + float* output = output_rows[i]; + + for(int j = 0; j < w; j++) + { + float pixel_opacity, pixel_transparency; + pixel_opacity = opacity * in_row[3]; + pixel_transparency = 1.0 - pixel_opacity; + + + output[0] = in_row[0] * pixel_opacity + + output[0] * pixel_transparency; + output[1] = in_row[1] * pixel_opacity + + output[1] * pixel_transparency; + output[2] = in_row[2] * pixel_opacity + + output[2] * pixel_transparency; + output[3] = in_row[3] > output[3] ? in_row[3] : output[3]; + + in_row += 4; + output += 4; + } + } + break; + } case BC_RGB888: BLEND_ONLY_3_NORMAL(uint32_t, unsigned char, 0xff, 0); break; @@ -2736,10 +2621,16 @@ void BlendUnit::process_package(LoadPackage *package) BLEND_ONLY_4_NORMAL(int64_t, uint16_t, 0xffff, 0x8000); break; } - } + } else switch(input->get_color_model()) { + case BC_RGB_FLOAT: + BLEND_ONLY(float, float, 1.0, 3, 0); + break; + case BC_RGBA_FLOAT: + BLEND_ONLY(float, float, 1.0, 4, 0); + break; case BC_RGB888: BLEND_ONLY(uint32_t, unsigned char, 0xff, 3, 0); break; diff --git a/hvirtual/cinelerra/overlayframe.h b/hvirtual/cinelerra/overlayframe.h index e2a28feb..a3bd899d 100644 --- a/hvirtual/cinelerra/overlayframe.h +++ b/hvirtual/cinelerra/overlayframe.h @@ -81,6 +81,7 @@ public: ~ScaleUnit(); float cubic_bspline(float x); + void tabulate_bcubic_f(float* &coef_table, int* &coord_table, float scale, diff --git a/hvirtual/cinelerra/packagedispatcher.C b/hvirtual/cinelerra/packagedispatcher.C index 217e1ea9..ed29f607 100644 --- a/hvirtual/cinelerra/packagedispatcher.C +++ b/hvirtual/cinelerra/packagedispatcher.C @@ -16,7 +16,7 @@ PackageDispatcher::PackageDispatcher() { packages = 0; - package_lock = new Mutex; + package_lock = new Mutex("PackageDispatcher::package_lock"); } PackageDispatcher::~PackageDispatcher() @@ -226,7 +226,7 @@ RenderPackage* PackageDispatcher::get_package(double frames_per_second, int client_number, int use_local_rate) { - package_lock->lock(); + package_lock->lock("PackageDispatcher::get_package"); // printf("PackageDispatcher::get_package 1 %f\n", // frames_per_second); diff --git a/hvirtual/cinelerra/packagerenderer.C b/hvirtual/cinelerra/packagerenderer.C index 86d54aa3..bead5357 100644 --- a/hvirtual/cinelerra/packagerenderer.C +++ b/hvirtual/cinelerra/packagerenderer.C @@ -105,14 +105,14 @@ int PackageRenderer::initialize(MWindow *mwindow, default_asset->sample_rate = command->get_edl()->session->sample_rate; default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w / command->get_edl()->session->aspect_h; - Render::check_asset(edl, *default_asset); + result = Render::check_asset(edl, *default_asset); audio_cache = new CICache(command->get_edl(), preferences, plugindb); video_cache = new CICache(command->get_edl(), preferences, plugindb); - PlaybackConfig *config = command->get_edl()->session->get_playback_config(PLAYBACK_LOCALHOST, 0); - aconfig = new AudioOutConfig(PLAYBACK_LOCALHOST, 0, 0); - vconfig = new VideoOutConfig(PLAYBACK_LOCALHOST, 0); + PlaybackConfig *config = command->get_edl()->session->playback_config; + aconfig = new AudioOutConfig(0); + vconfig = new VideoOutConfig; // playback_config = new PlaybackConfig(PLAYBACK_LOCALHOST, 0); for(int i = 0; i < MAX_CHANNELS; i++) { @@ -133,7 +133,7 @@ void PackageRenderer::create_output() // Tag output paths for VFS here. - if(!mwindow && preferences->renderfarm_vfs) + if(!mwindow && preferences->renderfarm_vfs && preferences->use_renderfarm) sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", package->path); else strcpy(asset->path, package->path); @@ -160,8 +160,8 @@ void PackageRenderer::create_output() char string[BCTEXTLEN]; sprintf(string, _("Couldn't open %s"), asset->path); ErrorBox error(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error.create_objects(string); error.run_window(); } @@ -187,7 +187,6 @@ void PackageRenderer::create_engine() command, 0, plugindb, - 0, 0); render_engine->set_acache(audio_cache); render_engine->set_vcache(video_cache); @@ -356,12 +355,14 @@ void PackageRenderer::do_video() // Get a buffer for background writing. +//printf("PackageRenderer::do_video 3\n"); if(video_write_position == 0) video_output = file->get_video_buffer(); +//printf("PackageRenderer::do_video 4\n"); // Construct layered output buffer @@ -370,13 +371,13 @@ void PackageRenderer::do_video() (i < asset->layers) ? video_output[i][video_write_position] : 0; -//printf("PackageRenderer::do_video 6\n"); result |= render_engine->vrender->process_buffer( video_output_ptr, video_position, 0); +//printf("PackageRenderer::do_video 5\n"); if(mwindow && video_device->output_visible()) { @@ -385,29 +386,30 @@ void PackageRenderer::do_video() video_device->new_output_buffers(preview_output, command->get_edl()->session->color_model); -//printf("PackageRenderer::do_video 8\n"); for(int i = 0; i < MAX_CHANNELS; i++) if(preview_output[i]) preview_output[i]->copy_from(video_output_ptr[i]); -//printf("PackageRenderer::do_video 9\n"); video_device->write_buffer(preview_output, command->get_edl()); -//printf("PackageRenderer::do_video 10\n"); } +//printf("PackageRenderer::do_video 6\n"); // Write to file if(video_preroll) { +//printf("PackageRenderer::do_video 6.1\n"); video_preroll--; // Keep the write position at 0 until ready to write real frames result |= file->write_video_buffer(0); +//printf("PackageRenderer::do_video 6.2\n"); video_write_position = 0; } else { +//printf("PackageRenderer::do_video 7\n"); // Set background rendering parameters if(package->use_brender) { @@ -415,10 +417,13 @@ void PackageRenderer::do_video() video_output_ptr[0]->set_number(video_position); } video_write_position++; +//printf("PackageRenderer::do_video 8\n"); if(video_write_position >= video_write_length) { +//printf("PackageRenderer::do_video 9\n"); result |= file->write_video_buffer(video_write_position); +//printf("PackageRenderer::do_video 10\n"); // Update the brender map after writing the files. if(package->use_brender) for(int i = 0; i < video_write_position; i++) @@ -426,6 +431,7 @@ void PackageRenderer::do_video() BRender::RENDERED); video_write_position = 0; } +//printf("PackageRenderer::do_video 11\n"); } @@ -461,15 +467,20 @@ void PackageRenderer::stop_output() if(asset->video_data) { +//printf("PackageRenderer::stop_output 1\n"); delete compressed_output; +//printf("PackageRenderer::stop_output 2\n"); if(video_write_position) file->write_video_buffer(video_write_position); +//printf("PackageRenderer::stop_output 3\n"); if(package->use_brender) for(int i = 0; i < video_write_position; i++) set_video_map(video_position - video_write_position + i, BRender::RENDERED); +//printf("PackageRenderer::stop_output 4\n"); video_write_position = 0; file->stop_video_thread(); +//printf("PackageRenderer::stop_output 5\n"); if(mwindow) { video_device->stop_playback(); @@ -600,19 +611,25 @@ int PackageRenderer::render_package(RenderPackage *package) result = get_result(); } +//printf("PackageRenderer::render_package 10\n"); stop_engine(); +//printf("PackageRenderer::render_package 11\n"); stop_output(); +//printf("PackageRenderer::render_package 12\n"); } +//printf("PackageRenderer::render_package 13\n"); close_output(); +//printf("PackageRenderer::render_package 14\n"); set_result(result); +//printf("PackageRenderer::render_package 15\n"); @@ -674,7 +691,6 @@ int PackageRenderer::direct_frame_copy(EDL *edl, else if(!error) { -//printf("Render::direct_frame_copy 3\n"); // Don't background render this one if(package->use_brender) set_video_map(video_position, BRender::SCANNED); diff --git a/hvirtual/cinelerra/patchbay.C b/hvirtual/cinelerra/patchbay.C index f1933885..f777bf58 100644 --- a/hvirtual/cinelerra/patchbay.C +++ b/hvirtual/cinelerra/patchbay.C @@ -8,6 +8,7 @@ #include "filexml.h" #include "intauto.h" #include "intautos.h" +#include "language.h" #include "localsession.h" #include "mainundo.h" #include "mwindow.h" @@ -21,11 +22,6 @@ #include "tracks.h" #include "vpatchgui.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -302,7 +298,7 @@ int PatchBay::cursor_motion_event() return 0; } -void PatchBay::change_meter_format(int mode, float min) +void PatchBay::change_meter_format(int mode, int min, int max) { for(int i = 0; i < patches.total; i++) { @@ -312,7 +308,7 @@ void PatchBay::change_meter_format(int mode, float min) APatchGUI *apatchgui = (APatchGUI*)patchgui; if(apatchgui->meter) { - apatchgui->meter->change_format(mode, min); + apatchgui->meter->change_format(mode, min, max); } } } diff --git a/hvirtual/cinelerra/patchbay.h b/hvirtual/cinelerra/patchbay.h index bf5eb287..9ae5f6ef 100644 --- a/hvirtual/cinelerra/patchbay.h +++ b/hvirtual/cinelerra/patchbay.h @@ -33,7 +33,7 @@ public: void update_meters(ArrayList *module_levels); void stop_meters(); void synchronize_faders(float value, int data_type, Track *skip); - void change_meter_format(int mode, float min); + void change_meter_format(int mode, int min, int max); void reset_meters(); ArrayList patches; diff --git a/hvirtual/cinelerra/playbackconfig.C b/hvirtual/cinelerra/playbackconfig.C index 65ca5143..3389a792 100644 --- a/hvirtual/cinelerra/playbackconfig.C +++ b/hvirtual/cinelerra/playbackconfig.C @@ -3,13 +3,9 @@ #include "videodevice.inc" #include -AudioOutConfig::AudioOutConfig(int playback_strategy, - int engine_number, - int duplex) +AudioOutConfig::AudioOutConfig(int duplex) { this->duplex = duplex; - this->playback_strategy = playback_strategy; - this->engine_number = engine_number; fragment_size = 16384; driver = AUDIO_OSS; @@ -86,41 +82,42 @@ int AudioOutConfig::operator==(AudioOutConfig &that) AudioOutConfig& AudioOutConfig::operator=(AudioOutConfig &that) { - fragment_size = that.fragment_size; - driver = that.driver; - strcpy(esound_out_server, that.esound_out_server); - esound_out_port = that.esound_out_port; + copy_from(&that); + return *this; +} + +void AudioOutConfig::copy_from(AudioOutConfig *src) +{ + fragment_size = src->fragment_size; + driver = src->driver; + strcpy(esound_out_server, src->esound_out_server); + esound_out_port = src->esound_out_port; for(int i = 0; i < MAXDEVICES; i++) { - oss_enable[i] = that.oss_enable[i]; - strcpy(oss_out_device[i], that.oss_out_device[i]); - oss_out_channels[i] = that.oss_out_channels[i]; + oss_enable[i] = src->oss_enable[i]; + strcpy(oss_out_device[i], src->oss_out_device[i]); + oss_out_channels[i] = src->oss_out_channels[i]; } - oss_out_bits = that.oss_out_bits; + oss_out_bits = src->oss_out_bits; - strcpy(alsa_out_device, that.alsa_out_device); - alsa_out_channels = that.alsa_out_channels; - alsa_out_bits = that.alsa_out_bits; + strcpy(alsa_out_device, src->alsa_out_device); + alsa_out_channels = src->alsa_out_channels; + alsa_out_bits = src->alsa_out_bits; - firewire_channels = that.firewire_channels; - firewire_channel = that.firewire_channel; - firewire_port = that.firewire_port; - firewire_syt = that.firewire_syt; - strcpy(firewire_path, that.firewire_path); + firewire_channels = src->firewire_channels; + firewire_channel = src->firewire_channel; + firewire_port = src->firewire_port; + firewire_syt = src->firewire_syt; + strcpy(firewire_path, src->firewire_path); - dv1394_channels = that.dv1394_channels; - dv1394_channel = that.dv1394_channel; - dv1394_port = that.dv1394_port; - dv1394_syt = that.dv1394_syt; - strcpy(dv1394_path, that.dv1394_path); + dv1394_channels = src->dv1394_channels; + dv1394_channel = src->dv1394_channel; + dv1394_port = src->dv1394_port; + dv1394_syt = src->dv1394_syt; + strcpy(dv1394_path, src->dv1394_path); for(int i = 0; i < MAXCHANNELS; i++) - do_channel[i] = that.do_channel[i]; -// printf("AudioOutConfig::operator= "); -// for(int i = 0; i < MAXCHANNELS; i++) -// printf("%d", do_channel[i]); -// printf("\n"); - return *this; + do_channel[i] = src->do_channel[i]; } int AudioOutConfig::load_defaults(Defaults *defaults) @@ -128,14 +125,8 @@ int AudioOutConfig::load_defaults(Defaults *defaults) char string[BCTEXTLEN]; fragment_size = defaults->get("FRAGMENT_SIZE", fragment_size); - sprintf(string, "AUDIO_OUT_DRIVER_%d_%d_%d", playback_strategy, engine_number, duplex); + sprintf(string, "AUDIO_OUT_DRIVER_%d", duplex); driver = defaults->get(string, driver); -// sprintf(string, "OSS_OUT_DEVICE_%d_%d_%d", playback_strategy, engine_number, duplex); -// defaults->get(string, oss_out_device); -// sprintf(string, "OSS_OUT_CHANNELS_%d_%d_%d", playback_strategy, engine_number, duplex); -// oss_out_channels = defaults->get(string, oss_out_channels); -// sprintf(string, "OSS_OUT_BITS_%d_%d_%d", playback_strategy, engine_number, duplex); -// oss_out_bits = defaults->get(string, oss_out_bits); for(int i = 0; i < MAXDEVICES; i++) { @@ -153,31 +144,31 @@ int AudioOutConfig::load_defaults(Defaults *defaults) alsa_out_channels = defaults->get("ALSA_OUT_CHANNELS", alsa_out_channels); alsa_out_bits = defaults->get("ALSA_OUT_BITS", alsa_out_bits); - sprintf(string, "ESOUND_OUT_SERVER_%d_%d_%d", playback_strategy, engine_number, duplex); + sprintf(string, "ESOUND_OUT_SERVER_%d", duplex); defaults->get(string, esound_out_server); - sprintf(string, "ESOUND_OUT_PORT_%d_%d_%d", playback_strategy, engine_number, duplex); + sprintf(string, "ESOUND_OUT_PORT_%d", duplex); esound_out_port = defaults->get(string, esound_out_port); - sprintf(string, "AFIREWIRE_OUT_CHANNELS_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_CHANNELS"); firewire_channels = defaults->get(string, firewire_channels); - sprintf(string, "AFIREWIRE_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_CHANNEL"); firewire_channel = defaults->get(string, firewire_channel); - sprintf(string, "AFIREWIRE_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_PORT"); firewire_port = defaults->get(string, firewire_port); - sprintf(string, "AFIREWIRE_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_PATH"); defaults->get(string, firewire_path); - sprintf(string, "AFIREWIRE_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_SYT"); firewire_syt = defaults->get(string, firewire_syt); - sprintf(string, "ADV1394_OUT_CHANNELS_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_CHANNELS"); dv1394_channels = defaults->get(string, dv1394_channels); - sprintf(string, "ADV1394_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_CHANNEL"); dv1394_channel = defaults->get(string, dv1394_channel); - sprintf(string, "ADV1394_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_PORT"); dv1394_port = defaults->get(string, dv1394_port); - sprintf(string, "ADV1394_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_PATH"); defaults->get(string, dv1394_path); - sprintf(string, "ADV1394_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_SYT"); dv1394_syt = defaults->get(string, dv1394_syt); return 0; @@ -188,14 +179,8 @@ int AudioOutConfig::save_defaults(Defaults *defaults) char string[BCTEXTLEN]; defaults->update("FRAGMENT_SIZE", fragment_size); - sprintf(string, "AUDIO_OUT_DRIVER_%d_%d_%d", playback_strategy, engine_number, duplex); + sprintf(string, "AUDIO_OUT_DRIVER_%d", duplex); defaults->update(string, driver); -// sprintf(string, "OSS_OUT_DEVICE_%d_%d_%d", playback_strategy, engine_number, duplex); -// defaults->update(string, oss_out_device); -// sprintf(string, "OSS_OUT_CHANNELS_%d_%d_%d", playback_strategy, engine_number, duplex); -// defaults->update(string, oss_out_channels); -// sprintf(string, "OSS_OUT_BITS_%d_%d_%d", playback_strategy, engine_number, duplex); -// defaults->update(string, oss_out_bits); for(int i = 0; i < MAXDEVICES; i++) { @@ -214,32 +199,32 @@ int AudioOutConfig::save_defaults(Defaults *defaults) defaults->update("ALSA_OUT_CHANNELS", alsa_out_channels); defaults->update("ALSA_OUT_BITS", alsa_out_bits); - sprintf(string, "ESOUND_OUT_SERVER_%d_%d_%d", playback_strategy, engine_number, duplex); + sprintf(string, "ESOUND_OUT_SERVER_%d", duplex); defaults->update(string, esound_out_server); - sprintf(string, "ESOUND_OUT_PORT_%d_%d_%d", playback_strategy, engine_number, duplex); + sprintf(string, "ESOUND_OUT_PORT_%d", duplex); defaults->update(string, esound_out_port); - sprintf(string, "AFIREWIRE_OUT_CHANNELS_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_CHANNELS"); defaults->update(string, firewire_channels); - sprintf(string, "AFIREWIRE_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_CHANNEL"); defaults->update(string, firewire_channel); - sprintf(string, "AFIREWIRE_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_PORT"); defaults->update(string, firewire_port); - sprintf(string, "AFIREWIRE_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_PATH"); defaults->update(string, firewire_path); - sprintf(string, "AFIREWIRE_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "AFIREWIRE_OUT_SYT"); defaults->update(string, firewire_syt); - sprintf(string, "ADV1394_OUT_CHANNELS_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_CHANNELS"); defaults->update(string, dv1394_channels); - sprintf(string, "ADV1394_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_CHANNEL"); defaults->update(string, dv1394_channel); - sprintf(string, "ADV1394_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_PORT"); defaults->update(string, dv1394_port); - sprintf(string, "ADV1394_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_PATH"); defaults->update(string, dv1394_path); - sprintf(string, "ADV1394_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "ADV1394_OUT_SYT"); defaults->update(string, dv1394_syt); return 0; @@ -314,12 +299,10 @@ int AudioOutConfig::playable_channel_number(int number) -VideoOutConfig::VideoOutConfig(int playback_strategy, int engine_number) +VideoOutConfig::VideoOutConfig() { sprintf(lml_out_device, "/dev/mvideo/stream"); sprintf(buz_out_device, "/dev/video0"); - this->playback_strategy = playback_strategy; - this->engine_number = engine_number; driver = PLAYBACK_X11_XV; for(int i = 0; i < MAX_CHANNELS; i++) do_channel[i] = 0; buz_out_channel = 0; @@ -381,27 +364,31 @@ int VideoOutConfig::operator==(VideoOutConfig &that) VideoOutConfig& VideoOutConfig::operator=(VideoOutConfig &that) { - this->driver = that.driver; - strcpy(this->lml_out_device, that.lml_out_device); - strcpy(this->buz_out_device, that.buz_out_device); - this->buz_out_channel = that.buz_out_channel; - this->buz_swap_fields = that.buz_swap_fields; - strcpy(this->x11_host, that.x11_host); - this->x11_use_fields = that.x11_use_fields; - for(int i = 0; i < MAX_CHANNELS; i++) - this->do_channel[i] = that.do_channel[i]; + copy_from(&that); + return *this; +} - firewire_channel = that.firewire_channel; - firewire_port = that.firewire_port; - strcpy(firewire_path, that.firewire_path); - firewire_syt = that.firewire_syt; +void VideoOutConfig::copy_from(VideoOutConfig *src) +{ + this->driver = src->driver; + strcpy(this->lml_out_device, src->lml_out_device); + strcpy(this->buz_out_device, src->buz_out_device); + this->buz_out_channel = src->buz_out_channel; + this->buz_swap_fields = src->buz_swap_fields; + strcpy(this->x11_host, src->x11_host); + this->x11_use_fields = src->x11_use_fields; + for(int i = 0; i < MAX_CHANNELS; i++) + this->do_channel[i] = src->do_channel[i]; - dv1394_channel = that.dv1394_channel; - dv1394_port = that.dv1394_port; - strcpy(dv1394_path, that.dv1394_path); - dv1394_syt = that.dv1394_syt; + firewire_channel = src->firewire_channel; + firewire_port = src->firewire_port; + strcpy(firewire_path, src->firewire_path); + firewire_syt = src->firewire_syt; - return *this; + dv1394_channel = src->dv1394_channel; + dv1394_port = src->dv1394_port; + strcpy(dv1394_path, src->dv1394_path); + dv1394_syt = src->dv1394_syt; } char* VideoOutConfig::get_path() @@ -428,38 +415,38 @@ char* VideoOutConfig::get_path() int VideoOutConfig::load_defaults(Defaults *defaults) { char string[BCTEXTLEN]; - sprintf(string, "VIDEO_OUT_DRIVER_%d_%d", playback_strategy, engine_number); + sprintf(string, "VIDEO_OUT_DRIVER"); driver = defaults->get(string, driver); - sprintf(string, "LML_OUT_DEVICE_%d_%d", playback_strategy, engine_number); + sprintf(string, "LML_OUT_DEVICE"); defaults->get(string, lml_out_device); - sprintf(string, "BUZ_OUT_DEVICE_%d_%d", playback_strategy, engine_number); + sprintf(string, "BUZ_OUT_DEVICE"); defaults->get(string, buz_out_device); - sprintf(string, "BUZ_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "BUZ_OUT_CHANNEL"); buz_out_channel = defaults->get(string, buz_out_channel); - sprintf(string, "BUZ_SWAP_FIELDS_%d_%d", playback_strategy, engine_number); + sprintf(string, "BUZ_SWAP_FIELDS"); buz_swap_fields = defaults->get(string, buz_swap_fields); - sprintf(string, "X11_OUT_DEVICE_%d_%d", playback_strategy, engine_number); + sprintf(string, "X11_OUT_DEVICE"); defaults->get(string, x11_host); x11_use_fields = defaults->get("X11_USE_FIELDS", x11_use_fields); - sprintf(string, "VFIREWIRE_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_CHANNEL"); firewire_channel = defaults->get(string, firewire_channel); - sprintf(string, "VFIREWIRE_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_PORT"); firewire_port = defaults->get(string, firewire_port); - sprintf(string, "VFIREWIRE_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_PATH"); defaults->get(string, firewire_path); - sprintf(string, "VFIREWIRE_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_SYT"); firewire_syt = defaults->get(string, firewire_syt); - sprintf(string, "VDV1394_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_CHANNEL"); dv1394_channel = defaults->get(string, dv1394_channel); - sprintf(string, "VDV1394_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_PORT"); dv1394_port = defaults->get(string, dv1394_port); - sprintf(string, "VDV1394_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_PATH"); defaults->get(string, dv1394_path); - sprintf(string, "VDV1394_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_SYT"); dv1394_syt = defaults->get(string, dv1394_syt); return 0; } @@ -467,36 +454,36 @@ int VideoOutConfig::load_defaults(Defaults *defaults) int VideoOutConfig::save_defaults(Defaults *defaults) { char string[BCTEXTLEN]; - sprintf(string, "VIDEO_OUT_DRIVER_%d_%d", playback_strategy, engine_number); + sprintf(string, "VIDEO_OUT_DRIVER"); defaults->update(string, driver); - sprintf(string, "LML_OUT_DEVICE_%d_%d", playback_strategy, engine_number); + sprintf(string, "LML_OUT_DEVICE"); defaults->update(string, lml_out_device); - sprintf(string, "BUZ_OUT_DEVICE_%d_%d", playback_strategy, engine_number); + sprintf(string, "BUZ_OUT_DEVICE"); defaults->update(string, buz_out_device); - sprintf(string, "BUZ_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "BUZ_OUT_CHANNEL"); defaults->update(string, buz_out_channel); - sprintf(string, "BUZ_SWAP_FIELDS_%d_%d", playback_strategy, engine_number); + sprintf(string, "BUZ_SWAP_FIELDS"); defaults->update(string, buz_swap_fields); - sprintf(string, "X11_OUT_DEVICE_%d_%d", playback_strategy, engine_number); + sprintf(string, "X11_OUT_DEVICE"); defaults->update(string, x11_host); defaults->update("X11_USE_FIELDS", x11_use_fields); - sprintf(string, "VFIREWIRE_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_CHANNEL"); defaults->update(string, firewire_channel); - sprintf(string, "VFIREWIRE_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_PORT"); defaults->update(string, firewire_port); - sprintf(string, "VFIREWIRE_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_PATH"); defaults->update(string, firewire_path); - sprintf(string, "VFIREWIRE_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VFIREWIRE_OUT_SYT"); defaults->update(string, firewire_syt); - sprintf(string, "VDV1394_OUT_CHANNEL_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_CHANNEL"); defaults->update(string, dv1394_channel); - sprintf(string, "VDV1394_OUT_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_PORT"); defaults->update(string, dv1394_port); - sprintf(string, "VDV1394_OUT_PATH_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_PATH"); defaults->update(string, dv1394_path); - sprintf(string, "VDV1394_OUT_SYT_%d_%d", playback_strategy, engine_number); + sprintf(string, "VDV1394_OUT_SYT"); defaults->update(string, dv1394_syt); return 0; } @@ -517,12 +504,10 @@ int VideoOutConfig::total_playable_channels() -PlaybackConfig::PlaybackConfig(int playback_strategy, int engine_number) +PlaybackConfig::PlaybackConfig() { - aconfig = new AudioOutConfig(playback_strategy, engine_number, 0); - vconfig = new VideoOutConfig(playback_strategy, engine_number); - this->playback_strategy = playback_strategy; - this->engine_number = engine_number; + aconfig = new AudioOutConfig(0); + vconfig = new VideoOutConfig; sprintf(hostname, "localhost"); port = 23456; } @@ -535,19 +520,24 @@ PlaybackConfig::~PlaybackConfig() PlaybackConfig& PlaybackConfig::operator=(PlaybackConfig &that) { - *aconfig = *that.aconfig; - *vconfig = *that.vconfig; - strcpy(hostname, that.hostname); - port = that.port; + copy_from(&that); return *this; } +void PlaybackConfig::copy_from(PlaybackConfig *src) +{ + aconfig->copy_from(src->aconfig); + vconfig->copy_from(src->vconfig); + strcpy(hostname, src->hostname); + port = src->port; +} + int PlaybackConfig::load_defaults(Defaults *defaults) { char string[1024]; - sprintf(string, "PLAYBACK_HOSTNAME_%d_%d", playback_strategy, engine_number); + sprintf(string, "PLAYBACK_HOSTNAME"); defaults->get(string, hostname); - sprintf(string, "PLAYBACK_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "PLAYBACK_PORT"); port = defaults->get(string, port); aconfig->load_defaults(defaults); vconfig->load_defaults(defaults); @@ -557,9 +547,9 @@ int PlaybackConfig::load_defaults(Defaults *defaults) int PlaybackConfig::save_defaults(Defaults *defaults) { char string[1024]; - sprintf(string, "PLAYBACK_HOSTNAME_%d_%d", playback_strategy, engine_number); + sprintf(string, "PLAYBACK_HOSTNAME"); defaults->update(string, hostname); - sprintf(string, "PLAYBACK_PORT_%d_%d", playback_strategy, engine_number); + sprintf(string, "PLAYBACK_PORT"); defaults->update(string, port); aconfig->save_defaults(defaults); vconfig->save_defaults(defaults); diff --git a/hvirtual/cinelerra/playbackconfig.h b/hvirtual/cinelerra/playbackconfig.h index 284dfb36..bdf0c815 100644 --- a/hvirtual/cinelerra/playbackconfig.h +++ b/hvirtual/cinelerra/playbackconfig.h @@ -11,12 +11,13 @@ class AudioOutConfig { public: - AudioOutConfig(int playback_strategy, int engine_number, int duplex); + AudioOutConfig(int duplex); ~AudioOutConfig(); int operator!=(AudioOutConfig &that); int operator==(AudioOutConfig &that); AudioOutConfig& operator=(AudioOutConfig &that); + void copy_from(AudioOutConfig *src); int load_defaults(Defaults *defaults); int save_defaults(Defaults *defaults); // Total channels in do_channels @@ -29,8 +30,6 @@ public: // Change default titles for duplex int duplex; - int playback_strategy; - int engine_number; int driver; int oss_enable[MAXDEVICES]; char oss_out_device[MAXDEVICES][BCTEXTLEN]; @@ -66,19 +65,18 @@ public: class VideoOutConfig { public: - VideoOutConfig(int playback_strategy, int engine_number); + VideoOutConfig(); ~VideoOutConfig(); int operator!=(VideoOutConfig &that); int operator==(VideoOutConfig &that); VideoOutConfig& operator=(VideoOutConfig &that); + void copy_from(VideoOutConfig *src); int load_defaults(Defaults *defaults); int save_defaults(Defaults *defaults); int total_playable_channels(); char* get_path(); - int playback_strategy; - int engine_number; int driver; char lml_out_device[BCTEXTLEN]; char buz_out_device[BCTEXTLEN]; @@ -124,18 +122,17 @@ public: class PlaybackConfig { public: - PlaybackConfig(int playback_strategy, int engine_number); + PlaybackConfig(); ~PlaybackConfig(); PlaybackConfig& operator=(PlaybackConfig &that); + void copy_from(PlaybackConfig *src); int load_defaults(Defaults *defaults); int save_defaults(Defaults *defaults); char hostname[BCTEXTLEN]; int port; - int playback_strategy; - int engine_number; AudioOutConfig *aconfig; VideoOutConfig *vconfig; }; diff --git a/hvirtual/cinelerra/playbackengine.C b/hvirtual/cinelerra/playbackengine.C index 2cc13dea..91749e64 100644 --- a/hvirtual/cinelerra/playbackengine.C +++ b/hvirtual/cinelerra/playbackengine.C @@ -22,7 +22,7 @@ PlaybackEngine::PlaybackEngine(MWindow *mwindow, Canvas *output) - : Thread() + : Thread(1, 0, 0) { this->mwindow = mwindow; this->output = output; @@ -32,11 +32,12 @@ PlaybackEngine::PlaybackEngine(MWindow *mwindow, Canvas *output) audio_cache = 0; video_cache = 0; last_command = STOP; - Thread::set_synchronous(1); tracking_lock = new Mutex("PlaybackEngine::tracking_lock"); tracking_done = new Condition(1, "PlaybackEngine::tracking_done"); pause_lock = new Condition(0, "PlaybackEngine::pause_lock"); start_lock = new Condition(0, "PlaybackEngine::start_lock"); + render_engine = 0; + debug = 0; } PlaybackEngine::~PlaybackEngine() @@ -52,9 +53,9 @@ PlaybackEngine::~PlaybackEngine() delete preferences; delete command; delete que; - delete_render_engines(); - if(audio_cache) delete audio_cache; - if(video_cache) delete video_cache; + delete_render_engine(); + delete audio_cache; + delete video_cache; delete tracking_lock; delete tracking_done; delete pause_lock; @@ -80,8 +81,7 @@ int PlaybackEngine::create_objects() ChannelDB* PlaybackEngine::get_channeldb() { - int playback_strategy = command->get_edl()->session->playback_strategy; - PlaybackConfig *config = command->get_edl()->session->get_playback_config(playback_strategy, 0); + PlaybackConfig *config = command->get_edl()->session->playback_config; switch(config->vconfig->driver) { case VIDEO4LINUX2JPEG: @@ -94,68 +94,49 @@ ChannelDB* PlaybackEngine::get_channeldb() return 0; } -int PlaybackEngine::create_render_engines() +int PlaybackEngine::create_render_engine() { -//printf("PlaybackEngine::create_render_engines 1 %d\n", command->edl->session->playback_strategy); // Fix playback configurations - int playback_strategy = command->get_edl()->session->playback_strategy; int current_vchannel = 0; int current_achannel = 0; - delete_render_engines(); + delete_render_engine(); -//printf("PlaybackEngine::create_render_engines %d\n", command->get_edl()->session->playback_config[playback_strategy].total); - for(int i = 0; - i < command->get_edl()->session->get_playback_heads(playback_strategy); - i++) - { - RenderEngine *engine = new RenderEngine(this, - preferences, - command, - output, - mwindow->plugindb, - get_channeldb(), - i); - render_engines.append(engine); - } + render_engine = new RenderEngine(this, + preferences, + command, + output, + mwindow->plugindb, + get_channeldb()); return 0; } -void PlaybackEngine::delete_render_engines() +void PlaybackEngine::delete_render_engine() { - render_engines.remove_all_objects(); + delete render_engine; + render_engine = 0; } -void PlaybackEngine::arm_render_engines() +void PlaybackEngine::arm_render_engine() { int current_achannel = 0, current_vchannel = 0; - for(int i = 0; i < render_engines.total; i++) - { -//printf("PlaybackEngine::arm_render_engines %ld\n", command->playbackstart); - render_engines.values[i]->arm_command(command, + if(render_engine) + render_engine->arm_command(command, current_achannel, current_vchannel); - } } -void PlaybackEngine::start_render_engines() +void PlaybackEngine::start_render_engine() { -//printf("PlaybackEngine::start_render_engines 1 %d\n", render_engines.total); - for(int i = 0; i < render_engines.total; i++) - { - render_engines.values[i]->start_command(); - } + if(render_engine) render_engine->start_command(); } -void PlaybackEngine::wait_render_engines() +void PlaybackEngine::wait_render_engine() { - if(command->realtime) + if(command->realtime && render_engine) { - for(int i = 0; i < render_engines.total; i++) - { - render_engines.values[i]->join(); - } + render_engine->join(); } } @@ -186,12 +167,11 @@ void PlaybackEngine::perform_change() case CHANGE_EDL: audio_cache->set_edl(command->get_edl()); video_cache->set_edl(command->get_edl()); - create_render_engines(); + create_render_engine(); case CHANGE_PARAMS: if(command->change_type != CHANGE_EDL && command->change_type != CHANGE_ALL) - for(int i = 0; i < render_engines.total; i++) - render_engines.values[i]->edl->synchronize_params(command->get_edl()); + render_engine->edl->synchronize_params(command->get_edl()); case CHANGE_NONE: break; } @@ -201,15 +181,14 @@ void PlaybackEngine::sync_parameters(EDL *edl) { // TODO: lock out render engine from keyframe deletions command->get_edl()->synchronize_params(edl); - for(int i = 0; i < render_engines.total; i++) - render_engines.values[i]->edl->synchronize_params(edl); + if(render_engine) render_engine->edl->synchronize_params(edl); } void PlaybackEngine::interrupt_playback(int wait_tracking) { - for(int i = 0; i < render_engines.total; i++) - render_engines.values[i]->interrupt_playback(); + if(render_engine) + render_engine->interrupt_playback(); // Stop pausing pause_lock->unlock(); @@ -227,13 +206,10 @@ void PlaybackEngine::interrupt_playback(int wait_tracking) int PlaybackEngine::get_output_levels(double *levels, long position) { int result = 0; - for(int j = 0; j < render_engines.total; j++) + if(render_engine && render_engine->do_audio) { - if(render_engines.values[j]->do_audio) - { - result = 1; - render_engines.values[j]->get_output_levels(levels, position); - } + result = 1; + render_engine->get_output_levels(levels, position); } return result; } @@ -242,14 +218,10 @@ int PlaybackEngine::get_output_levels(double *levels, long position) int PlaybackEngine::get_module_levels(ArrayList *module_levels, long position) { int result = 0; - for(int j = 0; j < render_engines.total; j++) + if(render_engine && render_engine->do_audio) { - if(render_engines.values[j]->do_audio) - { - result = 1; - render_engines.values[j]->get_module_levels(module_levels, position); - break; - } + result = 1; + render_engine->get_module_levels(module_levels, position); } return result; } @@ -316,8 +288,8 @@ double PlaybackEngine::get_tracking_position() // Don't interpolate when every frame is played. if(command->get_edl()->session->video_every_frame && - render_engines.total && - render_engines.values[0]->do_video) + render_engine && + render_engine->do_video) { result = tracking_position; } @@ -387,14 +359,16 @@ void PlaybackEngine::run() // Wait for current command to finish que->output_lock->lock("PlaybackEngine::run"); - wait_render_engines(); +//printf("PlaybackEngine::run 1\n"); + wait_render_engine(); +//printf("PlaybackEngine::run 2\n"); // Read the new command que->input_lock->lock("PlaybackEngine::run"); if(done) return; - *command = que->command; + command->copy_from(&que->command); que->command.reset(); que->input_lock->unlock(); @@ -421,9 +395,9 @@ void PlaybackEngine::run() case CURRENT_FRAME: last_command = command->command; perform_change(); - arm_render_engines(); + arm_render_engine(); // Dispatch the command - start_render_engines(); + start_render_engine(); break; default: @@ -436,14 +410,14 @@ void PlaybackEngine::run() } perform_change(); - arm_render_engines(); + arm_render_engine(); // Start tracking after arming so the tracking position doesn't change. // The tracking for a single frame command occurs during PAUSE init_tracking(); // Dispatch the command - start_render_engines(); + start_render_engine(); break; } @@ -454,159 +428,3 @@ void PlaybackEngine::run() - - - - - - - - - - - - - - - - - - - -int PlaybackEngine::reset_parameters() -{ -// called before every playback - is_playing_back = 0; - follow_loop = 0; - speed = 1; - reverse = 0; - cursor = 0; - last_position = 0; - playback_start = playback_end = 0; - infinite = 0; - use_buttons = 0; - audio = 0; - video = 0; - shared_audio = 0; - return 0; -} - -// int PlaybackEngine::init_parameters() -// { -// // is_playing_back = 1; -// update_button = 1; -// correction_factor = 0; -// -// // correct playback buffer sizes -// input_length = -// playback_buffer = -// output_length = -// audio_module_fragment = -// command->get_edl()->session->audio_module_fragment; -// -// // get maximum actual buffer size written to device plus padding -// if(speed != 1) output_length = (long)(output_length / speed) + 16; -// if(output_length < playback_buffer) output_length = playback_buffer; -// -// // samples to read at a time is a multiple of the playback buffer greater than read_length -// while(input_length < command->get_edl()->session->audio_module_fragment) -// input_length += playback_buffer; -// return 0; -// } - -int PlaybackEngine::init_audio_device() -{ - return 0; -} - -int PlaybackEngine::init_video_device() -{ - return 0; -} - - - -int PlaybackEngine::start_reconfigure() -{ - reconfigure_status = is_playing_back; -// if(is_playing_back) stop_playback(0); - return 0; -} - -int PlaybackEngine::stop_reconfigure() -{ - return 0; -} - -int PlaybackEngine::reset_buttons() -{ - return 0; -} - - -long PlaybackEngine::absolute_position(int sync_time) -{ - return 0; -} - -long PlaybackEngine::get_position(int sync_time) -{ - long result; - - switch(is_playing_back) - { - case 2: -// playing back - result = absolute_position(sync_time); -// adjust for speed - result = (long)(result * speed); - -// adjust direction and initial position - if(reverse) - { - result = playback_end - result; - result += loop_adjustment; - -// adjust for looping -// while(mwindow->session->loop_playback && follow_loop && -// result < mwindow->session->loop_start) -// { -// result += mwindow->session->loop_end - mwindow->session->loop_start; -// loop_adjustment += mwindow->session->loop_end - mwindow->session->loop_start; -// } - } - else - { - result += playback_start; - result -= loop_adjustment; - -// while(mwindow->session->loop_playback && follow_loop && -// result > mwindow->session->loop_end) -// { -// result -= mwindow->session->loop_end - mwindow->session->loop_start; -// loop_adjustment += mwindow->session->loop_end - mwindow->session->loop_start; -// } - } - break; - - case 1: -// paused - result = last_position; - break; - - default: -// no value - result = -1; - break; - } - - return result; -} - - -int PlaybackEngine::move_right(long distance) -{ - mwindow->move_right(distance); - return 0; -} - diff --git a/hvirtual/cinelerra/playbackengine.h b/hvirtual/cinelerra/playbackengine.h index 81ef0658..85212f2c 100644 --- a/hvirtual/cinelerra/playbackengine.h +++ b/hvirtual/cinelerra/playbackengine.h @@ -27,11 +27,11 @@ public: virtual ~PlaybackEngine(); int create_objects(); - virtual int create_render_engines(); - void delete_render_engines(); - void arm_render_engines(); - void start_render_engines(); - void wait_render_engines(); + virtual int create_render_engine(); + void delete_render_engine(); + void arm_render_engine(); + void start_render_engine(); + void wait_render_engine(); void create_cache(); void perform_change(); void sync_parameters(EDL *edl); @@ -91,84 +91,14 @@ public: int last_command; int done; int do_cwindow; -// Render engine set - ArrayList render_engines; - - - - - - - - - - - - - - int reset_parameters(); - -// ================= position information ====================== -// get exact position in samples corrected for speed and direction - long get_position(int sync_time = 1); -// get total samples rendered since last start with no speed correction -// Sync_time uses the video thread to get the current position. -// Otherwise a timer or audio device is used. - long absolute_position(int sync_time = 1); - -// stop and start for user changes - int start_reconfigure(); - int stop_reconfigure(); - -// generic render routine - int render_audio(); - int reset_buttons(); - -// ============================ cursor - int lock_playback_cursor(); - int unlock_playback_cursor(); - int lock_playback_movement(); - int unlock_playback_movement(); - int move_right(long distance); - - Tracking *cursor; - - -// ============================== playback config - int infinite; // for infinite playback - int follow_loop; // 1 if mwindow's looping setting is followed - int is_playing_back; // 0 - no playback 1 - armed but stopped 2 - playing back - int reconfigure_status; // 0 - no playback 1 - armed but stopped 2 - playing back - // otherwise use DSP chip if audio tracks are being played - int update_button; // flag for thread on exit - int use_buttons; // flag to update buttons when done or not - long last_position; // starting position for restarting playback - long playback_start, playback_end; // range for current playback - int reverse; // direction of current playback - float speed; // speed of current playback. A speed of FRAME_SPEED causes frame advance - long playback_buffer; - long audio_module_fragment; - -// ================================== audio config -// long input_length; // number of samples to read from disk at a time -// // multiple of playback_buffer greater than read_buffer -// long output_length; // # of samples to write to device adjusted for speed - int shared_audio; // for duplex audio recording - -// ================================== video config - - long correction_factor; // number of frames to skip to get synchronized - +// Render engine RenderEngine *render_engine; - AudioDevice *audio; - VideoDevice *video; -private: - int init_parameters(); - int init_audio_device(); - int init_video_device(); - Timer timer; // timer for position information - long loop_adjustment; // for factoring loops into current position +// Used by label commands to get current position + int is_playing_back; + +// General purpose debugging register + int debug; }; diff --git a/hvirtual/cinelerra/playbackprefs.C b/hvirtual/cinelerra/playbackprefs.C index 16836157..4941309a 100644 --- a/hvirtual/cinelerra/playbackprefs.C +++ b/hvirtual/cinelerra/playbackprefs.C @@ -18,16 +18,16 @@ PlaybackPrefs::PlaybackPrefs(MWindow *mwindow, PreferencesWindow *pwindow) : PreferencesDialog(mwindow, pwindow) { - head_text = 0; - head_count_text = 0; - host_text = 0; +// head_text = 0; +// head_count_text = 0; +// host_text = 0; video_device = 0; } PlaybackPrefs::~PlaybackPrefs() { - delete_strategy(); - mwindow->defaults->update("PLAYBACK_HEAD", current_head); +// delete_strategy(); +// mwindow->defaults->update("PLAYBACK_HEAD", current_head); delete audio_device; delete video_device; } @@ -38,10 +38,11 @@ int PlaybackPrefs::create_objects() char string[BCTEXTLEN]; BC_PopupTextBox *popup; - current_head = mwindow->defaults->get("PLAYBACK_HEAD", 0); - strategies.append(new BC_ListBoxItem(_("Local Host"))); - strategies.append(new BC_ListBoxItem(_("Multihead"))); - strategies.append(new BC_ListBoxItem(_("Blond Symphony"))); + playback_config = pwindow->thread->edl->session->playback_config; +// current_head = mwindow->defaults->get("PLAYBACK_HEAD", 0); +// strategies.append(new BC_ListBoxItem(_("Local Host"))); +// strategies.append(new BC_ListBoxItem(_("Multihead"))); +// strategies.append(new BC_ListBoxItem(_("Blond Symphony"))); // Global playback options @@ -58,7 +59,7 @@ int PlaybackPrefs::create_objects() // sprintf(string, "%d", pwindow->thread->edl->session->audio_read_length); // add_subwindow(new PlaybackReadLength(x2, y, pwindow, this, string)); - sprintf(string, "%d", current_config()->aconfig->fragment_size); + sprintf(string, "%d", playback_config->aconfig->fragment_size); PlaybackModuleFragment *menu; add_subwindow(menu = new PlaybackModuleFragment(x2, y, @@ -86,13 +87,13 @@ int PlaybackPrefs::create_objects() y, pwindow, this, - current_config()->aconfig, + playback_config->aconfig, 0, MODEPLAY); audio_device->initialize(); // Strategic playback options created here - set_strategy(pwindow->thread->edl->session->playback_strategy); +// set_strategy(pwindow->thread->edl->session->playback_strategy); // // add_subwindow(new BC_Title(x, y, _("Playback driver:"), MEDIUMFONT, BLACK)); // add_subwindow(new AudioDriverMenu(x, y + 20, out_device, &(pwindow->thread->preferences->aconfig->audio_out_driver), 0, 1)); @@ -142,7 +143,7 @@ int PlaybackPrefs::create_objects() y, pwindow, this, - current_config()->vconfig, + playback_config->vconfig, 0, MODEPLAY); video_device->initialize(); @@ -154,120 +155,120 @@ int PlaybackPrefs::create_objects() return 0; } -char* PlaybackPrefs::strategy_to_string(int strategy) -{ - switch(strategy) - { - case PLAYBACK_LOCALHOST: - return _("Local Host"); - break; - case PLAYBACK_MULTIHEAD: - return _("Multihead"); - break; - case PLAYBACK_BLONDSYMPHONY: - return _("Blond Symphony"); - break; - } - return _("Local Host"); -} - -// Delete strategy dependant objects -void PlaybackPrefs::delete_strategy() -{ - if(head_text) - { - delete head_text; - delete head_title; - head_text = 0; - } - if(host_text) - { - delete host_title; - delete host_text; - host_text = 0; - } - if(head_count_text) - { - delete head_count_title; - delete head_count_text; - head_count_text = 0; - } - if(video_device) - { - delete vdevice_title; - delete video_device; - video_device = 0; - } -} - -int PlaybackPrefs::set_strategy(int strategy) -{ - int x = 350, x1 = 450, y = 10; - delete_strategy(); - - pwindow->thread->edl->session->playback_strategy = strategy; - switch(strategy) - { - case PLAYBACK_LOCALHOST: - break; - case PLAYBACK_MULTIHEAD: - add_subwindow(head_title = new BC_Title(x, y, _("Head:"))); - head_text = new PlaybackHead(this, x1, y); - head_text->create_objects(); - y += 25; - add_subwindow(head_count_title = new BC_Title(x, y, _("Total Heads:"))); - head_count_text = new PlaybackHeadCount(this, x1, y); - head_count_text->create_objects(); - x = 10; - y = 390; - add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:"))); - video_device = new VDevicePrefs(x + 100, - y, - pwindow, - this, - current_config()->vconfig, - 0, - MODEPLAY); - video_device->initialize(); - break; - case PLAYBACK_BLONDSYMPHONY: - add_subwindow(head_title = new BC_Title(x, y, _("Head:"))); - head_text = new PlaybackHead(this, x1, y); - head_text->create_objects(); - y += 25; - add_subwindow(head_count_title = new BC_Title(x, y, _("Total Heads:"))); - head_count_text = new PlaybackHeadCount(this, x1, y); - head_count_text->create_objects(); - y += 25; - add_subwindow(host_title = new BC_Title(x, y, _("Hostname:"))); - add_subwindow(host_text = new PlaybackHost(this, x1, y)); - x = 10; - y = 390; - add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:"))); - video_device = new VDevicePrefs(x + 100, - y, - pwindow, - this, - current_config()->vconfig, - 0, - MODEPLAY); - video_device->initialize(); - break; - } - - return 1; -} - -ArrayList* PlaybackPrefs::current_config_list() -{ - return pwindow->thread->edl->session->get_playback_config( - pwindow->thread->edl->session->playback_strategy); -} +// char* PlaybackPrefs::strategy_to_string(int strategy) +// { +// switch(strategy) +// { +// case PLAYBACK_LOCALHOST: +// return _("Local Host"); +// break; +// case PLAYBACK_MULTIHEAD: +// return _("Multihead"); +// break; +// case PLAYBACK_BLONDSYMPHONY: +// return _("Blond Symphony"); +// break; +// } +// return _("Local Host"); +// } +// +// // Delete strategy dependant objects +// void PlaybackPrefs::delete_strategy() +// { +// if(head_text) +// { +// delete head_text; +// delete head_title; +// head_text = 0; +// } +// if(host_text) +// { +// delete host_title; +// delete host_text; +// host_text = 0; +// } +// if(head_count_text) +// { +// delete head_count_title; +// delete head_count_text; +// head_count_text = 0; +// } +// if(video_device) +// { +// delete vdevice_title; +// delete video_device; +// video_device = 0; +// } +// } +// +// int PlaybackPrefs::set_strategy(int strategy) +// { +// int x = 350, x1 = 450, y = 10; +// delete_strategy(); +// +// pwindow->thread->edl->session->playback_strategy = strategy; +// switch(strategy) +// { +// case PLAYBACK_LOCALHOST: +// break; +// case PLAYBACK_MULTIHEAD: +// add_subwindow(head_title = new BC_Title(x, y, _("Head:"))); +// head_text = new PlaybackHead(this, x1, y); +// head_text->create_objects(); +// y += 25; +// add_subwindow(head_count_title = new BC_Title(x, y, _("Total Heads:"))); +// head_count_text = new PlaybackHeadCount(this, x1, y); +// head_count_text->create_objects(); +// x = 10; +// y = 390; +// add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:"))); +// video_device = new VDevicePrefs(x + 100, +// y, +// pwindow, +// this, +// playback_config->vconfig, +// 0, +// MODEPLAY); +// video_device->initialize(); +// break; +// case PLAYBACK_BLONDSYMPHONY: +// add_subwindow(head_title = new BC_Title(x, y, _("Head:"))); +// head_text = new PlaybackHead(this, x1, y); +// head_text->create_objects(); +// y += 25; +// add_subwindow(head_count_title = new BC_Title(x, y, _("Total Heads:"))); +// head_count_text = new PlaybackHeadCount(this, x1, y); +// head_count_text->create_objects(); +// y += 25; +// add_subwindow(host_title = new BC_Title(x, y, _("Hostname:"))); +// add_subwindow(host_text = new PlaybackHost(this, x1, y)); +// x = 10; +// y = 390; +// add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:"))); +// video_device = new VDevicePrefs(x + 100, +// y, +// pwindow, +// this, +// playback_config->vconfig, +// 0, +// MODEPLAY); +// video_device->initialize(); +// break; +// } +// +// return 1; +// } -PlaybackConfig* PlaybackPrefs::current_config() -{ - return current_config_list()->values[current_head]; -} +// ArrayList* PlaybackPrefs::current_config_list() +// { +// return pwindow->thread->edl->session->get_playback_config( +// pwindow->thread->edl->session->playback_strategy); +// } +// +// PlaybackConfig* PlaybackPrefs::current_config() +// { +// return current_config_list()->values[current_head]; +// } void PlaybackPrefs::update(int interpolation) @@ -298,81 +299,81 @@ int PlaybackPrefs::draw_framerate() -PlaybackStrategy::PlaybackStrategy(PlaybackPrefs *prefs, - int x, - int y) - : BC_PopupTextBox(prefs, - &prefs->strategies, - prefs->strategy_to_string(prefs->pwindow->thread->edl->session->playback_strategy), - x, - y, - 200, - 100) -{ - this->prefs = prefs; -} - -int PlaybackStrategy::handle_event() -{ - prefs->set_strategy(get_number()); - return 1; -} - - - - - -PlaybackHead::PlaybackHead(PlaybackPrefs *prefs, - int x, - int y) - : BC_TumbleTextBox(prefs, - prefs->current_head, - (int64_t)0, - (int64_t)prefs->current_config_list()->total - 1, - x, - y, - 100) -{ - this->prefs = prefs; -} - -int PlaybackHead::handle_event() -{ - return 1; -} - -PlaybackHeadCount::PlaybackHeadCount(PlaybackPrefs *prefs, - int x, - int y) - : BC_TumbleTextBox(prefs, - prefs->current_config_list()->total, - 1, - MAX_CHANNELS, - x, - y, - 100) -{ - this->prefs = prefs; -} - -int PlaybackHeadCount::handle_event() -{ - return 1; -} - - - -PlaybackHost::PlaybackHost(PlaybackPrefs *prefs, int x, int y) - : BC_TextBox(x, y, 100, 1, prefs->current_config()->hostname) -{ - this->prefs = prefs; -} - -int PlaybackHost::handle_event() -{ - strcpy(prefs->current_config()->hostname, get_text()); - return 1; -} +// PlaybackStrategy::PlaybackStrategy(PlaybackPrefs *prefs, +// int x, +// int y) +// : BC_PopupTextBox(prefs, +// &prefs->strategies, +// prefs->strategy_to_string(prefs->pwindow->thread->edl->session->playback_strategy), +// x, +// y, +// 200, +// 100) +// { +// this->prefs = prefs; +// } +// +// int PlaybackStrategy::handle_event() +// { +// prefs->set_strategy(get_number()); +// return 1; +// } +// +// +// +// +// +// PlaybackHead::PlaybackHead(PlaybackPrefs *prefs, +// int x, +// int y) +// : BC_TumbleTextBox(prefs, +// prefs->current_head, +// (int64_t)0, +// (int64_t)prefs->current_config_list()->total - 1, +// x, +// y, +// 100) +// { +// this->prefs = prefs; +// } +// +// int PlaybackHead::handle_event() +// { +// return 1; +// } +// +// PlaybackHeadCount::PlaybackHeadCount(PlaybackPrefs *prefs, +// int x, +// int y) +// : BC_TumbleTextBox(prefs, +// prefs->current_config_list()->total, +// 1, +// MAX_CHANNELS, +// x, +// y, +// 100) +// { +// this->prefs = prefs; +// } +// +// int PlaybackHeadCount::handle_event() +// { +// return 1; +// } +// +// +// +// PlaybackHost::PlaybackHost(PlaybackPrefs *prefs, int x, int y) +// : BC_TextBox(x, y, 100, 1, prefs->current_config()->hostname) +// { +// this->prefs = prefs; +// } +// +// int PlaybackHost::handle_event() +// { +// strcpy(prefs->current_config()->hostname, get_text()); +// return 1; +// } @@ -451,7 +452,7 @@ PlaybackModuleFragment::PlaybackModuleFragment(int x, int PlaybackModuleFragment::handle_event() { - playback->current_config()->aconfig->fragment_size = atol(get_text()); + playback->playback_config->aconfig->fragment_size = atol(get_text()); return 1; } diff --git a/hvirtual/cinelerra/playbackprefs.h b/hvirtual/cinelerra/playbackprefs.h index 00681ad7..92958a9d 100644 --- a/hvirtual/cinelerra/playbackprefs.h +++ b/hvirtual/cinelerra/playbackprefs.h @@ -35,15 +35,16 @@ public: ~PlaybackPrefs(); int create_objects(); - int set_strategy(int strategy); +// int set_strategy(int strategy); int get_buffer_bytes(); static char* strategy_to_string(int strategy); void delete_strategy(); - - ArrayList* current_config_list(); - PlaybackConfig* current_config(); +/* + * ArrayList* current_config_list(); + * PlaybackConfig* current_config(); + */ void update(int interpolation); int draw_framerate(); @@ -51,6 +52,7 @@ public: VDevicePrefs *video_device; ArrayList strategies; + PlaybackConfig *playback_config; BC_Title *framerate_title; PlaybackNearest *nearest_neighbor; PlaybackBicubicBicubic *cubic_cubic; @@ -58,50 +60,52 @@ public: PlaybackBilinearBilinear *linear_linear; PlaybackDeblock *mpeg4_deblock; - int64_t current_head; - BC_Title *head_title; - BC_Title *host_title; - BC_Title *head_count_title; +// int64_t current_head; +// BC_Title *head_title; +// BC_Title *host_title; +// BC_Title *head_count_title; BC_Title *vdevice_title; - PlaybackHead *head_text; - PlaybackHeadCount *head_count_text; - PlaybackHost *host_text; +// PlaybackHead *head_text; +// PlaybackHeadCount *head_count_text; +// PlaybackHost *host_text; }; -class PlaybackStrategy : public BC_PopupTextBox -{ -public: - PlaybackStrategy(PlaybackPrefs *prefs, int x, int y); - int handle_event(); - - PlaybackPrefs *prefs; -}; - -class PlaybackHead : public BC_TumbleTextBox -{ -public: - PlaybackHead(PlaybackPrefs *prefs, int x, int y); - int handle_event(); - PlaybackPrefs *prefs; -}; - -class PlaybackHeadCount : public BC_TumbleTextBox -{ -public: - PlaybackHeadCount(PlaybackPrefs *prefs, int x, int y); - int handle_event(); - PlaybackPrefs *prefs; -}; - -class PlaybackHost : public BC_TextBox -{ -public: - PlaybackHost(PlaybackPrefs *prefs, int x, int y); - int handle_event(); - PlaybackPrefs *prefs; -}; - +/* + * class PlaybackStrategy : public BC_PopupTextBox + * { + * public: + * PlaybackStrategy(PlaybackPrefs *prefs, int x, int y); + * int handle_event(); + * + * PlaybackPrefs *prefs; + * }; + * + * class PlaybackHead : public BC_TumbleTextBox + * { + * public: + * PlaybackHead(PlaybackPrefs *prefs, int x, int y); + * int handle_event(); + * PlaybackPrefs *prefs; + * }; + * + * class PlaybackHeadCount : public BC_TumbleTextBox + * { + * public: + * PlaybackHeadCount(PlaybackPrefs *prefs, int x, int y); + * int handle_event(); + * PlaybackPrefs *prefs; + * }; + * + * class PlaybackHost : public BC_TextBox + * { + * public: + * PlaybackHost(PlaybackPrefs *prefs, int x, int y); + * int handle_event(); + * PlaybackPrefs *prefs; + * }; + * + */ /* * class PlaybackBufferSize : public BC_TextBox * { diff --git a/hvirtual/cinelerra/pluginaclient.h b/hvirtual/cinelerra/pluginaclient.h index b10d1d63..f9092c08 100644 --- a/hvirtual/cinelerra/pluginaclient.h +++ b/hvirtual/cinelerra/pluginaclient.h @@ -15,14 +15,6 @@ public: int get_render_ptrs(); int init_realtime_parameters(); -// Replaced by pull method -/* - * void plugin_process_realtime(double **input, - * double **output, - * int64_t current_position, - * int64_t fragment_size, - * int64_t total_len); - */ int is_audio(); // These should return 1 if error or 0 if success. // Multichannel buffer process for backwards compatibility diff --git a/hvirtual/cinelerra/pluginclient.h b/hvirtual/cinelerra/pluginclient.h index 050f379c..85a877a0 100644 --- a/hvirtual/cinelerra/pluginclient.h +++ b/hvirtual/cinelerra/pluginclient.h @@ -62,14 +62,16 @@ public: \ void run(); \ window_class *window; \ plugin_class *plugin; \ + Condition *completion; \ }; #define PLUGIN_THREAD_OBJECT(plugin_class, thread_class, window_class) \ thread_class::thread_class(plugin_class *plugin) \ - : Thread(0, 0, 1) \ + : Thread(0, 0, 0) \ { \ this->plugin = plugin; \ + completion = new Condition(0, "thread_class::completion"); \ } \ \ thread_class::~thread_class() \ @@ -88,6 +90,8 @@ void thread_class::run() \ /* Only set it here so tracking doesn't update it until everything is created. */ \ plugin->thread = this; \ int result = window->run_window(); \ + completion->unlock(); \ +/* This is needed when the GUI is closed from itself */ \ if(result) plugin->client_side_close(); \ } @@ -113,9 +117,15 @@ void thread_class::run() \ #define PLUGIN_DESTRUCTOR_MACRO \ if(thread) \ { \ +/* This is needed when the GUI is closed from elsewhere than itself */ \ + thread->window->lock_window("PLUGIN_DESTRUCTOR_MACRO"); \ thread->window->set_done(0); \ + thread->window->unlock_window(); \ + thread->completion->lock("PLUGIN_DESTRUCTOR_MACRO"); \ + delete thread; \ } \ \ + \ if(defaults) save_defaults(); \ if(defaults) delete defaults; diff --git a/hvirtual/cinelerra/plugindialog.C b/hvirtual/cinelerra/plugindialog.C index 2bb2167c..4ada0f2d 100644 --- a/hvirtual/cinelerra/plugindialog.C +++ b/hvirtual/cinelerra/plugindialog.C @@ -1,10 +1,13 @@ +#include "condition.h" #include "edl.h" +#include "language.h" #include "localsession.h" #include "mainsession.h" #include "mainundo.h" #include "mwindow.h" #include "mwindowgui.h" #include "module.h" +#include "mutex.h" #include "plugin.h" #include "plugindialog.h" #include "pluginserver.h" @@ -13,11 +16,6 @@ #include "tracks.h" #include "transition.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - PluginDialogThread::PluginDialogThread(MWindow *mwindow) : Thread() @@ -26,6 +24,8 @@ PluginDialogThread::PluginDialogThread(MWindow *mwindow) window = 0; plugin = 0; Thread::set_synchronous(0); + window_lock = new Mutex("PluginDialogThread::window_lock"); + completion = new Condition(1, "PluginDialogThread::completion"); } PluginDialogThread::~PluginDialogThread() @@ -33,9 +33,11 @@ PluginDialogThread::~PluginDialogThread() if(window) { window->set_done(1); - completion.lock(); - completion.unlock(); + completion->lock("PluginDialogThread::~PluginDialogThread"); + completion->unlock(); } + delete window_lock; + delete completion; } void PluginDialogThread::start_window(Track *track, @@ -44,8 +46,15 @@ void PluginDialogThread::start_window(Track *track, { if(Thread::running()) { - window->raise_window(); - window->flush(); + window_lock->lock("PluginDialogThread::start_window"); + if(window) + { + window->lock_window("PluginDialogThread::start_window"); + window->raise_window(); + window->flush(); + window->unlock_window(); + } + window_lock->unlock(); } else { @@ -68,7 +77,7 @@ void PluginDialogThread::start_window(Track *track, } strcpy(this->window_title, title); - completion.lock(); + completion->lock("PluginDialogThread::start_window"); Thread::start(); } } @@ -83,19 +92,30 @@ void PluginDialogThread::run() { int result = 0; - window = new PluginDialog(mwindow, this, window_title); + int x = mwindow->gui->get_abs_cursor_x(1) - mwindow->session->plugindialog_w / 2; + int y = mwindow->gui->get_abs_cursor_y(1) - mwindow->session->plugindialog_h / 2; + + window_lock->lock("PluginDialogThread::run 1"); + window = new PluginDialog(mwindow, this, window_title, x, y); window->create_objects(); + window_lock->unlock(); + result = window->run_window(); + + + window_lock->lock("PluginDialogThread::run 2"); delete window; window = 0; - completion.unlock(); + window_lock->unlock(); + + completion->unlock(); // Done at closing if(!result) { if(plugin_type) { - mwindow->gui->lock_window(); + mwindow->gui->lock_window("PluginDialogThread::run 3"); mwindow->undo->update_undo_before(_("attach effect"), LOAD_EDITS | LOAD_PATCHES); @@ -146,10 +166,12 @@ void PluginDialogThread::run() PluginDialog::PluginDialog(MWindow *mwindow, PluginDialogThread *thread, - char *window_title) + char *window_title, + int x, + int y) : BC_Window(window_title, - mwindow->gui->get_abs_cursor_x() - mwindow->session->plugindialog_w / 2, - mwindow->gui->get_abs_cursor_y() - mwindow->session->plugindialog_h / 2, + x, + y, mwindow->session->plugindialog_w, mwindow->session->plugindialog_h, 510, @@ -160,6 +182,12 @@ PluginDialog::PluginDialog(MWindow *mwindow, { this->mwindow = mwindow; this->thread = thread; + standalone_attach = 0; + shared_attach = 0; + module_attach = 0; + standalone_change = 0; + shared_change = 0; + module_change = 0; inoutthru = 0; } @@ -181,9 +209,12 @@ PluginDialog::~PluginDialog() delete standalone_list; delete shared_list; delete module_list; - delete standalone_attach; - delete shared_attach; - delete module_attach; + if(standalone_attach) delete standalone_attach; + if(shared_attach) delete shared_attach; + if(module_attach) delete module_attach; + if(standalone_change) delete standalone_change; + if(shared_change) delete shared_change; + if(module_change) delete module_change; // delete in; // delete out; } @@ -271,10 +302,17 @@ int PluginDialog::create_objects() mwindow->theme->plugindialog_new_y, mwindow->theme->plugindialog_new_w, mwindow->theme->plugindialog_new_h)); - add_subwindow(standalone_attach = new PluginDialogAttachNew(mwindow, - this, - mwindow->theme->plugindialog_newattach_x, - mwindow->theme->plugindialog_newattach_y)); + + if(thread->plugin) + add_subwindow(standalone_change = new PluginDialogChangeNew(mwindow, + this, + mwindow->theme->plugindialog_newattach_x, + mwindow->theme->plugindialog_newattach_y)); + else + add_subwindow(standalone_attach = new PluginDialogAttachNew(mwindow, + this, + mwindow->theme->plugindialog_newattach_x, + mwindow->theme->plugindialog_newattach_y)); @@ -292,10 +330,16 @@ int PluginDialog::create_objects() mwindow->theme->plugindialog_shared_y, mwindow->theme->plugindialog_shared_w, mwindow->theme->plugindialog_shared_h)); - add_subwindow(shared_attach = new PluginDialogAttachShared(mwindow, - this, - mwindow->theme->plugindialog_sharedattach_x, - mwindow->theme->plugindialog_sharedattach_y)); + if(thread->plugin) + add_subwindow(shared_change = new PluginDialogChangeShared(mwindow, + this, + mwindow->theme->plugindialog_sharedattach_x, + mwindow->theme->plugindialog_sharedattach_y)); + else + add_subwindow(shared_attach = new PluginDialogAttachShared(mwindow, + this, + mwindow->theme->plugindialog_sharedattach_x, + mwindow->theme->plugindialog_sharedattach_y)); @@ -314,10 +358,16 @@ int PluginDialog::create_objects() mwindow->theme->plugindialog_module_y, mwindow->theme->plugindialog_module_w, mwindow->theme->plugindialog_module_h)); - add_subwindow(module_attach = new PluginDialogAttachModule(mwindow, - this, - mwindow->theme->plugindialog_moduleattach_x, - mwindow->theme->plugindialog_moduleattach_y)); + if(thread->plugin) + add_subwindow(module_change = new PluginDialogChangeModule(mwindow, + this, + mwindow->theme->plugindialog_moduleattach_x, + mwindow->theme->plugindialog_moduleattach_y)); + else + add_subwindow(module_attach = new PluginDialogAttachModule(mwindow, + this, + mwindow->theme->plugindialog_moduleattach_x, + mwindow->theme->plugindialog_moduleattach_y)); @@ -349,8 +399,12 @@ int PluginDialog::resize_event(int w, int h) mwindow->theme->plugindialog_new_y, mwindow->theme->plugindialog_new_w, mwindow->theme->plugindialog_new_h); - standalone_attach->reposition_window(mwindow->theme->plugindialog_newattach_x, - mwindow->theme->plugindialog_newattach_y); + if(standalone_attach) + standalone_attach->reposition_window(mwindow->theme->plugindialog_newattach_x, + mwindow->theme->plugindialog_newattach_y); + else + standalone_change->reposition_window(mwindow->theme->plugindialog_newattach_x, + mwindow->theme->plugindialog_newattach_y); @@ -362,8 +416,12 @@ int PluginDialog::resize_event(int w, int h) mwindow->theme->plugindialog_shared_y, mwindow->theme->plugindialog_shared_w, mwindow->theme->plugindialog_shared_h); - shared_attach->reposition_window(mwindow->theme->plugindialog_sharedattach_x, - mwindow->theme->plugindialog_sharedattach_y); + if(shared_attach) + shared_attach->reposition_window(mwindow->theme->plugindialog_sharedattach_x, + mwindow->theme->plugindialog_sharedattach_y); + else + shared_change->reposition_window(mwindow->theme->plugindialog_sharedattach_x, + mwindow->theme->plugindialog_sharedattach_y); @@ -375,8 +433,12 @@ int PluginDialog::resize_event(int w, int h) mwindow->theme->plugindialog_module_y, mwindow->theme->plugindialog_module_w, mwindow->theme->plugindialog_module_h); - module_attach->reposition_window(mwindow->theme->plugindialog_moduleattach_x, - mwindow->theme->plugindialog_moduleattach_y); + if(module_attach) + module_attach->reposition_window(mwindow->theme->plugindialog_moduleattach_x, + mwindow->theme->plugindialog_moduleattach_y); + else + module_change->reposition_window(mwindow->theme->plugindialog_moduleattach_x, + mwindow->theme->plugindialog_moduleattach_y); flush(); } @@ -505,6 +567,21 @@ int PluginDialogAttachNew::handle_event() return 1; } +PluginDialogChangeNew::PluginDialogChangeNew(MWindow *mwindow, PluginDialog *dialog, int x, int y) + : BC_GenericButton(x, y, _("Change")) +{ + this->dialog = dialog; +} +PluginDialogChangeNew::~PluginDialogChangeNew() +{ +} +int PluginDialogChangeNew::handle_event() +{ + dialog->attach_new(dialog->selected_available); + set_done(0); + return 1; +} + @@ -559,6 +636,23 @@ int PluginDialogAttachShared::handle_event() return 1; } +PluginDialogChangeShared::PluginDialogChangeShared(MWindow *mwindow, + PluginDialog *dialog, + int x, + int y) + : BC_GenericButton(x, y, _("Change")) +{ + this->dialog = dialog; +} +PluginDialogChangeShared::~PluginDialogChangeShared() { } +int PluginDialogChangeShared::handle_event() +{ + dialog->attach_shared(dialog->selected_shared); + set_done(0); + return 1; +} + + @@ -617,6 +711,23 @@ int PluginDialogAttachModule::handle_event() return 1; } +PluginDialogChangeModule::PluginDialogChangeModule(MWindow *mwindow, + PluginDialog *dialog, + int x, + int y) + : BC_GenericButton(x, y, _("Change")) +{ + this->dialog = dialog; +} +PluginDialogChangeModule::~PluginDialogChangeModule() { } +int PluginDialogChangeModule::handle_event() +{ + dialog->attach_module(dialog->selected_modules); + set_done(0); + return 1; +} + + diff --git a/hvirtual/cinelerra/plugindialog.h b/hvirtual/cinelerra/plugindialog.h index 63601648..41f6d7f2 100644 --- a/hvirtual/cinelerra/plugindialog.h +++ b/hvirtual/cinelerra/plugindialog.h @@ -9,14 +9,19 @@ class PluginDialogModules; class PluginDialogAttachNew; class PluginDialogAttachShared; class PluginDialogAttachModule; +class PluginDialogChangeNew; +class PluginDialogChangeShared; +class PluginDialogChangeModule; class PluginDialogIn; class PluginDialogOut; class PluginDialogThru; class PluginDialog; +#include "condition.inc" #include "guicast.h" -#include "plugin.inc" +#include "mutex.inc" #include "mwindow.inc" +#include "plugin.inc" #include "sharedlocation.h" #include "thread.h" #include "transition.inc" @@ -43,7 +48,8 @@ public: PluginDialog *window; // Plugin being modified if there is one Plugin *plugin; - Mutex completion; + Condition *completion; + Mutex *window_lock; char window_title[BCTEXTLEN]; @@ -55,15 +61,16 @@ public: // Title of attached plugin if new char plugin_title[BCTEXTLEN]; - -// Routing -// int in, out; }; class PluginDialog : public BC_Window { public: - PluginDialog(MWindow *mwindow, PluginDialogThread *thread, char *title); + PluginDialog(MWindow *mwindow, + PluginDialogThread *thread, + char *title, + int x, + int y); ~PluginDialog(); int create_objects(); @@ -86,6 +93,10 @@ public: PluginDialogAttachShared *shared_attach; PluginDialogAttachModule *module_attach; + PluginDialogChangeNew *standalone_change; + PluginDialogChangeShared *shared_change; + PluginDialogChangeModule *module_change; + PluginDialogThru *thru; PluginDialogThread *thread; @@ -137,6 +148,17 @@ public: PluginDialog *dialog; }; +class PluginDialogChangeNew : public BC_GenericButton +{ +public: + PluginDialogChangeNew(MWindow *mwindow, PluginDialog *dialog, int x, int y); + ~PluginDialogChangeNew(); + + int handle_event(); + PluginDialog *dialog; +}; + + class PluginDialogNew : public BC_ListBox { public: @@ -195,6 +217,17 @@ public: PluginDialog *dialog; }; +class PluginDialogChangeShared : public BC_GenericButton +{ +public: + PluginDialogChangeShared(MWindow *mwindow, PluginDialog *dialog, int x, int y); + ~PluginDialogChangeShared(); + + int handle_event(); + PluginDialog *dialog; +}; + + class PluginDialogAttachModule : public BC_GenericButton { public: @@ -205,6 +238,17 @@ public: PluginDialog *dialog; }; +class PluginDialogChangeModule : public BC_GenericButton +{ +public: + PluginDialogChangeModule(MWindow *mwindow, PluginDialog *dialog, int x, int y); + ~PluginDialogChangeModule(); + + int handle_event(); + PluginDialog *dialog; +}; + + class PluginDialogIn : public BC_CheckBox { public: diff --git a/hvirtual/cinelerra/pluginpopup.C b/hvirtual/cinelerra/pluginpopup.C index d9be2a7a..6dc251fb 100644 --- a/hvirtual/cinelerra/pluginpopup.C +++ b/hvirtual/cinelerra/pluginpopup.C @@ -26,7 +26,7 @@ PluginPopup::~PluginPopup() void PluginPopup::create_objects() { - add_item(attach = new PluginPopupAttach(mwindow, this)); + add_item(change = new PluginPopupChange(mwindow, this)); add_item(detach = new PluginPopupDetach(mwindow, this)); // add_item(in = new PluginPopupIn(mwindow, this)); // add_item(out = new PluginPopupOut(mwindow, this)); @@ -55,24 +55,25 @@ int PluginPopup::update(Plugin *plugin) -PluginPopupAttach::PluginPopupAttach(MWindow *mwindow, PluginPopup *popup) - : BC_MenuItem(_("Attach...")) +PluginPopupChange::PluginPopupChange(MWindow *mwindow, PluginPopup +*popup) + : BC_MenuItem(_("Change...")) { this->mwindow = mwindow; this->popup = popup; dialog_thread = new PluginDialogThread(mwindow); } -PluginPopupAttach::~PluginPopupAttach() +PluginPopupChange::~PluginPopupChange() { delete dialog_thread; } -int PluginPopupAttach::handle_event() +int PluginPopupChange::handle_event() { dialog_thread->start_window(popup->plugin->track, - popup->plugin, - PROGRAM_NAME ": Attach Effect"); + popup->plugin, + PROGRAM_NAME ": Change Effect"); } @@ -81,6 +82,7 @@ int PluginPopupAttach::handle_event() + PluginPopupDetach::PluginPopupDetach(MWindow *mwindow, PluginPopup *popup) : BC_MenuItem(_("Detach")) { diff --git a/hvirtual/cinelerra/pluginpopup.h b/hvirtual/cinelerra/pluginpopup.h new file mode 100644 index 00000000..4e57e60c --- /dev/null +++ b/hvirtual/cinelerra/pluginpopup.h @@ -0,0 +1,154 @@ +#ifndef PLUGINPOPUP_H +#define PLUGINPOPUP_H + +class PluginPopupChange; +class PluginPopupDetach; +class PluginPopupIn; +class PluginPopupOut; +class PluginPopupOn; +class PluginPopupShow; + +#include "guicast.h" +#include "mwindow.inc" +#include "mwindowgui.inc" +#include "plugin.inc" +#include "plugindialog.inc" + + + +class PluginPopup : public BC_PopupMenu +{ +public: + PluginPopup(MWindow *mwindow, MWindowGUI *gui); + ~PluginPopup(); + + void create_objects(); + int update(Plugin *plugin); + + MWindow *mwindow; + MWindowGUI *gui; +// Acquired through the update command as the plugin currently being operated on + Plugin *plugin; + + + + + + + + PluginPopupChange *change; + PluginPopupDetach *detach; +// PluginPopupIn *in; +// PluginPopupOut *out; + PluginPopupShow *show; + PluginPopupOn *on; +}; + +class PluginPopupAttach : public BC_MenuItem +{ +public: + PluginPopupAttach(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupAttach(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; + PluginDialogThread *dialog_thread; +}; + +class PluginPopupChange : public BC_MenuItem +{ +public: + PluginPopupChange(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupChange(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; + PluginDialogThread *dialog_thread; +}; + + +class PluginPopupDetach : public BC_MenuItem +{ +public: + PluginPopupDetach(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupDetach(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; +}; + + +class PluginPopupIn : public BC_MenuItem +{ +public: + PluginPopupIn(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupIn(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; +}; + +class PluginPopupOut : public BC_MenuItem +{ +public: + PluginPopupOut(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupOut(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; +}; + +class PluginPopupShow : public BC_MenuItem +{ +public: + PluginPopupShow(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupShow(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; +}; + +class PluginPopupOn : public BC_MenuItem +{ +public: + PluginPopupOn(MWindow *mwindow, PluginPopup *popup); + ~PluginPopupOn(); + + int handle_event(); + + MWindow *mwindow; + PluginPopup *popup; +}; + +class PluginPopupUp : public BC_MenuItem +{ +public: + PluginPopupUp(MWindow *mwindow, PluginPopup *popup); + int handle_event(); + MWindow *mwindow; + PluginPopup *popup; +}; + +class PluginPopupDown : public BC_MenuItem +{ +public: + PluginPopupDown(MWindow *mwindow, PluginPopup *popup); + int handle_event(); + MWindow *mwindow; + PluginPopup *popup; +}; + + +#endif diff --git a/hvirtual/cinelerra/pluginserver.C b/hvirtual/cinelerra/pluginserver.C index fec8ef77..f64e1b23 100644 --- a/hvirtual/cinelerra/pluginserver.C +++ b/hvirtual/cinelerra/pluginserver.C @@ -199,16 +199,15 @@ int PluginServer::open_plugin(int master, { if(plugin_open) return 0; - if(!plugin_fd) plugin_fd = dlopen(path, RTLD_NOW); this->preferences = preferences; this->plugin = plugin; this->edl = edl; -//printf("PluginServer::open_plugin %s %p %p\n", path, this->plugin, plugin_fd); + if(!new_plugin && !plugin_fd) plugin_fd = dlopen(path, RTLD_NOW); - if(!plugin_fd) + if(!new_plugin && !plugin_fd) { // If the dlopen failed it may still be an executable tool for a specific // file format, in which case we just store the path. @@ -225,7 +224,6 @@ int PluginServer::open_plugin(int master, if(!new_plugin && !lad_descriptor) { -//printf("%p %p\n", dlsym(RTLD_NEXT, "open"), dlsym(RTLD_NEXT, "open64")); new_plugin = (PluginClient* (*)(PluginServer*))dlsym(plugin_fd, "new_plugin"); // Probably a LAD plugin but we're not going to instantiate it here anyway. @@ -234,7 +232,6 @@ int PluginServer::open_plugin(int master, lad_descriptor_function = (LADSPA_Descriptor_Function)dlsym( plugin_fd, "ladspa_descriptor"); -//printf("PluginServer::open_plugin 2 %p\n", lad_descriptor_function); if(!lad_descriptor_function) { @@ -259,7 +256,6 @@ int PluginServer::open_plugin(int master, { dlclose(plugin_fd); plugin_fd = 0; -//printf("PluginServer::open_plugin 1 %s\n", path); return PLUGINSERVER_IS_LAD; } } @@ -306,11 +302,9 @@ int PluginServer::close_plugin() // shared object is persistent since plugin deletion would unlink its own object // dlclose(plugin_fd); -//printf("PluginServer::close_plugin 1\n"); plugin_open = 0; cleanup_plugin(); -//printf("PluginServer::close_plugin 2\n"); return 0; } @@ -406,7 +400,7 @@ void PluginServer::process_buffer(VFrame **frame, } - vclient->age_temp(); + vclient->age_temp(); } void PluginServer::process_buffer(double **buffer, @@ -579,6 +573,7 @@ int PluginServer::read_frame(VFrame *buffer, start_position, PLAY_FORWARD, mwindow->edl->session->frame_rate, + 0, 0); return 0; } @@ -612,6 +607,7 @@ int PluginServer::read_frame(VFrame *buffer, if(!multichannel) channel = 0; + if(nodes->total > channel) { return ((VirtualVNode*)nodes->values[channel])->read_data(buffer, @@ -625,6 +621,7 @@ int PluginServer::read_frame(VFrame *buffer, start_position, PLAY_FORWARD, frame_rate, + 0, 0); } else @@ -934,11 +931,8 @@ Theme* PluginServer::get_theme() // Called when plugin interface is tweeked void PluginServer::sync_parameters() { -TRACE("PluginServer::sync_parameters 1\n"); if(video) mwindow->restart_brender(); -TRACE("PluginServer::sync_parameters 10\n"); mwindow->sync_parameters(); -TRACE("PluginServer::sync_parameters 20\n"); if(mwindow->edl->session->auto_conf->plugins) { mwindow->gui->lock_window("PluginServer::sync_parameters"); @@ -946,7 +940,6 @@ TRACE("PluginServer::sync_parameters 20\n"); mwindow->gui->canvas->flash(); mwindow->gui->unlock_window(); } -TRACE("PluginServer::sync_parameters 30\n"); } diff --git a/hvirtual/cinelerra/pluginserver.h b/hvirtual/cinelerra/pluginserver.h index 1d5779c2..a287da6c 100644 --- a/hvirtual/cinelerra/pluginserver.h +++ b/hvirtual/cinelerra/pluginserver.h @@ -323,7 +323,8 @@ private: // Handle from dlopen. Plugins are opened once at startup and stored in the master // plugindb. void *plugin_fd; -// Pointers to C functions +// If no path, this is going to be set to a function which +// instantiates the plugin. PluginClient* (*new_plugin)(PluginServer*); // LAD support diff --git a/hvirtual/cinelerra/pluginvclient.h b/hvirtual/cinelerra/pluginvclient.h index caa6d33d..775e20b4 100644 --- a/hvirtual/cinelerra/pluginvclient.h +++ b/hvirtual/cinelerra/pluginvclient.h @@ -8,7 +8,7 @@ // Maximum dimensions for a temporary frame a plugin should retain between -// process_buffer calls. +// process_buffer calls. This allows memory conservation. #define PLUGIN_MAX_W 2000 #define PLUGIN_MAX_H 1000 diff --git a/hvirtual/cinelerra/preferences.C b/hvirtual/cinelerra/preferences.C index 410c3aba..99266712 100644 --- a/hvirtual/cinelerra/preferences.C +++ b/hvirtual/cinelerra/preferences.C @@ -32,7 +32,7 @@ Preferences::Preferences() // Set defaults FileSystem fs; - preferences_lock = new Mutex; + preferences_lock = new Mutex("Preferences::preferences_lock"); sprintf(index_directory, BCASTDIR); if(strlen(index_directory)) fs.complete_path(index_directory); @@ -72,7 +72,7 @@ Preferences::~Preferences() void Preferences::copy_rates_from(Preferences *preferences) { - preferences_lock->lock(); + preferences_lock->lock("Preferences::copy_rates_from"); // Need to match node titles in case the order changed and in case // one of the nodes in the source is the master node. local_rate = preferences->local_rate; @@ -305,7 +305,7 @@ void Preferences::add_node(char *text, int port, int enabled, float rate) { if(text[0] == 0) return; - preferences_lock->lock(); + preferences_lock->lock("Preferences::add_node"); char *new_item = new char[strlen(text) + 1]; strcpy(new_item, text); renderfarm_nodes.append(new_item); @@ -317,7 +317,7 @@ void Preferences::add_node(char *text, int port, int enabled, float rate) void Preferences::delete_node(int number) { - preferences_lock->lock(); + preferences_lock->lock("Preferences::delete_node"); if(number < renderfarm_nodes.total) { delete [] renderfarm_nodes.values[number]; @@ -331,7 +331,7 @@ void Preferences::delete_node(int number) void Preferences::delete_nodes() { - preferences_lock->lock(); + preferences_lock->lock("Preferences::delete_nodes"); for(int i = 0; i < renderfarm_nodes.total; i++) delete [] renderfarm_nodes.values[i]; renderfarm_nodes.remove_all(); @@ -374,7 +374,7 @@ void Preferences::set_rate(float rate, int node) float Preferences::get_avg_rate(int use_master_node) { - preferences_lock->lock(); + preferences_lock->lock("Preferences::get_avg_rate"); float total = 0.0; if(renderfarm_rate.total) { diff --git a/hvirtual/cinelerra/preferencesthread.C b/hvirtual/cinelerra/preferencesthread.C index a3a79dc1..323dc519 100644 --- a/hvirtual/cinelerra/preferencesthread.C +++ b/hvirtual/cinelerra/preferencesthread.C @@ -16,6 +16,7 @@ #include "levelwindow.h" #include "levelwindowgui.h" #include "meterpanel.h" +#include "mutex.h" #include "mwindow.h" #include "mwindowgui.h" #include "patchbay.h" @@ -32,6 +33,12 @@ #include + + +#define WIDTH 750 +#define HEIGHT 700 + + PreferencesMenuitem::PreferencesMenuitem(MWindow *mwindow) : BC_MenuItem(_("Preferences..."), "Shift+P", 'P') { @@ -49,8 +56,23 @@ PreferencesMenuitem::~PreferencesMenuitem() int PreferencesMenuitem::handle_event() { - if(thread->thread_running) return 1; - thread->start(); + if(!thread->running()) + { + thread->start(); + } + else + { +// window_lock has to be locked but window can't be locked until after +// it is known to exist, so we neglect window_lock for now + if(thread->window) + { + thread->window_lock->lock("SetFormat::handle_event"); + thread->window->lock_window("PreferencesMenuitem::handle_event"); + thread->window->raise_window(); + thread->window->unlock_window(); + thread->window_lock->unlock(); + } + } return 1; } @@ -63,10 +85,12 @@ PreferencesThread::PreferencesThread(MWindow *mwindow) this->mwindow = mwindow; window = 0; thread_running = 0; + window_lock = new Mutex("PreferencesThread::window_lock"); } PreferencesThread::~PreferencesThread() { + delete window_lock; } void PreferencesThread::run() @@ -88,8 +112,14 @@ void PreferencesThread::run() need_new_indexes = 0; rerender = 0; - window = new PreferencesWindow(mwindow, this); + int x = mwindow->gui->get_root_w(0, 1) / 2 - WIDTH / 2; + int y = mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2; + + window_lock->lock("PreferencesThread::run 1"); + window = new PreferencesWindow(mwindow, this, x, y); window->create_objects(); + window_lock->unlock(); + thread_running = 1; int result = window->run_window(); @@ -100,8 +130,10 @@ void PreferencesThread::run() mwindow->save_defaults(); } + window_lock->lock("PreferencesThread::run 2"); delete window; window = 0; + window_lock->unlock(); delete preferences; delete edl; @@ -122,10 +154,10 @@ int PreferencesThread::apply_settings() // Compare sessions - AudioOutConfig *this_aconfig = edl->session->get_playback_config(edl->session->playback_strategy, 0)->aconfig; - VideoOutConfig *this_vconfig = edl->session->get_playback_config(edl->session->playback_strategy, 0)->vconfig; - AudioOutConfig *aconfig = mwindow->edl->session->get_playback_config(edl->session->playback_strategy, 0)->aconfig; - VideoOutConfig *vconfig = mwindow->edl->session->get_playback_config(edl->session->playback_strategy, 0)->vconfig; + AudioOutConfig *this_aconfig = edl->session->playback_config->aconfig; + VideoOutConfig *this_vconfig = edl->session->playback_config->vconfig; + AudioOutConfig *aconfig = mwindow->edl->session->playback_config->aconfig; + VideoOutConfig *vconfig = mwindow->edl->session->playback_config->vconfig; rerender = @@ -136,7 +168,6 @@ int PreferencesThread::apply_settings() (edl->session->playback_software_position != mwindow->edl->session->playback_software_position) || (edl->session->test_playback_edits != mwindow->edl->session->test_playback_edits) || (edl->session->playback_buffer != mwindow->edl->session->playback_buffer) || - (edl->session->playback_strategy != mwindow->edl->session->playback_strategy) || (preferences->force_uniprocessor != preferences->force_uniprocessor) || (*this_aconfig != *aconfig) || (*this_vconfig != *vconfig) || @@ -154,28 +185,32 @@ int PreferencesThread::apply_settings() { mwindow->cwindow->gui->lock_window("PreferencesThread::apply_settings"); mwindow->cwindow->gui->meters->change_format(edl->session->meter_format, - edl->session->min_meter_db); + edl->session->min_meter_db, + edl->session->max_meter_db); mwindow->cwindow->gui->unlock_window(); mwindow->vwindow->gui->lock_window("PreferencesThread::apply_settings"); mwindow->vwindow->gui->meters->change_format(edl->session->meter_format, - edl->session->min_meter_db); + edl->session->min_meter_db, + edl->session->max_meter_db); mwindow->vwindow->gui->unlock_window(); mwindow->gui->lock_window("PreferencesThread::apply_settings 1"); mwindow->gui->patchbay->change_meter_format(edl->session->meter_format, - edl->session->min_meter_db); + edl->session->min_meter_db, + edl->session->max_meter_db); mwindow->gui->unlock_window(); mwindow->lwindow->gui->lock_window("PreferencesThread::apply_settings"); mwindow->lwindow->gui->panel->change_format(edl->session->meter_format, - edl->session->min_meter_db); + edl->session->min_meter_db, + edl->session->max_meter_db); mwindow->lwindow->gui->unlock_window(); } @@ -205,7 +240,9 @@ int PreferencesThread::apply_settings() if(redraw_times || redraw_overlays) { + mwindow->gui->lock_window("PreferencesThread::apply_settings 4"); mwindow->gui->flush(); + mwindow->gui->unlock_window(); } return 0; } @@ -258,16 +295,13 @@ int PreferencesThread::text_to_category(char *category) - - -#define WIDTH 750 -#define HEIGHT 700 - PreferencesWindow::PreferencesWindow(MWindow *mwindow, - PreferencesThread *thread) + PreferencesThread *thread, + int x, + int y) : BC_Window(PROGRAM_NAME ": Preferences", - mwindow->gui->get_root_w() / 2 - WIDTH / 2, - mwindow->gui->get_root_h() / 2 - HEIGHT / 2, + x, + y, WIDTH, HEIGHT, (int)BC_INFINITY, diff --git a/hvirtual/cinelerra/preferencesthread.h b/hvirtual/cinelerra/preferencesthread.h new file mode 100644 index 00000000..9dbdbad2 --- /dev/null +++ b/hvirtual/cinelerra/preferencesthread.h @@ -0,0 +1,114 @@ +#ifndef PREFERENCESTHREAD_H +#define PREFERENCESTHREAD_H + +#include "edl.inc" +#include "guicast.h" +#include "mutex.inc" +#include "mwindow.inc" +#include "preferences.inc" +#include "preferencesthread.inc" +#include "thread.h" + +#define CATEGORIES 5 + +class PreferencesMenuitem : public BC_MenuItem +{ +public: + PreferencesMenuitem(MWindow *mwindow); + ~PreferencesMenuitem(); + + int handle_event(); + + MWindow *mwindow; + PreferencesThread *thread; +}; + +class PreferencesThread : public Thread +{ +public: + PreferencesThread(MWindow *mwindow); + ~PreferencesThread(); + void run(); + + int update_framerate(); + int apply_settings(); + char* category_to_text(int category); + int text_to_category(char *category); + + int current_dialog; + int thread_running; + int redraw_indexes; + int redraw_meters; + int redraw_times; + int redraw_overlays; + int rerender; + int close_assets; + int reload_plugins; + PreferencesWindow *window; + Mutex *window_lock; + MWindow *mwindow; +// Copy of mwindow preferences + Preferences *preferences; + EDL *edl; +}; + +class PreferencesDialog : public BC_SubWindow +{ +public: + PreferencesDialog(MWindow *mwindow, PreferencesWindow *pwindow); + virtual ~PreferencesDialog(); + + virtual int create_objects() { return 0; }; + virtual int draw_framerate() { return 0; }; + PreferencesWindow *pwindow; + MWindow *mwindow; + Preferences *preferences; +}; + +class PreferencesCategory; + +class PreferencesWindow : public BC_Window +{ +public: + PreferencesWindow(MWindow *mwindow, + PreferencesThread *thread, + int x, + int y); + ~PreferencesWindow(); + + int create_objects(); + int delete_current_dialog(); + int set_current_dialog(int number); + int update_framerate(); + + MWindow *mwindow; + PreferencesThread *thread; + ArrayList categories; + PreferencesCategory *category; + +private: + PreferencesDialog *dialog; +}; + +class PreferencesCategory : public BC_PopupTextBox +{ +public: + PreferencesCategory(MWindow *mwindow, PreferencesThread *thread, int x, int y); + ~PreferencesCategory(); + int handle_event(); + MWindow *mwindow; + PreferencesThread *thread; +}; + +class PreferencesApply : public BC_GenericButton +{ +public: + PreferencesApply(MWindow *mwindow, PreferencesThread *thread, int x, int y); + ~PreferencesApply(); + + int handle_event(); + MWindow *mwindow; + PreferencesThread *thread; +}; + +#endif diff --git a/hvirtual/cinelerra/question.C b/hvirtual/cinelerra/question.C index 3ccaacf7..49c6276f 100644 --- a/hvirtual/cinelerra/question.C +++ b/hvirtual/cinelerra/question.C @@ -1,21 +1,17 @@ +#include "language.h" #include "mwindow.h" #include "mwindowgui.h" #include "question.h" #include "theme.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #define WIDTH 375 #define HEIGHT 160 QuestionWindow::QuestionWindow(MWindow *mwindow) : BC_Window(PROGRAM_NAME ": Question", - mwindow->gui->get_abs_cursor_x() - WIDTH / 2, - mwindow->gui->get_abs_cursor_y() - HEIGHT / 2, + mwindow->gui->get_abs_cursor_x(1) - WIDTH / 2, + mwindow->gui->get_abs_cursor_y(1) - HEIGHT / 2, WIDTH, HEIGHT) { diff --git a/hvirtual/cinelerra/quit.C b/hvirtual/cinelerra/quit.C index 7330c194..eff35f6a 100644 --- a/hvirtual/cinelerra/quit.C +++ b/hvirtual/cinelerra/quit.C @@ -59,8 +59,8 @@ void Quit::run() if(mwindow->gui->mainmenu->record->current_state == RECORD_CAPTURING) { ErrorBox error(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error.create_objects(_("Can't quit while a recording is in progress.")); error.run_window(); return; @@ -69,8 +69,8 @@ void Quit::run() if(mwindow->render->running()) { ErrorBox error(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error.create_objects(_("Can't quit while a render is in progress.")); error.run_window(); return; diff --git a/hvirtual/cinelerra/recconfirmdelete.C b/hvirtual/cinelerra/recconfirmdelete.C index 2e748035..a0ffd7e9 100644 --- a/hvirtual/cinelerra/recconfirmdelete.C +++ b/hvirtual/cinelerra/recconfirmdelete.C @@ -11,8 +11,8 @@ RecConfirmDelete::RecConfirmDelete(MWindow *mwindow) : BC_Window(PROGRAM_NAME ": Confirm", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), 320, 100) { } diff --git a/hvirtual/cinelerra/record.C b/hvirtual/cinelerra/record.C index d6e1ce88..800d95b4 100644 --- a/hvirtual/cinelerra/record.C +++ b/hvirtual/cinelerra/record.C @@ -68,15 +68,25 @@ int RecordMenuItem::handle_event() switch(current_state) { case RECORD_INTRO: - thread->record_window->lock_window("RecordMenuItem::handle_event 1"); - thread->record_window->raise_window(); - thread->record_window->unlock_window(); + thread->window_lock->lock("RecordMenuItem::handle_event 1"); + if(thread->record_window) + { + thread->record_window->lock_window("RecordMenuItem::handle_event 1"); + thread->record_window->raise_window(); + thread->record_window->unlock_window(); + } + thread->window_lock->unlock(); break; case RECORD_CAPTURING: - thread->record_gui->lock_window("RecordMenuItem::handle_event 2"); - thread->record_gui->raise_window(); - thread->record_gui->unlock_window(); + thread->window_lock->lock("RecordMenuItem::handle_event 2"); + if(thread->record_gui) + { + thread->record_gui->lock_window("RecordMenuItem::handle_event 2"); + thread->record_gui->raise_window(); + thread->record_gui->unlock_window(); + } + thread->window_lock->unlock(); break; } return 0; @@ -110,16 +120,7 @@ Record::Record(MWindow *mwindow, RecordMenuItem *menu_item) picture = new Picture; channeldb = new ChannelDB; master_channel = new Channel; - -// Initialize 601 to rgb tables -// int _601_to_rgb_value; -// for(int i = 0; i <= 255; i++) -// { -// _601_to_rgb_value = (int)(1.1644 * i - 255 * 0.0627 + 0.5); -// if(_601_to_rgb_value < 0) _601_to_rgb_value = 0; -// if(_601_to_rgb_value > 255) _601_to_rgb_value = 255; -// _601_to_rgb_table[i] = _601_to_rgb_value; -// } + window_lock = new Mutex("Record::window_lock"); } Record::~Record() @@ -127,6 +128,7 @@ Record::~Record() delete picture; delete channeldb; delete master_channel; + delete window_lock; } @@ -301,9 +303,11 @@ void Record::configure_batches() void Record::source_to_text(char *string, Batch *batch) { // Update source + strcpy(string, "Record::source_to_text: not implemented"); switch(mwindow->edl->session->vconfig_in->driver) { case VIDEO4LINUX: + case VIDEO4LINUX2: case CAPTURE_BUZ: case VIDEO4LINUX2JPEG: if(batch->channel < 0 || batch->channel >= channeldb->size()) @@ -368,12 +372,22 @@ void Record::run() // Get information about the file format do { -// Script did not contain "ok" so pop up a window. - record_window = new RecordWindow(mwindow, this); + int x = mwindow->gui->get_root_w(0, 1) / 2 - RECORD_WINDOW_WIDTH / 2; + int y = mwindow->gui->get_root_h(1) / 2 - RECORD_WINDOW_HEIGHT / 2; + + window_lock->lock("Record::run 1"); + record_window = new RecordWindow(mwindow, this, x, y); record_window->create_objects(); + window_lock->unlock(); + + result = record_window->run_window(); + window_lock->lock("Record::run 2"); delete record_window; record_window = 0; + window_lock->unlock(); + + if(!result) { @@ -400,6 +414,7 @@ void Record::run() edl->session->aspect_w = mwindow->edl->session->aspect_w; edl->session->aspect_h = mwindow->edl->session->aspect_h; + window_lock->lock("Record::run 3"); record_gui = new RecordGUI(mwindow, this); record_gui->load_defaults(); record_gui->create_objects(); @@ -426,6 +441,8 @@ void Record::run() start_monitor(); + window_lock->unlock(); + result = record_gui->run_window(); // Force monitor to quit without resuming @@ -434,16 +451,20 @@ void Record::run() else monitor_engine->record_audio->batch_done = 1; - stop_operation(0); + stop_operation(0);; close_output_file(); + window_lock->lock("Record::run 4"); delete record_monitor; + record_monitor = 0; record_gui->save_defaults(); TRACE("Record::run 1"); delete record_gui; + record_gui = 0; + window_lock->unlock(); TRACE("Record::run 2"); delete edl; @@ -755,12 +776,14 @@ void Record::toggle_label() record_gui->update_labels(current_display_position()); } -void Record::get_audio_write_length(int64_t &buffer_size, int64_t &fragment_size) +void Record::get_audio_write_length(int &buffer_size, + int &fragment_size) { fragment_size = 1; while(fragment_size < default_asset->sample_rate / mwindow->edl->session->record_speed) fragment_size *= 2; fragment_size /= 2; + CLAMP(fragment_size, 1024, 32768); for(buffer_size = fragment_size; buffer_size < mwindow->edl->session->record_write_length; @@ -996,8 +1019,9 @@ int Record::open_input_devices(int duplex, int context) if(!audio_opened) { adevice->open_input(mwindow->edl->session->aconfig_in, - default_asset->sample_rate, - get_in_length()); + mwindow->edl->session->vconfig_in, + default_asset->sample_rate, + get_in_length()); } } @@ -1176,12 +1200,15 @@ int Record::set_channel(int channel) char string[BCTEXTLEN]; get_editing_batch()->channel = channel; source_to_text(string, get_editing_batch()); + + record_gui->lock_window("Record::set_channel"); record_gui->batch_source->update(string); record_monitor->window->channel_picker->channel_text->update(string); record_gui->update_batches(); record_gui->unlock_window(); + if(vdevice) { vdevice->set_channel(channeldb->get(channel)); diff --git a/hvirtual/cinelerra/record.h b/hvirtual/cinelerra/record.h index bde594cf..bb9b7889 100644 --- a/hvirtual/cinelerra/record.h +++ b/hvirtual/cinelerra/record.h @@ -62,7 +62,8 @@ public: void close_output_file(); void delete_batch(int number); void swap_batches(int number1, int number2); - void get_audio_write_length(int64_t &buffer_size, int64_t &fragment_size); + void get_audio_write_length(int &buffer_size, + int &fragment_size); int open_input_devices(int duplex, int context); int close_input_devices(); void start_file_threads(); @@ -189,7 +190,7 @@ public: int fill_frames; // Parameters for video monitor EDL *edl; - + Mutex *window_lock; diff --git a/hvirtual/cinelerra/recordaudio.C b/hvirtual/cinelerra/recordaudio.C index 909b00c6..6e0535e8 100644 --- a/hvirtual/cinelerra/recordaudio.C +++ b/hvirtual/cinelerra/recordaudio.C @@ -146,10 +146,15 @@ void RecordAudio::run() { // Read into monitor buffer for monitoring. //printf("RecordAudio::run 1\n"); - grab_result = record->adevice->read_buffer(input, fragment_size, record_channels, over, max, 0); + grab_result = record->adevice->read_buffer(input, + fragment_size, + record_channels, + over, + max, + 0); //printf("RecordAudio::run 2 %d\n", grab_result); } -//printf("RecordAudio::run 3 %d\n", fragment_size); +//printf("RecordAudio::run 3 %d %f\n", fragment_size, max); // Update timer for synchronization timer_lock->lock("RecordAudio::run"); @@ -185,7 +190,9 @@ void RecordAudio::run() record->record_monitor->window->lock_window("RecordAudio::run 1"); for(channel = 0; channel < record_channels; channel++) { - record->record_monitor->window->meters->meters.values[channel]->update(max[channel], over[channel]); + record->record_monitor->window->meters->meters.values[channel]->update( + max[channel], + over[channel]); } record->record_monitor->window->unlock_window(); } @@ -237,8 +244,8 @@ TRACE("RecordAudio::run 4"); if(write_result && !record->default_asset->video_data) { ErrorBox error_box(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error_box.create_objects(_("No space left on disk.")); error_box.run_window(); batch_done = 1; diff --git a/hvirtual/cinelerra/recordaudio.h b/hvirtual/cinelerra/recordaudio.h index 578ed009..66062c94 100644 --- a/hvirtual/cinelerra/recordaudio.h +++ b/hvirtual/cinelerra/recordaudio.h @@ -51,7 +51,8 @@ private: int *over; double **input; RecordGUI *gui; - int64_t buffer_size, fragment_size, fragment_position; + int buffer_size, fragment_size; + int64_t fragment_position; int record_channels; Mutex *timer_lock; Condition *trigger_lock; diff --git a/hvirtual/cinelerra/recordconfig.C b/hvirtual/cinelerra/recordconfig.C index 517aecbf..3a970511 100644 --- a/hvirtual/cinelerra/recordconfig.C +++ b/hvirtual/cinelerra/recordconfig.C @@ -59,29 +59,34 @@ int AudioInConfig::is_duplex(AudioInConfig *in, AudioOutConfig *out) } -AudioInConfig& AudioInConfig::operator=(AudioInConfig &that) +void AudioInConfig::copy_from(AudioInConfig *src) { - driver = that.driver; + driver = src->driver; - firewire_port = that.firewire_port; - firewire_channel = that.firewire_channel; - strcpy(firewire_path, that.firewire_path); + firewire_port = src->firewire_port; + firewire_channel = src->firewire_channel; + strcpy(firewire_path, src->firewire_path); - strcpy(esound_in_server, that.esound_in_server); - esound_in_port = that.esound_in_port; + strcpy(esound_in_server, src->esound_in_server); + esound_in_port = src->esound_in_port; for(int i = 0; i < MAXDEVICES; i++) { - oss_enable[i] = that.oss_enable[i]; - strcpy(oss_in_device[i], that.oss_in_device[i]); - oss_in_channels[i] = that.oss_in_channels[i]; - oss_in_bits = that.oss_in_bits; + oss_enable[i] = src->oss_enable[i]; + strcpy(oss_in_device[i], src->oss_in_device[i]); + oss_in_channels[i] = src->oss_in_channels[i]; + oss_in_bits = src->oss_in_bits; } - strcpy(alsa_in_device, that.alsa_in_device); - alsa_in_bits = that.alsa_in_bits; - alsa_in_channels = that.alsa_in_channels; - in_samplerate = that.in_samplerate; + strcpy(alsa_in_device, src->alsa_in_device); + alsa_in_bits = src->alsa_in_bits; + alsa_in_channels = src->alsa_in_channels; + in_samplerate = src->in_samplerate; +} + +AudioInConfig& AudioInConfig::operator=(AudioInConfig &that) +{ + copy_from(&that); return *this; } @@ -193,22 +198,27 @@ char* VideoInConfig::get_path() return v4l_in_device; } +void VideoInConfig::copy_from(VideoInConfig *src) +{ + driver = src->driver; + strcpy(v4l_in_device, src->v4l_in_device); + strcpy(v4l2_in_device, src->v4l2_in_device); + strcpy(v4l2jpeg_in_device, src->v4l2jpeg_in_device); + strcpy(lml_in_device, src->lml_in_device); + strcpy(buz_in_device, src->buz_in_device); + strcpy(screencapture_display, src->screencapture_display); + firewire_port = src->firewire_port; + firewire_channel = src->firewire_channel; + strcpy(firewire_path, src->firewire_path); + capture_length = src->capture_length; + w = src->w; + h = src->h; + in_framerate = src->in_framerate; +} + VideoInConfig& VideoInConfig::operator=(VideoInConfig &that) { - driver = that.driver; - strcpy(v4l_in_device, that.v4l_in_device); - strcpy(v4l2_in_device, that.v4l2_in_device); - strcpy(v4l2jpeg_in_device, that.v4l2jpeg_in_device); - strcpy(lml_in_device, that.lml_in_device); - strcpy(buz_in_device, that.buz_in_device); - strcpy(screencapture_display, that.screencapture_display); - firewire_port = that.firewire_port; - firewire_channel = that.firewire_channel; - strcpy(firewire_path, that.firewire_path); - capture_length = that.capture_length; - w = that.w; - h = that.h; - in_framerate = that.in_framerate; + copy_from(&that); return *this; } diff --git a/hvirtual/cinelerra/recordconfig.h b/hvirtual/cinelerra/recordconfig.h index 19656c35..ace1141c 100644 --- a/hvirtual/cinelerra/recordconfig.h +++ b/hvirtual/cinelerra/recordconfig.h @@ -13,6 +13,7 @@ public: ~AudioInConfig(); AudioInConfig& operator=(AudioInConfig &that); + void copy_from(AudioInConfig *src); int load_defaults(Defaults *defaults); int save_defaults(Defaults *defaults); @@ -44,6 +45,7 @@ public: ~VideoInConfig(); VideoInConfig& operator=(VideoInConfig &that); + void copy_from(VideoInConfig *src); int load_defaults(Defaults *defaults); int save_defaults(Defaults *defaults); char* get_path(); diff --git a/hvirtual/cinelerra/recordgui.C b/hvirtual/cinelerra/recordgui.C index 1e12c28b..5fd07149 100644 --- a/hvirtual/cinelerra/recordgui.C +++ b/hvirtual/cinelerra/recordgui.C @@ -426,7 +426,8 @@ void RecordGUI::update_batch_sources() { //printf("RecordGUI::update_batch_sources 1\n"); if(record->record_monitor->window->channel_picker) - batch_source->update_list(&record->record_monitor->window->channel_picker->channel_listitems); + batch_source->update_list( + &record->record_monitor->window->channel_picker->channel_listitems); //printf("RecordGUI::update_batch_sources 2\n"); } diff --git a/hvirtual/cinelerra/recordmonitor.C b/hvirtual/cinelerra/recordmonitor.C index a2f37094..01b024d0 100644 --- a/hvirtual/cinelerra/recordmonitor.C +++ b/hvirtual/cinelerra/recordmonitor.C @@ -60,13 +60,13 @@ int RecordMonitor::create_objects() if(record->default_asset->video_data) { // Configure the output for record monitoring - VideoOutConfig config(PLAYBACK_LOCALHOST, 0); + VideoOutConfig config; device = new VideoDevice; // Override default device for X11 drivers - if(mwindow->edl->session->get_playback_config(PLAYBACK_LOCALHOST, 0)->vconfig->driver == + if(mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_XV) config.driver = PLAYBACK_X11_XV; config.x11_use_fields = 0; @@ -333,6 +333,7 @@ printf("RecordMonitorGUI::create_objects %d %d\n", mwindow->theme->rmonitor_tx_x mwindow->theme->rmonitor_meter_y, mwindow->theme->rmonitor_meter_h, record->default_asset->channels, + 1, 1); meters->create_objects(); } diff --git a/hvirtual/cinelerra/recordprefs.C b/hvirtual/cinelerra/recordprefs.C index d11289c2..749622ef 100644 --- a/hvirtual/cinelerra/recordprefs.C +++ b/hvirtual/cinelerra/recordprefs.C @@ -4,16 +4,13 @@ #include "edl.h" #include "edlsession.h" #include "new.h" +#include "language.h" #include "preferences.h" #include "recordconfig.h" #include "recordprefs.h" #include "vdeviceprefs.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) RecordPrefs::RecordPrefs(MWindow *mwindow, PreferencesWindow *pwindow) diff --git a/hvirtual/cinelerra/recordthread.C b/hvirtual/cinelerra/recordthread.C index e9c55f01..91244c6a 100644 --- a/hvirtual/cinelerra/recordthread.C +++ b/hvirtual/cinelerra/recordthread.C @@ -278,8 +278,9 @@ TRACE("RecordThread::run 6"); if(record->default_asset->audio_data && context != CONTEXT_SINGLEFRAME) { - int64_t buffer_size, fragment_size; - record->get_audio_write_length(buffer_size, fragment_size); + int buffer_size, fragment_size; + record->get_audio_write_length(buffer_size, + fragment_size); record->file->start_audio_thread(buffer_size, RING_BUFFERS); } TRACE("RecordThread::run 7"); diff --git a/hvirtual/cinelerra/recordvideo.C b/hvirtual/cinelerra/recordvideo.C index 5d70b65f..97d63084 100644 --- a/hvirtual/cinelerra/recordvideo.C +++ b/hvirtual/cinelerra/recordvideo.C @@ -164,7 +164,6 @@ void RecordVideo::run() trigger_lock->lock("RecordVideo::run"); trigger_lock->unlock(); - while(!batch_done && !write_result) { @@ -176,15 +175,16 @@ void RecordVideo::run() current_sample = record->sync_position(); - if(current_sample < next_sample && current_sample > 0) { // Too early. delay = (int64_t)((float)(next_sample - current_sample) / record->default_asset->sample_rate * - 1000 - ); + 1000); // Sanity check and delay. +// In 2.6.7 this doesn't work. For some reason, probably buffer overflowing, +// it causes the driver to hang up momentarily so we try to only delay +// when really really far ahead. if(delay < 2000 && delay > 0) delayer.delay(delay); gui->update_dropped_frames(0); last_dropped_frames = 0; @@ -204,7 +204,8 @@ void RecordVideo::run() last_dropped_frames = dropped_frames; } -//printf("RecordVideo::run 3\n"); + + // Capture a frame if(!batch_done) { @@ -235,8 +236,7 @@ void RecordVideo::run() else // Brief pause to keep CPU from burning up { - Timer timer; - timer.delay(250); + Timer::delay(250); } } @@ -311,7 +311,7 @@ void RecordVideo::run() } } -TRACE("RecordVideo::run 1"); +//TRACE("RecordVideo::run 1"); // Update dependant threads if(record->default_asset->audio_data) { @@ -319,15 +319,16 @@ TRACE("RecordVideo::run 1"); // Interrupt driver for IEEE1394 record_thread->record_audio->stop_recording(); } -TRACE("RecordVideo::run 2"); + +//TRACE("RecordVideo::run 2"); if(write_result) { if(!record_thread->monitor) { ErrorBox error_box(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error_box.create_objects(_("No space left on disk.")); error_box.run_window(); batch_done = 1; @@ -335,12 +336,11 @@ TRACE("RecordVideo::run 2"); } cleanup_recording(); -TRACE("RecordVideo::run 100"); +//TRACE("RecordVideo::run 100"); } void RecordVideo::read_buffer() { - grab_result = record->vdevice->read_buffer(capture_frame); @@ -357,7 +357,6 @@ void RecordVideo::read_buffer() int64_t field2_offset = mjpeg_get_field2(data, size); capture_frame->set_compressed_size(size); capture_frame->set_field2_offset(field2_offset); -//printf("RecordVideo::read_buffer 1 %d\n", capture_frame->get_field2_offset()); } } } diff --git a/hvirtual/cinelerra/recordwindow.C b/hvirtual/cinelerra/recordwindow.C index b2a988d0..564625a8 100644 --- a/hvirtual/cinelerra/recordwindow.C +++ b/hvirtual/cinelerra/recordwindow.C @@ -1,5 +1,5 @@ #include "formattools.h" -//#include "loadmode.h" +#include "language.h" #include "mwindow.h" #include "mwindowgui.h" #include "record.h" @@ -7,22 +7,16 @@ #include "videodevice.inc" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) -#define WIDTH 410 -#define HEIGHT 360 -RecordWindow::RecordWindow(MWindow *mwindow, Record *record) +RecordWindow::RecordWindow(MWindow *mwindow, Record *record, int x, int y) : BC_Window(PROGRAM_NAME ": Record", - mwindow->gui->get_root_w() / 2 - WIDTH / 2, - mwindow->gui->get_root_h() / 2 - HEIGHT / 2, - WIDTH, - HEIGHT, + x, + y, + RECORD_WINDOW_WIDTH, + RECORD_WINDOW_HEIGHT, (int)BC_INFINITY, (int)BC_INFINITY, 0, diff --git a/hvirtual/cinelerra/recordwindow.h b/hvirtual/cinelerra/recordwindow.h index 2d8d7e25..174425f5 100644 --- a/hvirtual/cinelerra/recordwindow.h +++ b/hvirtual/cinelerra/recordwindow.h @@ -11,11 +11,14 @@ // Dialog for record file format. +#define RECORD_WINDOW_WIDTH 410 +#define RECORD_WINDOW_HEIGHT 360 + class RecordWindow : public BC_Window { public: - RecordWindow(MWindow *mwindow, Record *record); + RecordWindow(MWindow *mwindow, Record *record, int w, int h); ~RecordWindow(); int create_objects(); diff --git a/hvirtual/cinelerra/render.C b/hvirtual/cinelerra/render.C index 15c2c640..8bde7723 100644 --- a/hvirtual/cinelerra/render.C +++ b/hvirtual/cinelerra/render.C @@ -144,7 +144,7 @@ void MainPackageRenderer::set_result(int value) void MainPackageRenderer::set_progress(int64_t value) { - render->counter_lock->lock(); + render->counter_lock->lock("MainPackageRenderer::set_progress"); render->total_rendered += value; // If non interactive, print progress out @@ -201,7 +201,7 @@ int MainPackageRenderer::progress_cancelled() Render::Render(MWindow *mwindow) - : Thread() + : Thread(0, 0, 0) { this->mwindow = mwindow; if(mwindow) plugindb = mwindow->plugindb; @@ -237,8 +237,8 @@ void Render::start_interactive() else { ErrorBox error_box(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error_box.create_objects("Already rendering"); error_box.run_window(); } @@ -257,8 +257,8 @@ void Render::start_batches(ArrayList *jobs) else { ErrorBox error_box(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error_box.create_objects("Already rendering"); error_box.run_window(); } @@ -307,24 +307,27 @@ void Render::run() check_asset(mwindow->edl, *asset); // Get format from user - do + if(!result) { - format_error = 0; - result = 0; - + do { - RenderWindow window(mwindow, this, asset); - window.create_objects(); - result = window.run_window(); - } + format_error = 0; + result = 0; - if(!result) - { + { + RenderWindow window(mwindow, this, asset); + window.create_objects(); + result = window.run_window(); + } + + if(!result) + { // Check the asset format for errors. - FormatCheck format_check(asset); - format_error = format_check.check_format(); - } - }while(format_error && !result); + FormatCheck format_check(asset); + format_error = format_check.check_format(); + } + }while(format_error && !result); + } save_defaults(asset); mwindow->save_defaults(); @@ -428,7 +431,13 @@ int Render::check_asset(EDL *edl, Asset &asset) asset.audio_data = 0; asset.channels = 0; } -//printf("Render::check_asset 3\n"); + + if(!asset.audio_data && + !asset.video_data) + { + return 1; + } + return 0; } int Render::fix_strategy(int strategy, int use_renderfarm) @@ -550,8 +559,8 @@ int Render::render(int test_overwrite, // Configure preview monitor - VideoOutConfig vconfig(PLAYBACK_LOCALHOST, 0); - PlaybackConfig *playback_config = new PlaybackConfig(PLAYBACK_LOCALHOST, 0); + VideoOutConfig vconfig; + PlaybackConfig *playback_config = new PlaybackConfig; for(int i = 0; i < MAX_CHANNELS; i++) { vconfig.do_channel[i] = (i < command->get_edl()->session->video_channels); @@ -566,8 +575,8 @@ int Render::render(int test_overwrite, default_asset->frame_rate = command->get_edl()->session->frame_rate; default_asset->sample_rate = command->get_edl()->session->sample_rate; -// Conform asset to EDL. - check_asset(command->get_edl(), *default_asset); +// Conform asset to EDL. Find out if any tracks are playable. + result = check_asset(command->get_edl(), *default_asset); if(!result) { @@ -679,7 +688,7 @@ int Render::render(int test_overwrite, MainPackageRenderer package_renderer(this); - package_renderer.initialize(mwindow, + result = package_renderer.initialize(mwindow, command->get_edl(), // Copy of master EDL preferences, default_asset, @@ -752,8 +761,8 @@ int Render::render(int test_overwrite, if(mwindow) { ErrorBox error_box(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error_box.create_objects(_("Error rendering data.")); error_box.run_window(); } @@ -962,8 +971,8 @@ int Render::save_defaults(Asset *asset) RenderWindow::RenderWindow(MWindow *mwindow, Render *render, Asset *asset) : BC_Window(PROGRAM_NAME ": Render", - mwindow->gui->get_root_w() / 2 - WIDTH / 2, - mwindow->gui->get_root_h() / 2 - HEIGHT / 2, + mwindow->gui->get_root_w(0, 1) / 2 - WIDTH / 2, + mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2, WIDTH, HEIGHT, (int)BC_INFINITY, diff --git a/hvirtual/cinelerra/renderengine.C b/hvirtual/cinelerra/renderengine.C index 010defdf..a73f73c8 100644 --- a/hvirtual/cinelerra/renderengine.C +++ b/hvirtual/cinelerra/renderengine.C @@ -26,18 +26,16 @@ RenderEngine::RenderEngine(PlaybackEngine *playback_engine, TransportCommand *command, Canvas *output, ArrayList *plugindb, - ChannelDB *channeldb, - int head_number) + ChannelDB *channeldb) : Thread(1, 0, 0) { this->playback_engine = playback_engine; this->output = output; this->plugindb = plugindb; this->channeldb = channeldb; - this->head_number = head_number; audio = 0; video = 0; - config = new PlaybackConfig(PLAYBACK_LOCALHOST, 0); + config = new PlaybackConfig; arender = 0; vrender = 0; do_audio = 0; @@ -95,7 +93,7 @@ int RenderEngine::arm_command(TransportCommand *command, input_lock->lock("RenderEngine::arm_command"); - *this->command = *command; + this->command->copy_from(command); // Fix background rendering asset to use current dimensions and ignore // headers. @@ -110,8 +108,7 @@ int RenderEngine::arm_command(TransportCommand *command, interrupted = 0; // Retool configuration for this node - int playback_strategy = command->get_edl()->session->playback_strategy; - *this->config = *command->get_edl()->session->get_playback_config(playback_strategy, head_number); + this->config->copy_from(command->get_edl()->session->playback_config); VideoOutConfig *vconfig = this->config->vconfig; AudioOutConfig *aconfig = this->config->aconfig; if(command->realtime) @@ -170,10 +167,7 @@ Workarounds::clamp(vconfig->do_channel[i], 0, 1); } else { - this->config->playback_strategy = PLAYBACK_LOCALHOST; vconfig->driver = PLAYBACK_X11; - vconfig->playback_strategy = PLAYBACK_LOCALHOST; - aconfig->playback_strategy = PLAYBACK_LOCALHOST; for(int i = 0; i < MAX_CHANNELS; i++) { vconfig->do_channel[i] = (i < command->get_edl()->session->video_channels); @@ -255,12 +249,12 @@ void RenderEngine::create_render_threads() int RenderEngine::get_output_w() { - return edl->calculate_output_w(config->playback_strategy != PLAYBACK_LOCALHOST); + return edl->calculate_output_w(1); } int RenderEngine::get_output_h() { - return edl->calculate_output_h(config->playback_strategy != PLAYBACK_LOCALHOST); + return edl->calculate_output_h(1); } int RenderEngine::brender_available(int position, int direction) @@ -412,29 +406,19 @@ void RenderEngine::reset_sync_position() int64_t RenderEngine::sync_position() { - switch(edl->session->playback_strategy) - { - case PLAYBACK_LOCALHOST: - case PLAYBACK_MULTIHEAD: - // Use audio device // No danger of race conditions because the output devices are closed after all // threads join. - if(do_audio) - { - return audio->current_position(); - } - - if(do_video) - { - int64_t result = timer.get_scaled_difference( - edl->session->sample_rate); - return result; - } - break; + if(do_audio) + { + return audio->current_position(); + } - case PLAYBACK_BLONDSYMPHONY: - break; + if(do_video) + { + int64_t result = timer.get_scaled_difference( + edl->session->sample_rate); + return result; } } @@ -454,7 +438,6 @@ PluginServer* RenderEngine::scan_plugindb(char *title, int RenderEngine::start_command() { -//printf("RenderEngine::start_command 1 %d\n", command->realtime); if(command->realtime) { interrupt_lock->lock("RenderEngine::start_command"); @@ -462,14 +445,12 @@ int RenderEngine::start_command() Thread::start(); start_lock->lock("RenderEngine::start_command 2"); start_lock->unlock(); -//printf("RenderEngine::start_command 2 %p %d\n", this, Thread::get_tid()); } return 0; } void RenderEngine::arm_render_threads() { -//printf("RenderEngine::arm_render_threads 1 %d %d\n", do_audio, do_video); if(do_audio) { arender->arm_command(); @@ -477,9 +458,7 @@ void RenderEngine::arm_render_threads() if(do_video) { -//printf("RenderEngine::arm_render_threads 1 %d %d\n", do_audio, do_video); vrender->arm_command(); -//printf("RenderEngine::arm_render_threads 2 %d %d\n", do_audio, do_video); } } @@ -520,14 +499,11 @@ void RenderEngine::wait_render_threads() void RenderEngine::interrupt_playback() { -//printf("RenderEngine::interrupt_playback 0 %p\n", this); interrupt_lock->lock("RenderEngine::interrupt_playback"); interrupted = 1; if(audio) { -//printf("RenderEngine::interrupt_playback 1 %p\n", this); audio->interrupt_playback(); -//printf("RenderEngine::interrupt_playback 2 %p\n", this); } if(video) { @@ -598,7 +574,6 @@ void RenderEngine::get_module_levels(ArrayList *module_levels, int64_t p void RenderEngine::run() { -//printf("RenderEngine::run 1 %p\n", this); start_render_threads(); start_lock->unlock(); interrupt_lock->unlock(); @@ -651,7 +626,6 @@ void RenderEngine::run() input_lock->unlock(); interrupt_lock->unlock(); -//printf("RenderEngine::run 100 %p\n", this); } diff --git a/hvirtual/cinelerra/renderengine.h b/hvirtual/cinelerra/renderengine.h index 223d1688..4614b894 100644 --- a/hvirtual/cinelerra/renderengine.h +++ b/hvirtual/cinelerra/renderengine.h @@ -29,8 +29,7 @@ public: TransportCommand *command, Canvas *output, ArrayList *plugindb, - ChannelDB *channeldb, - int head_number); + ChannelDB *channeldb); ~RenderEngine(); int total_playable_channels(); @@ -79,7 +78,6 @@ public: // Update preferences window void update_framerate(float framerate); - int head_number; // Copy of command TransportCommand *command; // EDL to be used by renderengine since not all commands involve an EDL change diff --git a/hvirtual/cinelerra/renderfarm.C b/hvirtual/cinelerra/renderfarm.C index bcfc029e..e1a2f258 100644 --- a/hvirtual/cinelerra/renderfarm.C +++ b/hvirtual/cinelerra/renderfarm.C @@ -53,7 +53,7 @@ RenderFarmServer::RenderFarmServer(ArrayList *plugindb, this->default_asset = default_asset; this->edl = edl; this->brender = brender; - client_lock = new Mutex; + client_lock = new Mutex("RenderFarmServer::client_lock"); } RenderFarmServer::~RenderFarmServer() @@ -69,7 +69,7 @@ int RenderFarmServer::start_clients() for(int i = 0; i < preferences->get_enabled_nodes() && !result; i++) { - client_lock->lock(); + client_lock->lock("RenderFarmServer::start_clients"); RenderFarmServerThread *client = new RenderFarmServerThread(plugindb, this, i); diff --git a/hvirtual/cinelerra/renderfarmclient.C b/hvirtual/cinelerra/renderfarmclient.C index 9af729bc..6e63d635 100644 --- a/hvirtual/cinelerra/renderfarmclient.C +++ b/hvirtual/cinelerra/renderfarmclient.C @@ -208,7 +208,7 @@ RenderFarmClientThread::RenderFarmClientThread(RenderFarmClient *client) frames_per_second = 0; Thread::set_synchronous(0); fs_client = 0; - mutex_lock = new Mutex; + mutex_lock = new Mutex("RenderFarmClientThread::mutex_lock"); } RenderFarmClientThread::~RenderFarmClientThread() @@ -250,10 +250,10 @@ int RenderFarmClientThread::read_socket(char *data, int len, int timeout) timeout); } -void RenderFarmClientThread::lock() +void RenderFarmClientThread::lock(char *location) { //printf("RenderFarmClientThread::lock 1 %p %p\n", this, mutex_lock); - mutex_lock->lock(); + mutex_lock->lock(location); } void RenderFarmClientThread::unlock() @@ -599,7 +599,7 @@ FarmPackageRenderer::~FarmPackageRenderer() int FarmPackageRenderer::get_result() { - thread->lock(); + thread->lock("FarmPackageRenderer::get_result"); thread->send_request_header(RENDERFARM_GET_RESULT, 0); unsigned char data[1]; @@ -615,7 +615,7 @@ int FarmPackageRenderer::get_result() void FarmPackageRenderer::set_result(int value) { - thread->lock(); + thread->lock("FarmPackageRenderer::set_result"); thread->send_request_header(RENDERFARM_SET_RESULT, 1); unsigned char data[1]; @@ -626,7 +626,7 @@ void FarmPackageRenderer::set_result(int value) void FarmPackageRenderer::set_progress(int64_t total_samples) { - thread->lock(); + thread->lock("FarmPackageRenderer::set_progress"); thread->send_request_header(RENDERFARM_PROGRESS, 4); unsigned char datagram[4]; @@ -638,7 +638,7 @@ void FarmPackageRenderer::set_progress(int64_t total_samples) void FarmPackageRenderer::set_video_map(int64_t position, int value) { - thread->lock(); + thread->lock("FarmPackageRenderer::set_video_map"); thread->send_request_header(RENDERFARM_SET_VMAP, 8); unsigned char datagram[8]; diff --git a/hvirtual/cinelerra/renderfarmclient.h b/hvirtual/cinelerra/renderfarmclient.h index 98c8acb1..535d9c0f 100644 --- a/hvirtual/cinelerra/renderfarmclient.h +++ b/hvirtual/cinelerra/renderfarmclient.h @@ -62,7 +62,7 @@ public: int write_socket(char *data, int len, int timeout); int read_socket(char *data, int len, int timeout); void read_string(int socket_fd, char* &string); - void lock(); + void lock(char *location); void unlock(); diff --git a/hvirtual/cinelerra/resizetrackthread.C b/hvirtual/cinelerra/resizetrackthread.C index 8b23287b..0c64ca2e 100644 --- a/hvirtual/cinelerra/resizetrackthread.C +++ b/hvirtual/cinelerra/resizetrackthread.C @@ -1,4 +1,5 @@ #include "edl.h" +#include "language.h" #include "mainundo.h" #include "mwindow.h" #include "mwindowgui.h" @@ -8,11 +9,6 @@ #include "tracks.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -52,8 +48,8 @@ void ResizeTrackThread::run() ResizeTrackWindow *window = this->window = new ResizeTrackWindow(mwindow, this, - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); window->create_objects(); int result = window->run_window(); this->window = 0; diff --git a/hvirtual/cinelerra/resourcepixmap.C b/hvirtual/cinelerra/resourcepixmap.C index 2dac6702..164cf4e6 100644 --- a/hvirtual/cinelerra/resourcepixmap.C +++ b/hvirtual/cinelerra/resourcepixmap.C @@ -742,6 +742,7 @@ void ResourcePixmap::draw_video_resource(Edit *edit, // Try displaying from source cache FrameCache *frame_cache = source->get_frame_cache(); VFrame *picon_frame = 0; + int use_cache = 0; //frame_cache->dump(); if((picon_frame = frame_cache->get_frame_ptr(source_frame, @@ -750,7 +751,7 @@ void ResourcePixmap::draw_video_resource(Edit *edit, picon_w, picon_h)) != 0) { - ; + use_cache = 1; } else // Display from file and put in cache @@ -808,7 +809,8 @@ void ResourcePixmap::draw_video_resource(Edit *edit, 0, 0); - + if(use_cache) + frame_cache->unlock(); if(frames_per_picon > 1) { diff --git a/hvirtual/cinelerra/savefile.C b/hvirtual/cinelerra/savefile.C index 95fefb1b..35d24a43 100644 --- a/hvirtual/cinelerra/savefile.C +++ b/hvirtual/cinelerra/savefile.C @@ -84,8 +84,8 @@ int Save::handle_event() char string2[256]; sprintf(string2, _("Couldn't open %s"), mwindow->session->filename); ErrorBox error(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error.create_objects(string2); error.run_window(); return 1; @@ -183,8 +183,8 @@ void SaveAs::run() mwindow->set_filename(""); // update the project name sprintf(string2, _("Couldn't open %s."), filename); ErrorBox error(PROGRAM_NAME ": Error", - mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y()); + mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1)); error.create_objects(string2); error.run_window(); return; @@ -213,8 +213,8 @@ void SaveAs::run() SaveFileWindow::SaveFileWindow(MWindow *mwindow, char *init_directory) - : BC_FileBox(mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y() - BC_WindowBase::get_resources()->filebox_h / 2, + : BC_FileBox(mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1) - BC_WindowBase::get_resources()->filebox_h / 2, init_directory, PROGRAM_NAME ": Save", _("Enter a filename to save as")) diff --git a/hvirtual/cinelerra/setformat.C b/hvirtual/cinelerra/setformat.C index 55fcb49c..7cc4185b 100644 --- a/hvirtual/cinelerra/setformat.C +++ b/hvirtual/cinelerra/setformat.C @@ -5,6 +5,7 @@ #include "defaults.h" #include "edl.h" #include "edlsession.h" +#include "formatpresets.h" #include "language.h" #include "levelwindow.h" #include "levelwindowgui.h" @@ -39,9 +40,16 @@ int SetFormat::handle_event() } else { - thread->window_lock->lock(); - if(thread->window) thread->window->raise_window(); - thread->window_lock->unlock(); +// window_lock has to be locked but window can't be locked until after +// it is known to exist, so we neglect window_lock for now + if(thread->window) + { + thread->window_lock->lock("SetFormat::handle_event"); + thread->window->lock_window("SetFormat::handle_event"); + thread->window->raise_window(); + thread->window->unlock_window(); + thread->window_lock->unlock(); + } } return 1; } @@ -50,7 +58,7 @@ SetFormatThread::SetFormatThread(MWindow *mwindow) : Thread() { this->mwindow = mwindow; - window_lock = new Mutex; + window_lock = new Mutex("SetFormatThread::window_lock"); window = 0; } @@ -66,15 +74,19 @@ void SetFormatThread::run() new_settings->create_objects(); new_settings->copy_session(mwindow->edl); - window_lock->lock(); - window = new SetFormatWindow(mwindow, this); +// This locks mwindow, so it must be done outside window_lock + int x = mwindow->gui->get_abs_cursor_x(1) - mwindow->theme->setformat_w / 2; + int y = mwindow->gui->get_abs_cursor_y(1) - mwindow->theme->setformat_h / 2; + + window_lock->lock("SetFormatThread::run 1"); + window = new SetFormatWindow(mwindow, this, x, y); window->create_objects(); window_lock->unlock(); int result = window->run_window(); - window_lock->lock(); + window_lock->lock("SetFormatThread::run 2"); delete window; window = 0; window_lock->unlock(); @@ -83,9 +95,8 @@ void SetFormatThread::run() if(!result) { apply_changes(); - } - + mwindow->defaults->update("AUTOASPECT", auto_aspect); delete new_settings; } @@ -145,6 +156,32 @@ void SetFormatThread::apply_changes() mwindow->sync_parameters(CHANGE_ALL); } +void SetFormatThread::update() +{ + window->sample_rate->update(new_settings->session->sample_rate); + window->channels->update((int64_t)new_settings->session->audio_channels); + window->frame_rate->update((float)new_settings->session->frame_rate); + + auto_aspect = 0; + window->auto_aspect->update(0); + + constrain_ratio = 0; + dimension[0] = new_settings->session->output_w; + window->dimension[0]->update((int64_t)dimension[0]); + dimension[1] = new_settings->session->output_h; + window->dimension[1]->update((int64_t)dimension[1]); + + ratio[0] = (float)dimension[0] / orig_dimension[0]; + window->ratio[0]->update(ratio[0]); + ratio[1] = (float)dimension[1] / orig_dimension[1]; + window->ratio[1]->update(ratio[1]); + + window->aspect_w->update(new_settings->session->aspect_w); + window->aspect_h->update(new_settings->session->aspect_h); + + window->canvas->draw(); +} + void SetFormatThread::update_window() { int i, result, modified_item, dimension_modified = 0, ratio_modified = 0; @@ -206,7 +243,7 @@ void SetFormatThread::update_aspect() { if(auto_aspect) { - char string[1024]; + char string[BCTEXTLEN]; MWindow::create_aspect_ratio(new_settings->session->aspect_w, new_settings->session->aspect_h, dimension[0], @@ -226,15 +263,18 @@ void SetFormatThread::update_aspect() -SetFormatWindow::SetFormatWindow(MWindow *mwindow, SetFormatThread *thread) +SetFormatWindow::SetFormatWindow(MWindow *mwindow, + SetFormatThread *thread, + int x, + int y) : BC_Window(PROGRAM_NAME ": Set Format", - mwindow->gui->get_abs_cursor_x() - mwindow->theme->setformat_w / 2, - mwindow->gui->get_abs_cursor_y() - mwindow->theme->setformat_h / 2, + x, + y, mwindow->theme->setformat_w, mwindow->theme->setformat_h, -1, -1, - 1, + 0, 0, 1) { @@ -244,15 +284,27 @@ SetFormatWindow::SetFormatWindow(MWindow *mwindow, SetFormatThread *thread) void SetFormatWindow::create_objects() { - int x, y = mwindow->theme->setformat_y1; - BC_TextBox *textbox; + int x = 10, y = mwindow->theme->setformat_y1; mwindow->theme->draw_setformat_bg(this); + + + + presets = new SetFormatPresets(mwindow, + this, + x, + y); + presets->create_objects(); + x = presets->x; + y = presets->y; + + y = mwindow->theme->setformat_y2; + add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y, _("Audio"), LARGEFONT)); - y += mwindow->theme->setformat_margin; + y = mwindow->theme->setformat_y3; add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y, _("Samplerate:"))); @@ -261,25 +313,25 @@ void SetFormatWindow::create_objects() add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y, _("Samplerate:"))); - add_subwindow(textbox = new SetSampleRateTextBox(thread, + add_subwindow(sample_rate = new SetSampleRateTextBox(thread, mwindow->theme->setformat_x2, y)); add_subwindow(new SampleRatePulldown(mwindow, - textbox, - mwindow->theme->setformat_x2 + textbox->get_w(), + sample_rate, + mwindow->theme->setformat_x2 + sample_rate->get_w(), y)); y += mwindow->theme->setformat_margin; add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y, _("Channels:"))); - add_subwindow(textbox = new SetChannelsTextBox(thread, + add_subwindow(channels = new SetChannelsTextBox(thread, mwindow->theme->setformat_x2, y)); - add_subwindow(new BC_ITumbler(textbox, + add_subwindow(new BC_ITumbler(channels, 1, MAXCHANNELS, - mwindow->theme->setformat_x2 + textbox->get_w(), + mwindow->theme->setformat_x2 + channels->get_w(), y)); y += mwindow->theme->setformat_margin; @@ -303,22 +355,22 @@ void SetFormatWindow::create_objects() - y = mwindow->theme->setformat_y1; + y = mwindow->theme->setformat_y2; add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Video"), LARGEFONT)); - y += mwindow->theme->setformat_margin; + y = mwindow->theme->setformat_y3; add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Frame rate:"))); - add_subwindow(textbox = new SetFrameRateTextBox(thread, + add_subwindow(frame_rate = new SetFrameRateTextBox(thread, mwindow->theme->setformat_x4, y)); add_subwindow(new FrameRatePulldown(mwindow, - textbox, - mwindow->theme->setformat_x4 + textbox->get_w(), + frame_rate, + mwindow->theme->setformat_x4 + frame_rate->get_w(), y)); y += mwindow->theme->setformat_margin; @@ -368,14 +420,14 @@ void SetFormatWindow::create_objects() y, _("Color model:"))); x = mwindow->theme->setformat_x4; - add_subwindow(textbox = new BC_TextBox(x, + add_subwindow(color_model = new BC_TextBox(x, y, 100, 1, "")); - x += textbox->get_w(); + x += color_model->get_w(); add_subwindow(new ColormodelPulldown(mwindow, - textbox, + color_model, &thread->new_settings->session->color_model, x, y)); @@ -404,7 +456,7 @@ void SetFormatWindow::create_objects() x, y)); x += 30; - add_subwindow(new ScaleAspectAuto(x, y, thread)); + add_subwindow(auto_aspect = new ScaleAspectAuto(x, y, thread)); @@ -419,6 +471,53 @@ void SetFormatWindow::create_objects() show_window(); } +char* SetFormatWindow::get_preset_text() +{ + return ""; +} + + + + + + + + + + + + + + + +SetFormatPresets::SetFormatPresets(MWindow *mwindow, + SetFormatWindow *gui, + int x, + int y) + : FormatPresets(mwindow, 0, gui, x, y) +{ + +} + +SetFormatPresets::~SetFormatPresets() +{ +} + +int SetFormatPresets::handle_event() +{ + format_gui->thread->update(); + return 1; +} + +EDL* SetFormatPresets::get_edl() +{ + return format_gui->thread->new_settings; +} + + + + + @@ -464,22 +563,17 @@ SetChannelsCanvas::SetChannelsCanvas(MWindow *mwindow, w, h) { -//printf("SetChannelsCanvas::SetChannelsCanvas 1\n"); this->thread = thread; this->mwindow = mwindow; active_channel = -1; -//printf("SetChannelsCanvas::SetChannelsCanvas 1\n"); box_r = mwindow->theme->channel_position_data->get_w() / 2; -//printf("SetChannelsCanvas::SetChannelsCanvas 1\n"); temp_picon = new VFrame(0, mwindow->theme->channel_position_data->get_w(), mwindow->theme->channel_position_data->get_h(), mwindow->theme->channel_position_data->get_color_model()); -//printf("SetChannelsCanvas::SetChannelsCanvas 1\n"); rotater = new RotateFrame(mwindow->preferences->processors, mwindow->theme->channel_position_data->get_w(), mwindow->theme->channel_position_data->get_h()); -//printf("SetChannelsCanvas::SetChannelsCanvas 2\n"); } SetChannelsCanvas::~SetChannelsCanvas() { @@ -506,7 +600,6 @@ int SetChannelsCanvas::draw(int angle) set_color(mwindow->theme->channel_position_color); for(int i = 0; i < thread->new_settings->session->audio_channels; i++) { -//printf("SetChannelsCanvas::draw %d\n", thread->new_settings->session->achannel_positions[i]); get_dimensions(thread->new_settings->session->achannel_positions[i], x, y, @@ -606,9 +699,11 @@ int SetChannelsCanvas::cursor_motion_event() int new_d; new_d = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2); new_d += 90; - if(new_d >= 360) new_d -= 360; new_d -= degree_offset; - if(new_d < 0) new_d += 360; + + while(new_d >= 360) new_d -= 360; + while(new_d < 0) new_d += 360; + if(thread->new_settings->session->achannel_positions[active_channel] != new_d) { thread->new_settings->session->achannel_positions[active_channel] = new_d; @@ -677,14 +772,18 @@ int ScaleSizeText::handle_event() -ScaleRatioText::ScaleRatioText(int x, int y, SetFormatThread *thread, float *output) +ScaleRatioText::ScaleRatioText(int x, + int y, + SetFormatThread *thread, + float *output) : BC_TextBox(x, y, 100, 1, *output) { this->thread = thread; this->output = output; } ScaleRatioText::~ScaleRatioText() -{} +{ +} int ScaleRatioText::handle_event() { *output = atof(get_text()); diff --git a/hvirtual/cinelerra/setformat.h b/hvirtual/cinelerra/setformat.h new file mode 100644 index 00000000..87d67a9d --- /dev/null +++ b/hvirtual/cinelerra/setformat.h @@ -0,0 +1,208 @@ +#ifndef SETFORMAT_H +#define SETFORMAT_H + + +#include "edl.inc" +#include "formatpresets.h" +#include "guicast.h" +#include "mutex.inc" +#include "mwindow.inc" +#include "setformat.inc" +#include "thread.h" + + +class SetFormatPresets; + + + +class SetFormat : public BC_MenuItem +{ +public: + SetFormat(MWindow *mwindow); + int handle_event(); + SetFormatThread *thread; + MWindow *mwindow; +}; + + +class SetFormatThread : public Thread +{ +public: + SetFormatThread(MWindow *mwindow); + + void run(); + + void apply_changes(); +// Update image size based on ratio of dimensions to original. + void update_window(); +// Update automatic aspect ratio based in image size + void update_aspect(); +// Update all parameters from preset menu + void update(); + + + Mutex *window_lock; + SetFormatWindow *window; + MWindow *mwindow; + EDL *new_settings; + float ratio[2]; + int dimension[2]; + int orig_dimension[2]; + int auto_aspect; + int constrain_ratio; +}; + + +class SetSampleRateTextBox : public BC_TextBox +{ +public: + SetSampleRateTextBox(SetFormatThread *thread, int x, int y); + int handle_event(); + SetFormatThread *thread; +}; + +class SetChannelsTextBox : public BC_TextBox +{ +public: + SetChannelsTextBox(SetFormatThread *thread, int x, int y); + + int handle_event(); + + SetFormatThread *thread; + MWindow *mwindow; +}; + + +class SetChannelsCanvas : public BC_SubWindow +{ +public: + SetChannelsCanvas(MWindow *mwindow, + SetFormatThread *thread, + int x, + int y, + int w, + int h); + ~SetChannelsCanvas(); + + int draw(int angle = -1); + int get_dimensions(int channel_position, int &x, int &y, int &w, int &h); + int button_press_event(); + int button_release_event(); + int cursor_motion_event(); + +private: + int active_channel; // for selection + int degree_offset; + int box_r; + + int poltoxy(int &x, int &y, int r, int d); + int xytopol(int &d, int x, int y); + MWindow *mwindow; + SetFormatThread *thread; + VFrame *temp_picon; + RotateFrame *rotater; +}; + + +class SetFrameRateTextBox : public BC_TextBox +{ +public: + SetFrameRateTextBox(SetFormatThread *thread, int x, int y); + int handle_event(); + SetFormatThread *thread; +}; + +class ScaleSizeText : public BC_TextBox +{ +public: + ScaleSizeText(int x, int y, SetFormatThread *thread, int *output); + ~ScaleSizeText(); + int handle_event(); + SetFormatThread *thread; + int *output; +}; + + +class ScaleRatioText : public BC_TextBox +{ +public: + ScaleRatioText(int x, int y, SetFormatThread *thread, float *output); + ~ScaleRatioText(); + int handle_event(); + SetFormatThread *thread; + float *output; +}; + +class ScaleAspectAuto : public BC_CheckBox +{ +public: + ScaleAspectAuto(int x, int y, SetFormatThread *thread); + ~ScaleAspectAuto(); + int handle_event(); + SetFormatThread *thread; +}; + +class ScaleAspectText : public BC_TextBox +{ +public: + ScaleAspectText(int x, int y, SetFormatThread *thread, float *output); + ~ScaleAspectText(); + int handle_event(); + SetFormatThread *thread; + float *output; +}; + +class SetFormatApply : public BC_GenericButton +{ +public: + SetFormatApply(int x, int y, SetFormatThread *thread); + int handle_event(); + SetFormatThread *thread; +}; + +class SetFormatPresets : public FormatPresets +{ +public: + SetFormatPresets(MWindow *mwindow, SetFormatWindow *gui, int x, int y); + ~SetFormatPresets(); + int handle_event(); + EDL* get_edl(); +}; + +class SetFormatWindow : public BC_Window +{ +public: + SetFormatWindow(MWindow *mwindow, + SetFormatThread *thread, + int x, + int y); + + void create_objects(); + char* get_preset_text(); + + MWindow *mwindow; + SetFormatThread *thread; + SetChannelsCanvas *canvas; +// Screen size width, height + ScaleSizeText* dimension[2]; +// Size ratio width, height + ScaleRatioText* ratio[2]; +// Aspect ratio + ScaleAspectText *aspect_w; + ScaleAspectText *aspect_h; + SetSampleRateTextBox *sample_rate; + SetChannelsTextBox *channels; + SetFrameRateTextBox *frame_rate; + BC_TextBox *color_model; + SetFormatPresets *presets; + ScaleAspectAuto *auto_aspect; +}; + + + + + + + + +#endif diff --git a/hvirtual/cinelerra/theme.C b/hvirtual/cinelerra/theme.C index 34c07218..c3241d5e 100644 --- a/hvirtual/cinelerra/theme.C +++ b/hvirtual/cinelerra/theme.C @@ -97,9 +97,11 @@ void Theme::flush_images() void Theme::initialize() { -// Force to use executable for images - unset_path(); +// Force to use local data for images + extern unsigned char _binary_theme_data_start[]; + set_data(_binary_theme_data_start); +// Set images which weren't set by subclass new_image("mode_add", "mode_add.png"); new_image("mode_divide", "mode_divide.png"); new_image("mode_multiply", "mode_multiply.png"); diff --git a/hvirtual/cinelerra/theme.h b/hvirtual/cinelerra/theme.h index 212d3c12..c14e3ba4 100644 --- a/hvirtual/cinelerra/theme.h +++ b/hvirtual/cinelerra/theme.h @@ -192,7 +192,9 @@ public: int batchrender_x1, batchrender_x2, batchrender_x3; - int setformat_x1, setformat_x2, setformat_x3, setformat_x4, setformat_y1, setformat_w, setformat_h, setformat_margin; + int setformat_x1, setformat_x2, setformat_x3, setformat_x4; + int setformat_y1, setformat_y2, setformat_y3; + int setformat_w, setformat_h, setformat_margin; int setformat_channels_x, setformat_channels_y, setformat_channels_w, setformat_channels_h; int title_h; int title_font, title_color; diff --git a/hvirtual/cinelerra/threadindexer.C b/hvirtual/cinelerra/threadindexer.C index 5440ec49..870c32ac 100644 --- a/hvirtual/cinelerra/threadindexer.C +++ b/hvirtual/cinelerra/threadindexer.C @@ -110,8 +110,8 @@ void ThreadIndexer::run() // try to create now if(!progress) { - progress = new BC_ProgressBox(mwindow->gui->get_abs_cursor_x(), - mwindow->gui->get_abs_cursor_y(), + progress = new BC_ProgressBox(mwindow->gui->get_abs_cursor_x(1), + mwindow->gui->get_abs_cursor_y(1), _("Building Indexes..."), 1); progress->start(); diff --git a/hvirtual/cinelerra/timebar.C b/hvirtual/cinelerra/timebar.C index 78f34c5b..29ee3c8e 100644 --- a/hvirtual/cinelerra/timebar.C +++ b/hvirtual/cinelerra/timebar.C @@ -385,18 +385,12 @@ void TimeBar::update_presentations() void TimeBar::update(int do_range, int do_others) { -//printf("TimeBar::update 1\n"); draw_time(); -//printf("TimeBar::update 1\n"); // Need to redo these when range is drawn to get the background updated. update_labels(); -//printf("TimeBar::update 1\n"); update_points(); -//printf("TimeBar::update 1\n"); update_presentations(); -//printf("TimeBar::update 1\n"); flash(); -//printf("TimeBar::update 10\n"); } diff --git a/hvirtual/cinelerra/track.C b/hvirtual/cinelerra/track.C index 9af26e11..6be67d8a 100644 --- a/hvirtual/cinelerra/track.C +++ b/hvirtual/cinelerra/track.C @@ -962,7 +962,6 @@ int Track::copy(double start, FileXML *file, char *output_path) { -//printf("Track::copy 1\n"); // Use a copy of the selection in converted units // So copy_automation doesn't reconvert. int64_t start_unit = to_units(start, 0); @@ -972,12 +971,10 @@ int Track::copy(double start, file->tag.set_title("TRACK"); -// file->tag.set_property("PLAY", play); file->tag.set_property("RECORD", record); file->tag.set_property("NUDGE", nudge); file->tag.set_property("PLAY", play); file->tag.set_property("GANG", gang); -// file->tag.set_property("MUTE", mute); file->tag.set_property("DRAW", draw); file->tag.set_property("EXPAND", expand_view); file->tag.set_property("TRACK_W", track_w); @@ -994,42 +991,35 @@ int Track::copy(double start, file->append_tag(); file->append_newline(); -//printf("Track::copy 1\n"); if(data_type == TRACK_AUDIO) file->tag.set_property("TYPE", "AUDIO"); else file->tag.set_property("TYPE", "VIDEO"); -//printf("Track::copy 1\n"); file->append_tag(); file->append_newline(); -//printf("Track::copy 2\n"); edits->copy(start_unit, end_unit, file, output_path); -//printf("Track::copy 3\n"); AutoConf auto_conf; auto_conf.set_all(); automation->copy(start_unit, end_unit, file, 0, 0); -//printf("Track::copy 4\n"); for(int i = 0; i < plugin_set.total; i++) { plugin_set.values[i]->copy(start_unit, end_unit, file); } -//printf("Track::copy 5\n"); copy_derived(start_unit, end_unit, file); -//printf("Track::copy 6\n"); file->tag.set_title("/TRACK"); file->append_tag(); file->append_newline(); file->append_newline(); file->append_newline(); file->append_newline(); -//printf("Track::copy 100\n"); + return 0; } diff --git a/hvirtual/cinelerra/trackcanvas.C b/hvirtual/cinelerra/trackcanvas.C index 281f7459..8172a8e2 100644 --- a/hvirtual/cinelerra/trackcanvas.C +++ b/hvirtual/cinelerra/trackcanvas.C @@ -53,6 +53,8 @@ #include "tracks.h" #include "transition.h" #include "vframe.h" +#include "apatchgui.inc" +#include "vpatchgui.inc" #include @@ -192,6 +194,95 @@ int TrackCanvas::keypress_event() result = 1; } break; + case TAB: + case LEFTTAB: + int cursor_x = get_relative_cursor_x(); + int cursor_y = get_relative_cursor_y(); + if(get_keypress() == TAB) + { + // Switch the record button + for(Track *track = mwindow->edl->tracks->first; track; track = track->next) + { + int64_t track_x, track_y, track_w, track_h; + track_dimensions(track, track_x, track_y, track_w, track_h); + + if(cursor_y >= track_y && + cursor_y < track_y + track_h) + { + if (track->record) + track->record = 0; + else + track->record = 1; + result = 1; + break; + } + } + } else + { + Track *this_track; + for(Track *track = mwindow->edl->tracks->first; track; track = track->next) + { + int64_t track_x, track_y, track_w, track_h; + track_dimensions(track, track_x, track_y, track_w, track_h); + + if(cursor_y >= track_y && + cursor_y < track_y + track_h) + { + // This is our track + this_track = track; + break; + } + } + + int total_selected = mwindow->edl->tracks->total_of(Tracks::RECORD); + +// nothing previously selected + if(total_selected == 0) + { + mwindow->edl->tracks->select_all(Tracks::RECORD, + 1); + } + else + if(total_selected == 1) + { +// this patch was previously the only one on + if(this_track && this_track->record) + { + mwindow->edl->tracks->select_all(Tracks::RECORD, + 1); + } +// another patch was previously the only one on + else + { + mwindow->edl->tracks->select_all(Tracks::RECORD, + 0); + if (this_track) + this_track->record = 1; + + } + } + else + if(total_selected > 1) + { + mwindow->edl->tracks->select_all(Tracks::RECORD, + 0); + if (this_track) + this_track->record = 1; + } + + } + + gui->update (0, + 1, + 0, + 0, + 1, + 0, + 1); + mwindow->cwindow->update(0, 1, 1); + + result = 1; + break; } // since things under cursor have changed... @@ -364,7 +455,8 @@ int TrackCanvas::drag_motion_event() int TrackCanvas::cursor_leave_event() { - // because drag motion calls get_cursor_over_window we can be sure that all highlights get deleted now +// because drag motion calls get_cursor_over_window we can be sure that +// all highlights get deleted now drag_motion(); return 0; } @@ -376,7 +468,6 @@ int TrackCanvas::drag_stop_event() if(drag_popup) { -//printf("TrackCanvas::drag_stop_event 1 %p\n", drag_popup); delete drag_popup; drag_popup = 0; } @@ -1606,6 +1697,7 @@ int TrackCanvas::do_keyframes(int cursor_x, } if(result && buttonpress) { + synchronize_autos(0, track, (FloatAuto*)mwindow->session->drag_auto, 1); mwindow->session->current_operation = DRAG_FADE; update_drag_caption(); } @@ -2159,6 +2251,83 @@ void TrackCanvas::draw_floatline(int center_pixel, } +void TrackCanvas::synchronize_autos(float change, Track *skip, FloatAuto *fauto, int fill_gangs) +{ + if (fill_gangs == 1 && skip->gang) // fill mwindow->session->drag_auto_gang + { + for(Track *current = mwindow->edl->tracks->first; + current; + current = NEXT) + { + if(current->data_type == skip->data_type && + current->gang && + current->record && + current != skip) + { + FloatAutos *fade_autos = current->automation->fade_autos; + double position = skip->from_units(fauto->position); + FloatAuto *previous = 0, *next = 0; + + float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next); + FloatAuto *keyframe; + keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position); + + if (!keyframe) + { +// create keyframe at exactly this point in time + keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position); + keyframe->value = init_value; + } + else + { +// keyframe exists, just change it + keyframe->value += change; + } + + keyframe->position = fauto->position; + keyframe->control_out_position = fauto->control_out_position; + keyframe->control_in_position = fauto->control_in_position; + keyframe->control_out_value = fauto->control_out_value; + keyframe->control_in_value = fauto->control_in_value; + + mwindow->session->drag_auto_gang->append((Auto *)keyframe); + } + } + } else + if (fill_gangs == 0) // move the gangs + { + + // Move the gang! + for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) + { + FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i]; + + keyframe->value += change; + keyframe->position = fauto->position; + if(skip->data_type == TRACK_AUDIO) + CLAMP(keyframe->value, INFINITYGAIN, MAX_AUDIO_FADE); + else + CLAMP(keyframe->value, 0, MAX_VIDEO_FADE); + keyframe->control_out_position = fauto->control_out_position; + keyframe->control_in_position = fauto->control_in_position; + keyframe->control_out_value = fauto->control_out_value; + keyframe->control_in_value = fauto->control_in_value; + } + + } else + if (fill_gangs == -1) // remove the gangs + { + for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) + { + FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i]; + keyframe->autos->remove_nonsequential( + keyframe); + } + mwindow->session->drag_auto_gang->remove_all(); + } +} + + int TrackCanvas::test_floatline(int center_pixel, FloatAutos *autos, int64_t unit_start, @@ -2845,6 +3014,8 @@ int TrackCanvas::do_plugin_autos(Track *track, double zoom_sample; double zoom_units; + if(!track->expand_view) return 0; + calculate_viewport(track, view_start, unit_start, @@ -2855,7 +3026,8 @@ int TrackCanvas::do_plugin_autos(Track *track, zoom_sample, zoom_units); -//printf("TrackCanvas::draw_plugin_autos 1 %d\n", track->plugin_set.total); + + for(int i = 0; i < track->plugin_set.total && !result; i++) { PluginSet *plugin_set = track->plugin_set.values[i]; @@ -2863,8 +3035,7 @@ int TrackCanvas::do_plugin_autos(Track *track, mwindow->edl->local_session->zoom_track + (i + 0.5) * mwindow->theme->plugin_bg_data->get_h() + (mwindow->edl->session->show_titles ? mwindow->theme->title_bg_data->get_h() : 0)); - -//printf("TrackCanvas::draw_plugin_autos 2\n"); + for(Plugin *plugin = (Plugin*)plugin_set->first; plugin && !result; plugin = (Plugin*)plugin->next) @@ -2932,7 +3103,7 @@ int TrackCanvas::do_plugin_autos(Track *track, void TrackCanvas::draw_overlays() { int new_cursor, update_cursor, rerender; -TRACE("TrackCanvas::draw_overlays 1") +//TRACE("TrackCanvas::draw_overlays 1") // Move background pixmap to foreground pixmap draw_pixmap(background_pixmap, @@ -2942,29 +3113,29 @@ TRACE("TrackCanvas::draw_overlays 1") get_h(), 0, 0); -TRACE("TrackCanvas::draw_overlays 10") +//TRACE("TrackCanvas::draw_overlays 10") // In/Out points draw_inout_points(); -TRACE("TrackCanvas::draw_overlays 11"); +//TRACE("TrackCanvas::draw_overlays 11"); // Transitions if(mwindow->edl->session->auto_conf->transitions) draw_transitions(); -TRACE("TrackCanvas::draw_overlays 12"); +//TRACE("TrackCanvas::draw_overlays 12"); // Plugins draw_plugins(); -TRACE("TrackCanvas::draw_overlays 13"); +//TRACE("TrackCanvas::draw_overlays 13"); // Loop points draw_loop_points(); draw_brender_start(); -TRACE("TrackCanvas::draw_overlays 14"); +//TRACE("TrackCanvas::draw_overlays 14"); // Highlighted areas draw_highlighting(); -TRACE("TrackCanvas::draw_overlays 15"); +//TRACE("TrackCanvas::draw_overlays 15"); // Automation do_keyframes(0, 0, @@ -2974,15 +3145,15 @@ TRACE("TrackCanvas::draw_overlays 15"); update_cursor, rerender); -TRACE("TrackCanvas::draw_overlays 16\n"); +//TRACE("TrackCanvas::draw_overlays 16\n"); // Selection cursor if(gui->cursor) gui->cursor->restore(); -TRACE("TrackCanvas::draw_overlays 17\n"); +//TRACE("TrackCanvas::draw_overlays 17\n"); // Handle dragging draw_drag_handle(); -TRACE("TrackCanvas::draw_overlays 20"); +//TRACE("TrackCanvas::draw_overlays 20"); // Playback cursor draw_playback_cursor(); @@ -3094,6 +3265,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0); float value; + float old_value; //printf("TrackCanvas::update_drag_floatauto %ld %d\n", //position, //mwindow->session->drag_handle); @@ -3103,6 +3275,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) // Center case 0: // Snap to nearby values + old_value = current->value; if(shift_down()) { double value1; @@ -3130,7 +3303,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) if(!current->previous && !current->next) { - value = ((FloatAutos*)current->autos)->default_; + current->value = ((FloatAutos*)current->autos)->default_; } value = current->value; } @@ -3138,11 +3311,13 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) value = ((FloatAuto*)current)->percentage_to_value(percentage); //printf("TrackCanvas::update_drag_floatauto 1 %f\n", value); - if(value != current->value || position != current->position) + if(value != old_value || position != current->position) { result = 1; + float change = value - old_value; current->value = value; current->position = position; + synchronize_autos(change, current->autos->track, current, 0); char string[BCTEXTLEN], string2[BCTEXTLEN]; Units::totext(string2, @@ -3166,6 +3341,7 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) result = 1; current->control_in_value = value; current->control_in_position = position; + synchronize_autos(0, current->autos->track, current, 0); char string[BCTEXTLEN], string2[BCTEXTLEN]; Units::totext(string2, @@ -3187,8 +3363,9 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y) position != current->control_out_position) { result = 1; - ((FloatAuto*)current)->control_out_value = value; - ((FloatAuto*)current)->control_out_position = position; + current->control_out_value = value; + current->control_out_position = position; + synchronize_autos(0, current->autos->track, current, 0); char string[BCTEXTLEN], string2[BCTEXTLEN]; Units::totext(string2, @@ -3547,6 +3724,7 @@ int TrackCanvas::cursor_motion_event() { draw_overlays(); flash(); + flush(); } @@ -3699,6 +3877,7 @@ int TrackCanvas::button_release_event() break; case DRAG_FADE: + synchronize_autos(0, 0, 0, -1); // delete the drag_auto_gang first and remove out of order keys case DRAG_CZOOM: case DRAG_PZOOM: case DRAG_PLAY: @@ -3747,11 +3926,13 @@ int TrackCanvas::button_release_event() { draw_overlays(); flash(); + flush(); } if(redraw) { draw(); flash(); + flush(); } return result; } @@ -4042,8 +4223,8 @@ int TrackCanvas::test_edits(int cursor_x, drag_popup = new BC_DragWindow(gui, mwindow->theme->clip_icon, - get_abs_cursor_x() - mwindow->theme->clip_icon->get_w() / 2, - get_abs_cursor_y() - mwindow->theme->clip_icon->get_h() / 2); + get_abs_cursor_x(0) - mwindow->theme->clip_icon->get_w() / 2, + get_abs_cursor_y(0) - mwindow->theme->clip_icon->get_h() / 2); //printf("TrackCanvas::test_edits 3 %p\n", drag_popup); result = 1; @@ -4162,14 +4343,15 @@ int TrackCanvas::test_plugins(int cursor_x, { case PLUGIN_STANDALONE: { - PluginServer *server = mwindow->scan_plugindb(plugin->title, - track->data_type); + PluginServer *server = mwindow->scan_plugindb( + plugin->title, + plugin->track->data_type); VFrame *frame = server->picon; //printf("TrackCanvas::test_plugins 7\n"); drag_popup = new BC_DragWindow(gui, frame, - get_abs_cursor_x() - frame->get_w() / 2, - get_abs_cursor_y() - frame->get_h() / 2); + get_abs_cursor_x(0) - frame->get_w() / 2, + get_abs_cursor_y(0) - frame->get_h() / 2); break; } @@ -4177,8 +4359,8 @@ int TrackCanvas::test_plugins(int cursor_x, case PLUGIN_SHAREDMODULE: drag_popup = new BC_DragWindow(gui, mwindow->theme->clip_icon, - get_abs_cursor_x() - mwindow->theme->clip_icon->get_w() / 2, - get_abs_cursor_y() - mwindow->theme->clip_icon->get_h() / 2); + get_abs_cursor_x(0) - mwindow->theme->clip_icon->get_w() / 2, + get_abs_cursor_y(0) - mwindow->theme->clip_icon->get_h() / 2); break; //printf("test plugins %d %p\n", mwindow->edl->session->editing_mode, mwindow->session->drag_plugin); } diff --git a/hvirtual/cinelerra/trackcanvas.h b/hvirtual/cinelerra/trackcanvas.h index d3e6352b..367e6167 100644 --- a/hvirtual/cinelerra/trackcanvas.h +++ b/hvirtual/cinelerra/trackcanvas.h @@ -178,6 +178,9 @@ public: double &zoom_sample, double &zoom_units); + void synchronize_autos(float change, Track *skip, FloatAuto *fauto, int fill_gangs); + + void draw_brender_start(); void draw_loop_points(); void draw_transitions(); diff --git a/hvirtual/cinelerra/tracking.C b/hvirtual/cinelerra/tracking.C index 6da7958e..d0cc7ef4 100644 --- a/hvirtual/cinelerra/tracking.C +++ b/hvirtual/cinelerra/tracking.C @@ -185,7 +185,7 @@ void Tracking::run() while(state != DONE) { Thread::enable_cancel(); - timer.delay(100); + timer.delay(1000 / TRACKING_RATE); Thread::disable_cancel(); if(state != DONE) diff --git a/hvirtual/cinelerra/tracking.inc b/hvirtual/cinelerra/tracking.inc new file mode 100644 index 00000000..6869bb91 --- /dev/null +++ b/hvirtual/cinelerra/tracking.inc @@ -0,0 +1,9 @@ +#ifndef TRACKING_INC +#define TRACKING_INC + +class Tracking; + +// Number of updates every second +#define TRACKING_RATE 24 + +#endif diff --git a/hvirtual/cinelerra/transitionpopup.C b/hvirtual/cinelerra/transitionpopup.C index 7c4fad5a..0f4a5970 100644 --- a/hvirtual/cinelerra/transitionpopup.C +++ b/hvirtual/cinelerra/transitionpopup.C @@ -37,8 +37,8 @@ void TransitionLengthThread::run() TransitionLengthDialog::TransitionLengthDialog(MWindow *mwindow, Transition *transition) : BC_Window(PROGRAM_NAME ": Transition length", - mwindow->gui->get_abs_cursor_x() - 150, - mwindow->gui->get_abs_cursor_y() - 50, + mwindow->gui->get_abs_cursor_x(1) - 150, + mwindow->gui->get_abs_cursor_y(1) - 50, 300, 100, -1, diff --git a/hvirtual/cinelerra/transportque.C b/hvirtual/cinelerra/transportque.C index 855920d5..bf55f716 100644 --- a/hvirtual/cinelerra/transportque.C +++ b/hvirtual/cinelerra/transportque.C @@ -1,3 +1,4 @@ +#include "bcsignals.h" #include "clip.h" #include "condition.h" #include "edl.h" @@ -40,6 +41,19 @@ EDL* TransportCommand::get_edl() return edl; } +void TransportCommand::delete_edl() +{ + delete edl; + edl = 0; +} + +void TransportCommand::new_edl() +{ + edl = new EDL; + edl->create_objects(); +} + + void TransportCommand::copy_from(TransportCommand *command) { this->command = command->command; @@ -251,7 +265,6 @@ int TransportQue::send_command(int command, change_type == CHANGE_ALL) { // Copy EDL -//printf("TransportQue::send_command 1 %p %p\n", this->command.get_edl(), new_edl); this->command.get_edl()->copy_all(new_edl); } else @@ -264,11 +277,9 @@ int TransportQue::send_command(int command, this->command.set_playback_range(new_edl); } -//printf("TransportQue::send_command 3\n"); -//printf("TransportQue::send_command 2 %p %d %d\n", new_edl, this->command.playbackstart); input_lock->unlock(); + output_lock->unlock(); -//printf("TransportQue::send_command 4\n"); return 0; } diff --git a/hvirtual/cinelerra/transportque.h b/hvirtual/cinelerra/transportque.h index a495bb3d..7aff0907 100644 --- a/hvirtual/cinelerra/transportque.h +++ b/hvirtual/cinelerra/transportque.h @@ -27,6 +27,8 @@ public: int single_frame(); EDL* get_edl(); + void delete_edl(); + void new_edl(); int command; int change_type; diff --git a/hvirtual/cinelerra/vattachmentpoint.C b/hvirtual/cinelerra/vattachmentpoint.C index 61ec560b..c60e2827 100644 --- a/hvirtual/cinelerra/vattachmentpoint.C +++ b/hvirtual/cinelerra/vattachmentpoint.C @@ -23,6 +23,7 @@ VAttachmentPoint::~VAttachmentPoint() void VAttachmentPoint::delete_buffer_vector() { + if(!this) printf("VAttachmentPoint::delete_buffer_vector NULL\n"); if(buffer_vector) { for(int i = 0; i < virtual_plugins.total; i++) @@ -34,6 +35,7 @@ void VAttachmentPoint::delete_buffer_vector() void VAttachmentPoint::new_buffer_vector(int width, int height, int colormodel) { + if(!this) printf("VAttachmentPoint::new_buffer_vector NULL\n"); if(buffer_vector && (width != buffer_vector[0]->get_w() || height != buffer_vector[0]->get_h() || @@ -64,10 +66,17 @@ int VAttachmentPoint::get_buffer_size() void VAttachmentPoint::render(VFrame *output, int buffer_number, long start_position, - double frame_rate) + double frame_rate, + int debug_render) { + if(!this) printf("VAttachmentPoint::render NULL\n"); if(!plugin_server || !plugin->on) return; + if(debug_render) + printf(" VAttachmentPoint::render %s %d\n", + plugin_server->title, + plugin_server->multichannel); + if(plugin_server->multichannel) { // Test against previous parameters for reuse of previous data @@ -112,10 +121,8 @@ void VAttachmentPoint::render(VFrame *output, else // process single track { -//printf("VAttachmentPoint::render 1\n"); VFrame *output_temp[1]; output_temp[0] = output; -//printf("VAttachmentPoint::render 1 %s\n", plugin_server->title); plugin_servers.values[buffer_number]->process_buffer(output_temp, start_position, frame_rate, @@ -123,7 +130,6 @@ void VAttachmentPoint::render(VFrame *output, frame_rate / renderengine->edl->session->frame_rate), renderengine->command->get_direction()); -//printf("VAttachmentPoint::render 100\n"); } } diff --git a/hvirtual/cinelerra/vattachmentpoint.h b/hvirtual/cinelerra/vattachmentpoint.h index 925af1ad..8b5a3f29 100644 --- a/hvirtual/cinelerra/vattachmentpoint.h +++ b/hvirtual/cinelerra/vattachmentpoint.h @@ -16,7 +16,8 @@ public: void render(VFrame *output, int buffer_number, long start_position, - double frame_rate); + double frame_rate, + int debug_render); void dispatch_plugin_server(int buffer_number, int64_t current_position, int64_t fragment_size); diff --git a/hvirtual/cinelerra/vdevice1394.C b/hvirtual/cinelerra/vdevice1394.C index 7dd62955..577f6a40 100644 --- a/hvirtual/cinelerra/vdevice1394.C +++ b/hvirtual/cinelerra/vdevice1394.C @@ -63,7 +63,9 @@ int VDevice1394::open_input() device->in_config->capture_length, 2, 48000, - 16); + 16, + device->in_config->w, + device->in_config->h); if(result) { delete input_thread; diff --git a/hvirtual/cinelerra/vdeviceprefs.C b/hvirtual/cinelerra/vdeviceprefs.C index fb0ab20d..8451b12b 100644 --- a/hvirtual/cinelerra/vdeviceprefs.C +++ b/hvirtual/cinelerra/vdeviceprefs.C @@ -1,6 +1,7 @@ #include "channelpicker.h" #include "edl.h" #include "edlsession.h" +#include "../hvirtual_config.h" #include "language.h" #include "mwindow.h" #include "vdeviceprefs.h" @@ -124,7 +125,6 @@ int VDevicePrefs::delete_objects() { case PLAYBACK_LML: case PLAYBACK_BUZ: - delete device_text; delete output_title; delete channel_picker; delete buz_swap_channels; @@ -420,8 +420,10 @@ int VDriverMenu::create_objects() if(do_input) { add_item(new VDriverItem(this, VIDEO4LINUX_TITLE, VIDEO4LINUX)); +#ifdef HAVE_VIDEO4LINUX2 add_item(new VDriverItem(this, VIDEO4LINUX2_TITLE, VIDEO4LINUX2)); add_item(new VDriverItem(this, VIDEO4LINUX2JPEG_TITLE, VIDEO4LINUX2JPEG)); +#endif add_item(new VDriverItem(this, SCREENCAPTURE_TITLE, SCREENCAPTURE)); add_item(new VDriverItem(this, CAPTURE_BUZ_TITLE, CAPTURE_BUZ)); add_item(new VDriverItem(this, CAPTURE_FIREWIRE_TITLE, CAPTURE_FIREWIRE)); diff --git a/hvirtual/cinelerra/vdevicev4l.C b/hvirtual/cinelerra/vdevicev4l.C index 07ed4a91..7f116b64 100644 --- a/hvirtual/cinelerra/vdevicev4l.C +++ b/hvirtual/cinelerra/vdevicev4l.C @@ -519,17 +519,14 @@ int VDeviceV4L::read_buffer(VFrame *frame) if(shared_memory) { -//printf("VDeviceV4L::read_buffer 1\n"); // Read the current frame if(!got_first_frame) v4l1_start_capture(); wait_v4l_frame(); read_v4l_frame(frame); // Free this frame up for capturing capture_frame(capture_frame_number); -//printf("VDeviceV4L::read_buffer 6\n"); // Advance the frame to capture. capture_frame_number = next_frame(capture_frame_number); -//printf("VDeviceV4L::read_buffer 7\n"); } else { @@ -539,3 +536,14 @@ int VDeviceV4L::read_buffer(VFrame *frame) return 0; } + + + + + + + + + + + diff --git a/hvirtual/cinelerra/videodevice.C b/hvirtual/cinelerra/videodevice.C index 7a4a9ba8..933aab47 100644 --- a/hvirtual/cinelerra/videodevice.C +++ b/hvirtual/cinelerra/videodevice.C @@ -99,7 +99,7 @@ int KeepaliveThread::stop() VideoDevice::VideoDevice() { in_config = new VideoInConfig; - out_config = new VideoOutConfig(0, 0); + out_config = new VideoOutConfig; channel = new Channel; picture = new Picture; sharing_lock = new Mutex("VideoDevice::sharing_lock"); @@ -162,6 +162,7 @@ int VideoDevice::open_input(VideoInConfig *config, this->input_z = -1; // Force initialization. this->frame_rate = frame_rate; + switch(in_config->driver) { case VIDEO4LINUX: @@ -172,7 +173,7 @@ int VideoDevice::open_input(VideoInConfig *config, break; -#ifdef HAVE_V4L2 +#ifdef HAVE_VIDEO4LINUX2 case VIDEO4LINUX2: input_base = new VDeviceV4L2(this); result = input_base->open_input(); diff --git a/hvirtual/cinelerra/virtualaconsole.C b/hvirtual/cinelerra/virtualaconsole.C index 35ac535e..3e2f93fb 100644 --- a/hvirtual/cinelerra/virtualaconsole.C +++ b/hvirtual/cinelerra/virtualaconsole.C @@ -135,28 +135,20 @@ int VirtualAConsole::process_buffer(int64_t len, if(meter_render_end > len) meter_render_end = len; - double min = 0; - double max = 0; double peak = 0; for( ; j < meter_render_end; j++) { // Level history comes before clipping to get over status - if(current_buffer[j] > max) max = current_buffer[j]; + double *sample = ¤t_buffer[j]; +// Clip it + if(fabs(*sample) > peak) peak = fabs(*sample); + if(*sample > 1) *sample = 1; else - if(current_buffer[j] < min) min = current_buffer[j]; - - if(current_buffer[j] > 1) current_buffer[j] = 1; - else - if(current_buffer[j] < -1) current_buffer[j] = -1; + if(*sample < -1) *sample = -1; } - if(fabs(max) > fabs(min)) - peak = fabs(max); - else - peak = fabs(min); - if(renderengine->command->realtime) { arender->level_history[i][arender->current_level[i]] = peak; diff --git a/hvirtual/cinelerra/virtualanode.C b/hvirtual/cinelerra/virtualanode.C index cd6272ba..d22bcf21 100644 --- a/hvirtual/cinelerra/virtualanode.C +++ b/hvirtual/cinelerra/virtualanode.C @@ -180,7 +180,6 @@ int VirtualANode::render_as_module(double **audio_out, int direction = renderengine->command->get_direction(); EDL *edl = vconsole->renderengine->edl; -//printf("VirtualANode::render_as_module 1 %p\n", this); // Process last subnode. This calls read_data, propogates up the chain // of subnodes, and finishes the chain. @@ -219,26 +218,25 @@ int VirtualANode::render_as_module(double **audio_out, if(real_module && renderengine->command->realtime) { ARender *arender = ((VirtualAConsole*)vconsole)->arender; - double max = 0, min = 0, peak; // Starting sample of meter block int64_t meter_render_start; // Ending sample of meter block int64_t meter_render_end; - int64_t current_level = ((AModule*)real_module)->current_level; // Number of samples in each meter fragment normalized to requested rate int meter_render_fragment = arender->meter_render_fragment * sample_rate / project_sample_rate; + // Scan fragment in meter sized fragments for(int i = 0; i < len; ) { + int current_level = ((AModule*)real_module)->current_level; + double peak = 0; meter_render_start = i; meter_render_end = i + meter_render_fragment; if(meter_render_end > len) meter_render_end = len; - max = 0; - min = 0; // Number of samples into the fragment this meter sized fragment is, // normalized to project sample rate. int64_t meter_render_start_project = meter_render_start * @@ -248,16 +246,10 @@ int VirtualANode::render_as_module(double **audio_out, // Scan meter sized fragment for( ; i < meter_render_end; i++) { - if(output_temp[i] > max) max = output_temp[i]; - else - if(output_temp[i] < min) min = output_temp[i]; + double sample = fabs(output_temp[i]); + if(sample > peak) peak = sample; } - if(fabs(max) > fabs(min)) - peak = fabs(max); - else - peak = fabs(min); - ((AModule*)real_module)->level_history[current_level] = peak; ((AModule*)real_module)->level_samples[current_level] = @@ -265,19 +257,19 @@ int VirtualANode::render_as_module(double **audio_out, (start_position_project + meter_render_start_project) : (start_position_project - meter_render_start_project); ((AModule*)real_module)->current_level = - arender->get_next_peak(((AModule*)real_module)->current_level); + arender->get_next_peak(current_level); } } // process pans and copy the output to the output channels // Keep rendering unmuted fragments until finished. - int64_t mute_position = 0; + int mute_position = 0; for(int i = 0; i < len; ) { int mute_constant; - int64_t mute_fragment = len - i; - int64_t mute_fragment_project = mute_fragment * + int mute_fragment = len - i; + int mute_fragment_project = mute_fragment * project_sample_rate / sample_rate; start_position_project = start_position + @@ -304,17 +296,6 @@ int VirtualANode::render_as_module(double **audio_out, { double *buffer = audio_out[j]; -// printf("VirtualANode::render_as_module 4.3 %p %p %lld %lld %lld %lld %p %d %d\n", -// output_temp, -// buffer, -// mute_position, -// mute_fragment, -// start_position + -// ((direction == PLAY_FORWARD) ? i : -i), -// sample_rate, -// (Autos*)track->automation->pan_autos, -// j, -// direction); render_pan(output_temp + mute_position, buffer + mute_position, mute_fragment, @@ -327,14 +308,12 @@ int VirtualANode::render_as_module(double **audio_out, } } } -//printf("VirtualANode::render_as_module 4.4\n"); len -= mute_fragment; i += mute_fragment; mute_position += mute_fragment; } -//printf("VirtualANode::render_as_module 100 %p\n", this); return 0; } diff --git a/hvirtual/cinelerra/virtualconsole.C b/hvirtual/cinelerra/virtualconsole.C index 807c3a50..d0c210fc 100644 --- a/hvirtual/cinelerra/virtualconsole.C +++ b/hvirtual/cinelerra/virtualconsole.C @@ -26,6 +26,7 @@ VirtualConsole::VirtualConsole(RenderEngine *renderengine, total_entry_nodes = 0; playable_tracks = 0; entry_nodes = 0; + debug_tree = 0; } @@ -33,7 +34,7 @@ VirtualConsole::~VirtualConsole() { delete_virtual_console(); - if(playable_tracks) delete playable_tracks; + delete playable_tracks; } diff --git a/hvirtual/cinelerra/virtualconsole.h b/hvirtual/cinelerra/virtualconsole.h index c5eba5c6..f5b970a7 100644 --- a/hvirtual/cinelerra/virtualconsole.h +++ b/hvirtual/cinelerra/virtualconsole.h @@ -80,7 +80,8 @@ public: // exit conditions int interrupt; int done; - +// Trace the rendering path of the tree + int debug_tree; diff --git a/hvirtual/cinelerra/virtualnode.C b/hvirtual/cinelerra/virtualnode.C index e169cc81..9af2966d 100644 --- a/hvirtual/cinelerra/virtualnode.C +++ b/hvirtual/cinelerra/virtualnode.C @@ -462,12 +462,11 @@ VirtualNode* VirtualNode::get_previous_plugin(VirtualNode *current_node) void VirtualNode::get_mute_fragment(int64_t input_position, int &mute_constant, - int64_t &fragment_len, + int &fragment_len, Autos *autos, int direction, int use_nudge) { - int64_t mute_len; if(use_nudge) input_position += track->nudge; IntAuto *prev_keyframe = 0; diff --git a/hvirtual/cinelerra/virtualnode.h b/hvirtual/cinelerra/virtualnode.h index 1089da4a..121cdc5b 100644 --- a/hvirtual/cinelerra/virtualnode.h +++ b/hvirtual/cinelerra/virtualnode.h @@ -114,7 +114,7 @@ public: // of the next status in fragment_len void get_mute_fragment(int64_t input_position, int &mute_constant, - int64_t &fragment_len, + int &fragment_len, Autos *autos, int direction, int use_nudge); diff --git a/hvirtual/cinelerra/virtualvconsole.C b/hvirtual/cinelerra/virtualvconsole.C index 8bde24bf..4177b567 100644 --- a/hvirtual/cinelerra/virtualvconsole.C +++ b/hvirtual/cinelerra/virtualvconsole.C @@ -1,3 +1,4 @@ +#include "bcsignals.h" #include "datatype.h" #include "edl.h" #include "edlsession.h" @@ -36,29 +37,6 @@ void VirtualVConsole::get_playable_tracks() 1); } -// void VirtualVConsole::new_input_buffer(int ring_buffer) -// { -// buffer_in = new VFrame*[total_tracks]; -// //printf("VirtualVConsole::new_input_buffer 1\n"); -// for(int i = 0; i < total_tracks; i++) -// { -// buffer_in[i] = new VFrame(0, -// playable_tracks->values[i]->track_w, -// playable_tracks->values[i]->track_h, -// renderengine->edl->session->color_model, -// -1); -// } -// } -// -// void VirtualVConsole::delete_input_buffer(int ring_buffer) -// { -// for(int i = 0; i < total_tracks; i++) -// { -// delete buffer_in[i]; -// } -// delete [] buffer_in; -// } - VirtualNode* VirtualVConsole::new_entry_node(Track *track, Module *module, int track_number) @@ -77,7 +55,11 @@ int VirtualVConsole::process_buffer(int64_t input_position) int i, j, k; int result = 0; -//printf("VirtualVConsole::process_buffer 1\n"); + + + + + if(debug_tree) printf("VirtualVConsole::process_buffer begin\n"); // clear output buffers for(i = 0; i < MAX_CHANNELS; i++) { @@ -114,11 +96,13 @@ int VirtualVConsole::process_buffer(int64_t input_position) -1); } +//printf("VirtualVConsole::process_buffer %p\n", output_temp->get_rows()); result |= node->render(output_temp, input_position + track->nudge, renderengine->edl->session->frame_rate); } + if(debug_tree) printf("VirtualVConsole::process_buffer end\n"); return result; } diff --git a/hvirtual/cinelerra/virtualvnode.C b/hvirtual/cinelerra/virtualvnode.C index c6a2ea62..308e02cb 100644 --- a/hvirtual/cinelerra/virtualvnode.C +++ b/hvirtual/cinelerra/virtualvnode.C @@ -82,6 +82,11 @@ int VirtualVNode::read_data(VFrame *output_temp, if(!output_temp) printf("VirtualVNode::read_data output_temp=%p\n", output_temp); + if(vconsole->debug_tree) + printf(" VirtualVNode::read_data position=%lld rate=%f title=%s\n", + start_position, + frame_rate, + track->title); // This is a plugin on parent module with a preceeding effect. // Get data from preceeding effect on parent module. @@ -107,7 +112,8 @@ int VirtualVNode::read_data(VFrame *output_temp, start_position, renderengine->command->get_direction(), frame_rate, - 0); + 0, + vconsole->debug_tree); } return 0; @@ -146,11 +152,16 @@ void VirtualVNode::render_as_plugin(VFrame *output_temp, !real_plugin || !real_plugin->on) return; + + if(vconsole->debug_tree) + printf(" VirtualVNode::render_as_plugin title=%s\n", track->title); + ((VAttachmentPoint*)attachment)->render( output_temp, plugin_buffer_number, start_position, - frame_rate); + frame_rate, + vconsole->debug_tree); } @@ -159,33 +170,30 @@ int VirtualVNode::render_as_module(VFrame **video_out, int64_t start_position, double frame_rate) { -//printf("VirtualVNode::render_as_module 1\n"); + int direction = renderengine->command->get_direction(); double edl_rate = renderengine->edl->session->frame_rate; + if(vconsole->debug_tree) + printf(" VirtualVNode::render_as_module title=%s\n", track->title); + // Process last subnode. This propogates up the chain of subnodes and finishes // the chain. if(subnodes.total) { -//printf("VirtualVNode::render_as_module 2\n"); VirtualVNode *node = (VirtualVNode*)subnodes.values[subnodes.total - 1]; node->render(output_temp, start_position, frame_rate); -//printf("VirtualVNode::render_as_module 3\n"); } else // Read data from previous entity { -//printf("VirtualVNode::render_as_module 5\n"); read_data(output_temp, start_position, frame_rate); -//printf("VirtualVNode::render_as_module 6\n"); } - -//printf("VirtualVNode::render_as_module 10\n"); render_fade(output_temp, start_position, frame_rate, @@ -204,7 +212,7 @@ int VirtualVNode::render_as_module(VFrame **video_out, // overlay on the final output // Get mute status int mute_constant; - int64_t mute_fragment = 1; + int mute_fragment = 1; int64_t mute_position = 0; @@ -225,7 +233,6 @@ int VirtualVNode::render_as_module(VFrame **video_out, frame_rate); } -//printf("VirtualVNode::render_as_module 100\n"); return 0; } @@ -246,6 +253,9 @@ int VirtualVNode::render_fade(VFrame *output, edl_rate / frame_rate); + if(vconsole->debug_tree) + printf(" VirtualVNode::render_fade title=%s\n", track->title); + intercept = ((FloatAutos*)autos)->get_value(start_position_project, direction, previous, @@ -279,6 +289,8 @@ int VirtualVNode::render_projector(VFrame *input, edl_rate / frame_rate); VRender *vrender = ((VirtualVConsole*)vconsole)->vrender; + if(vconsole->debug_tree) + printf(" VirtualVNode::render_projector title=%s\n", track->title); for(int i = 0; i < MAX_CHANNELS; i++) { diff --git a/hvirtual/cinelerra/vmodule.C b/hvirtual/cinelerra/vmodule.C index e74049ca..ec446e74 100644 --- a/hvirtual/cinelerra/vmodule.C +++ b/hvirtual/cinelerra/vmodule.C @@ -148,6 +148,7 @@ int VModule::import_frame(VFrame *output, !EQUIV(in_w1, current_edit->asset->width) || !EQUIV(in_h1, current_edit->asset->height)) { +//printf("VModule::import_frame 1\n"); // Get temporary input buffer VFrame **input = 0; // Realtime playback @@ -293,10 +294,14 @@ int VModule::render(VFrame *output, int64_t start_position, int direction, double frame_rate, - int use_nudge) + int use_nudge, + int debug_render) { int result = 0; double edl_rate = get_edl()->session->frame_rate; + + + if(use_nudge) start_position += (int64_t)(track->nudge * frame_rate / edl_rate); @@ -307,9 +312,16 @@ int VModule::render(VFrame *output, frame_rate + 0.5); + if(debug_render) + printf(" VModule::render %d %lld %s\n", + use_nudge, + start_position_project, + track->title); + update_transition(start_position_project, direction); + VEdit* current_edit = (VEdit*)track->edits->editof(start_position_project, direction, 0); diff --git a/hvirtual/cinelerra/vmodule.h b/hvirtual/cinelerra/vmodule.h index daf809b6..0249bed6 100644 --- a/hvirtual/cinelerra/vmodule.h +++ b/hvirtual/cinelerra/vmodule.h @@ -48,7 +48,8 @@ public: int64_t start_position, int direction, double frame_rate, - int use_nudge); + int use_nudge, + int debug_render); // synchronization with tracks FloatAutos* get_fade_automation(); // get the fade automation for this module diff --git a/hvirtual/cinelerra/vplayback.C b/hvirtual/cinelerra/vplayback.C new file mode 100644 index 00000000..9fe6d515 --- /dev/null +++ b/hvirtual/cinelerra/vplayback.C @@ -0,0 +1,33 @@ +#include "edl.h" +#include "edlsession.h" +#include "playtransport.h" +#include "transportque.h" +#include "vplayback.h" +#include "vtracking.h" +#include "vwindow.h" +#include "vwindowgui.h" + +// Playback engine for viewer + +VPlayback::VPlayback(MWindow *mwindow, VWindow *vwindow, Canvas *output) + : PlaybackEngine(mwindow, output) +{ + this->vwindow = vwindow; +} + +int VPlayback::create_render_engine() +{ + return PlaybackEngine::create_render_engine(); +} + +void VPlayback::init_cursor() +{ + vwindow->playback_cursor->start_playback(tracking_position); +} + +void VPlayback::stop_cursor() +{ + vwindow->playback_cursor->stop_playback(); +} + + diff --git a/hvirtual/cinelerra/vplayback.h b/hvirtual/cinelerra/vplayback.h new file mode 100644 index 00000000..0d42f2b7 --- /dev/null +++ b/hvirtual/cinelerra/vplayback.h @@ -0,0 +1,20 @@ +#ifndef VPLAYBACK_H +#define VPLAYBACK_H + +#include "playbackengine.h" +#include "vwindow.inc" + +class VPlayback : public PlaybackEngine +{ +public: + VPlayback(MWindow *mwindow, VWindow *vwindow, Canvas *output); + + int create_render_engine(); + void init_cursor(); + void stop_cursor(); + void goto_start(); + void goto_end(); + VWindow *vwindow; +}; + +#endif diff --git a/hvirtual/cinelerra/vrender.C b/hvirtual/cinelerra/vrender.C index aa31675d..1ae25599 100644 --- a/hvirtual/cinelerra/vrender.C +++ b/hvirtual/cinelerra/vrender.C @@ -1,4 +1,5 @@ #include "asset.h" +#include "bcsignals.h" #include "cache.h" #include "condition.h" #include "datatype.h" @@ -104,20 +105,23 @@ int VRender::process_buffer(int64_t input_position) int use_brender = 0; int result = 0; -//sleep(1); +//TRACE("VRender::process_buffer 1"); // Determine the rendering strategy for this frame. use_vconsole = get_use_vconsole(playable_edit, input_position, use_brender); +//TRACE("VRender::process_buffer 2"); // Negotiate color model colormodel = get_colormodel(playable_edit, use_vconsole, use_brender); +//TRACE("VRender::process_buffer 3"); // Get output buffer from device if(renderengine->command->realtime) renderengine->video->new_output_buffers(video_out, colormodel); +//TRACE("VRender::process_buffer 4"); // Read directly from file to video_out if(!use_vconsole) @@ -133,11 +137,11 @@ int VRender::process_buffer(int64_t input_position) if(renderengine->command->get_direction() == PLAY_REVERSE) corrected_position--; - file->set_video_position(corrected_position, - renderengine->edl->session->frame_rate); // Cache single frames only if(renderengine->command->single_frame()) file->set_cache_frames(1); + file->set_video_position(corrected_position, + renderengine->edl->session->frame_rate); file->read_frame(video_out[0]); if(renderengine->command->single_frame()) file->set_cache_frames(0); @@ -160,7 +164,9 @@ int VRender::process_buffer(int64_t input_position) { // process this buffer now in the virtual console +//TRACE("VRender::process_buffer 5"); result = ((VirtualVConsole*)vconsole)->process_buffer(input_position); +//TRACE("VRender::process_buffer 10"); } @@ -304,9 +310,12 @@ void VRender::run() process_buffer(current_position); +//TRACE("VRender::run 1"); if(renderengine->command->single_frame()) { +//TRACE("VRender::run 2"); flash_output(); +//TRACE("VRender::run 3"); frame_step = 1; done = 1; } @@ -387,6 +396,7 @@ void VRender::run() flash_output(); } } +//TRACE("VRender::run 4"); // Trigger audio to start if(first_frame) @@ -395,6 +405,7 @@ void VRender::run() first_frame = 0; renderengine->reset_sync_position(); } +//TRACE("VRender::run 5"); session_frame += frame_step; @@ -412,6 +423,7 @@ void VRender::run() frame_step -= current_input_length; current_input_length = frame_step; } +//TRACE("VRender::run 6"); // Update tracking. if(renderengine->command->realtime && @@ -421,6 +433,7 @@ void VRender::run() renderengine->playback_engine->update_tracking(fromunits(current_position)); } +//TRACE("VRender::run 7"); // Calculate the framerate counter framerate_counter++; if(framerate_counter >= renderengine->edl->session->frame_rate && @@ -431,6 +444,7 @@ void VRender::run() framerate_counter = 0; framerate_timer.update(); } +//TRACE("VRender::run 8"); } // In case we were interrupted before the first loop diff --git a/hvirtual/guicast/bcbitmap.C b/hvirtual/guicast/bcbitmap.C index b0fc50eb..66c0a3a6 100644 --- a/hvirtual/guicast/bcbitmap.C +++ b/hvirtual/guicast/bcbitmap.C @@ -1,6 +1,7 @@ #include "bcbitmap.h" #include "bcipc.h" #include "bcresources.h" +#include "bcsignals.h" #include "bcwindow.h" #include "colormodels.h" #include "vframe.h" @@ -237,6 +238,7 @@ int BC_Bitmap::allocate_data() perror("BC_Bitmap::allocate_data XShmAttach"); } +// This causes it to automatically delete when the program exits. shmctl(shm_info.shmid, IPC_RMID, 0); } else @@ -419,7 +421,9 @@ int BC_Bitmap::write_drawable(Drawable &pixmap, //printf("BC_Bitmap::write_drawable 1 %p %d\n", this, current_ringbuffer);fflush(stdout); if(use_shm) { +//TRACE("BC_Bitmap::write_drawable 1"); if(dont_wait) XSync(top_level->display, False); +//TRACE("BC_Bitmap::write_drawable 2"); if(hardware_scaling()) { @@ -436,6 +440,7 @@ int BC_Bitmap::write_drawable(Drawable &pixmap, // pixmap, // gc, // xv_image[current_ringbuffer]); +//TRACE("BC_Bitmap::write_drawable 3"); XvShmPutImage(top_level->display, xv_portid, pixmap, @@ -450,7 +455,7 @@ int BC_Bitmap::write_drawable(Drawable &pixmap, dest_w, dest_h, False); -//printf("BC_Bitmap::write_drawable 2\n"); +//TRACE("BC_Bitmap::write_drawable 4"); // Need to pass these to the XvStopVideo last_pixmap = pixmap; last_pixmap_used = 1; @@ -481,6 +486,7 @@ int BC_Bitmap::write_drawable(Drawable &pixmap, // Force the X server into processing all requests. // This allows the shared memory to be written to again. if(!dont_wait) XSync(top_level->display, False); +//TRACE("BC_Bitmap::write_drawable 5"); } else { diff --git a/hvirtual/guicast/bcbutton.C b/hvirtual/guicast/bcbutton.C index 4b418d06..a10a0e66 100644 --- a/hvirtual/guicast/bcbutton.C +++ b/hvirtual/guicast/bcbutton.C @@ -166,8 +166,11 @@ int BC_Button::cursor_leave_event() if(status == BUTTON_UPHI) { status = BUTTON_UP; + draw_face(); + hide_tooltip(); + } return 0; } @@ -339,9 +342,9 @@ int BC_GenericButton::draw_face() draw_3segmenth(0, 0, get_w(), images[status]); if(enabled) - set_color(BLACK); + set_color(get_resources()->default_text_color); else - set_color(MEGREY); + set_color(get_resources()->disabled_text_color); set_font(MEDIUMFONT); y = (int)((float)get_h() / 2 + get_text_ascent(MEDIUMFONT) / 2 - 2); w = get_text_width(current_font, text, strlen(text)); diff --git a/hvirtual/guicast/bccounter.C b/hvirtual/guicast/bccounter.C new file mode 100644 index 00000000..bb3b98ab --- /dev/null +++ b/hvirtual/guicast/bccounter.C @@ -0,0 +1,29 @@ +#include "bccounter.h" +#include "mutex.h" + +BCCounter::BCCounter() +{ + value = 0; + mutex = new Mutex; +} + +BCCounter::~BCCounter() +{ + delete mutex; +} + +void BCCounter::up() +{ + mutex->lock("BCCounter::up"); + value++; + printf("BCCounter::up %p %d\n", this, value); + mutex->unlock(); +} + +void BCCounter::down() +{ + mutex->lock("BCCounter::down"); + value--; + printf("BCCounter::down %p %d\n", this, value); + mutex->unlock(); +} diff --git a/hvirtual/guicast/bcdisplayinfo.C b/hvirtual/guicast/bcdisplayinfo.C index eddef3d9..fa54ef10 100644 --- a/hvirtual/guicast/bcdisplayinfo.C +++ b/hvirtual/guicast/bcdisplayinfo.C @@ -199,6 +199,11 @@ int BC_DisplayInfo::get_bottom_border() void BC_DisplayInfo::init_window(char *display_name, int show_error) { if(display_name && display_name[0] == 0) display_name = NULL; + +// This function must be the first Xlib +// function a multi-threaded program calls + XInitThreads(); + if((display = XOpenDisplay(display_name)) == NULL) { if(show_error) diff --git a/hvirtual/guicast/bcdragwindow.C b/hvirtual/guicast/bcdragwindow.C index 42ac90cd..21514aa2 100644 --- a/hvirtual/guicast/bcdragwindow.C +++ b/hvirtual/guicast/bcdragwindow.C @@ -21,8 +21,8 @@ BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window, init_y = icon_y; end_x = BC_INFINITY; end_y = BC_INFINITY; - icon_offset_x = init_x - parent_window->get_abs_cursor_x(); - icon_offset_y = init_y - parent_window->get_abs_cursor_y(); + icon_offset_x = init_x - parent_window->get_abs_cursor_x(0); + icon_offset_y = init_y - parent_window->get_abs_cursor_y(0); //printf("BC_DragWindow::BC_DragWindow 1 %d %d\n", icon_offset_x, icon_offset_y); do_animation = 1; } @@ -46,8 +46,8 @@ BC_DragWindow::BC_DragWindow(BC_WindowBase *parent_window, init_y = icon_y; end_x = BC_INFINITY; end_y = BC_INFINITY; - icon_offset_x = init_x - parent_window->get_abs_cursor_x(); - icon_offset_y = init_y - parent_window->get_abs_cursor_y(); + icon_offset_x = init_x - parent_window->get_abs_cursor_x(0); + icon_offset_y = init_y - parent_window->get_abs_cursor_y(0); //printf("BC_DragWindow::BC_DragWindow 1 %d %d\n", icon_offset_x, icon_offset_y); do_animation = 1; } @@ -88,8 +88,8 @@ int BC_DragWindow::get_init_y(BC_WindowBase *parent_window, int icon_y) int BC_DragWindow::cursor_motion_event() { - reposition_window(get_abs_cursor_x() + icon_offset_x, - get_abs_cursor_y() + icon_offset_y, + reposition_window(get_abs_cursor_x(0) + icon_offset_x, + get_abs_cursor_y(0) + icon_offset_y, get_w(), get_h()); flush(); diff --git a/hvirtual/guicast/bcfilebox.C b/hvirtual/guicast/bcfilebox.C index 87fa596f..c6203235 100644 --- a/hvirtual/guicast/bcfilebox.C +++ b/hvirtual/guicast/bcfilebox.C @@ -1,11 +1,13 @@ #include "bcfilebox.h" +#include "bclistboxitem.h" #include "bcpixmap.h" #include "bcresources.h" #include "bctitle.h" #include "clip.h" +#include "condition.h" #include "filesystem.h" -#include "bclistboxitem.h" #include "language.h" +#include "mutex.h" #include #include @@ -57,21 +59,27 @@ BC_NewFolderThread::BC_NewFolderThread(BC_FileBox *filebox) { this->filebox = filebox; window = 0; + change_lock = new Mutex("BC_NewFolderThread::change_lock"); + completion_lock = new Condition(1, "BC_NewFolderThread::completion_lock"); } BC_NewFolderThread::~BC_NewFolderThread() { interrupt(); + delete change_lock; + delete completion_lock; } void BC_NewFolderThread::run() { - change_lock.lock(); - window = new BC_NewFolder(filebox->get_abs_cursor_x(), - filebox->get_abs_cursor_y(), + int x = filebox->get_abs_cursor_x(1); + int y = filebox->get_abs_cursor_y(1); + change_lock->lock("BC_NewFolderThread::run 1"); + window = new BC_NewFolder(x, + y, filebox); window->create_objects(); - change_lock.unlock(); + change_lock->unlock(); int result = window->run_window(); @@ -81,51 +89,51 @@ void BC_NewFolderThread::run() char new_folder[BCTEXTLEN]; filebox->fs->join_names(new_folder, filebox->fs->get_current_dir(), window->get_text()); mkdir(new_folder, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - filebox->lock_window(); + filebox->lock_window("BC_NewFolderThread::run"); filebox->refresh(); filebox->unlock_window(); } - change_lock.lock(); + change_lock->lock("BC_NewFolderThread::run 2"); delete window; window = 0; - change_lock.unlock(); + change_lock->unlock(); - completion_lock.unlock(); + completion_lock->unlock(); } int BC_NewFolderThread::interrupt() { - change_lock.lock(); + change_lock->lock("BC_NewFolderThread::interrupt"); if(window) { - window->lock_window(); + window->lock_window("BC_NewFolderThread::interrupt"); window->set_done(1); window->unlock_window(); } - change_lock.unlock(); + change_lock->unlock(); - completion_lock.lock(); - completion_lock.unlock(); + completion_lock->lock("BC_NewFolderThread::interrupt"); + completion_lock->unlock(); return 0; } int BC_NewFolderThread::start_new_folder() { - change_lock.lock(); + change_lock->lock(); if(window) { - window->lock_window(); + window->lock_window("BC_NewFolderThread::start_new_folder"); window->raise_window(); window->unlock_window(); - change_lock.unlock(); + change_lock->unlock(); } else { - change_lock.unlock(); - completion_lock.lock(); + change_lock->unlock(); + completion_lock->lock("BC_NewFolderThread::start_new_folder"); Thread::start(); } diff --git a/hvirtual/guicast/bcfilebox.h b/hvirtual/guicast/bcfilebox.h index 570674d8..7f7b9482 100644 --- a/hvirtual/guicast/bcfilebox.h +++ b/hvirtual/guicast/bcfilebox.h @@ -8,8 +8,9 @@ #include "bcresources.inc" #include "bctextbox.h" #include "bcwindow.h" +#include "condition.inc" #include "filesystem.inc" -#include "mutex.h" +#include "mutex.inc" #include "thread.h" @@ -37,7 +38,8 @@ public: int start_new_folder(); private: - Mutex change_lock, completion_lock; + Mutex *change_lock; + Condition *completion_lock; BC_FileBox *filebox; BC_NewFolder *window; }; diff --git a/hvirtual/guicast/bclistbox.C b/hvirtual/guicast/bclistbox.C index 6bd486dc..c3365faa 100644 --- a/hvirtual/guicast/bclistbox.C +++ b/hvirtual/guicast/bclistbox.C @@ -3543,21 +3543,21 @@ int BC_ListBox::drag_start_event() { drag_popup = new BC_DragWindow(this, item_return->icon_vframe, - get_abs_cursor_x() - item_return->icon_vframe->get_w() / 2, - get_abs_cursor_y() - item_return->icon_vframe->get_h() / 2); + get_abs_cursor_x(0) - item_return->icon_vframe->get_w() / 2, + get_abs_cursor_y(0) - item_return->icon_vframe->get_h() / 2); } else // this probably works not! if (item_return->icon) drag_popup = new BC_DragWindow(this, item_return->icon, - get_abs_cursor_x() - item_return->icon->get_w() / 2, - get_abs_cursor_y() - item_return->icon->get_h() / 2); + get_abs_cursor_x(0) - item_return->icon->get_w() / 2, + get_abs_cursor_y(0) - item_return->icon->get_h() / 2); else drag_popup = new BC_DragWindow(this, drag_icon_vframe, - get_abs_cursor_x() - drag_icon_vframe->get_w() / 2, - get_abs_cursor_y() - drag_icon_vframe->get_h() / 2); + get_abs_cursor_x(0) - drag_icon_vframe->get_w() / 2, + get_abs_cursor_y(0) - drag_icon_vframe->get_h() / 2); current_operation = DRAG_ITEM; return 1; } @@ -3569,8 +3569,8 @@ int BC_ListBox::drag_start_event() { drag_popup = new BC_DragWindow(this, drag_column_icon_vframe, - get_abs_cursor_x() - drag_column_icon_vframe->get_w() / 2, - get_abs_cursor_y() - drag_column_icon_vframe->get_h() / 2); + get_abs_cursor_x(0) - drag_column_icon_vframe->get_w() / 2, + get_abs_cursor_y(0) - drag_column_icon_vframe->get_h() / 2); dragged_title = highlighted_title; current_operation = COLUMN_DRAG; draw_titles(1); @@ -3814,7 +3814,8 @@ int BC_ListBox::activate() &tempwin); if(new_x < 0) new_x = 0; - if(new_y + popup_h > top_level->get_root_h()) new_y -= get_h() + popup_h; + if(new_y + popup_h > top_level->get_root_h(0)) + new_y -= get_h() + popup_h; //printf("BC_ListBox::activate %d %d\n", popup_w, popup_h); add_subwindow(gui = new BC_Popup(this, @@ -4283,9 +4284,9 @@ int BC_ListBox::draw_titles(int flash) { BC_Pixmap *src; if(sort_order == SORT_ASCENDING) - src = column_sort_up; - else src = column_sort_dn; + else + src = column_sort_up; int x = column_offset + column_width - LISTBOX_BORDER; if(x > items_w) x = items_w; diff --git a/hvirtual/guicast/bcmenubar.C b/hvirtual/guicast/bcmenubar.C index cdd74037..a74ca5db 100644 --- a/hvirtual/guicast/bcmenubar.C +++ b/hvirtual/guicast/bcmenubar.C @@ -222,6 +222,7 @@ int BC_MenuBar::draw_face() draw_line(0, h, w, h); flash(); + flush(); return 0; } diff --git a/hvirtual/guicast/bcmeter.C b/hvirtual/guicast/bcmeter.C index d59383b4..5f34cca3 100644 --- a/hvirtual/guicast/bcmeter.C +++ b/hvirtual/guicast/bcmeter.C @@ -8,12 +8,15 @@ #include "vframe.h" #include +// Which source image to replicate #define METER_NORMAL 0 #define METER_GREEN 1 #define METER_RED 2 #define METER_YELLOW 3 -#define METER_OVER 4 +#define METER_WHITE 4 +#define METER_OVER 5 +// Region of source image to replicate #define METER_LEFT 0 #define METER_MID 1 #define METER_RIGHT 3 @@ -23,7 +26,8 @@ BC_Meter::BC_Meter(int x, int y, int orientation, int pixels, - float min, + int min, + int max, int mode, int use_titles, long over_delay, @@ -34,23 +38,18 @@ BC_Meter::BC_Meter(int x, this->over_delay = over_delay; this->peak_delay = peak_delay; this->min = min; + this->max = max; this->mode = mode; this->orientation = orientation; this->pixels = pixels; for(int i = 0; i < TOTAL_METER_IMAGES; i++) images[i] = 0; - title_pixel = 0; - db_titles = 0; - meter_titles = 0; } BC_Meter::~BC_Meter() { - if(db_titles) - { - for(int i = 0; i < meter_titles; i++) delete [] db_titles[i]; - delete [] db_titles; - } - if(title_pixel) delete [] title_pixel; + db_titles.remove_all_objects(); + title_pixels.remove_all(); + tick_pixels.remove_all(); for(int i = 0; i < TOTAL_METER_IMAGES; i++) delete images[i]; } @@ -161,10 +160,11 @@ int BC_Meter::reset_over() return 0; } -int BC_Meter::change_format(int mode, float min) +int BC_Meter::change_format(int mode, int min, int max) { this->mode = mode; this->min = min; + this->max = max; reposition_window(get_x(), get_y(), pixels); return 0; } @@ -174,12 +174,15 @@ int BC_Meter::level_to_pixel(float level) int result; if(mode == METER_DB) { - result = pixels - 4 - (int)((level / min) * (pixels - 4)); - if(level == 0) result = pixels; + result = (int)(pixels * + (level - min) / + (max - min)); + if(level <= min) result = 0; } else { - result = (int)(level * (pixels - 4)); +// Not implemented anymore + result = 0; } return result; @@ -189,59 +192,77 @@ int BC_Meter::level_to_pixel(float level) void BC_Meter::get_divisions() { int i; - float j, j_step; - float division, division_step; - char string[1024]; + int j, j_step; + int division, division_step; + char string[BCTEXTLEN]; + char *new_string; - if(db_titles) - { - for(int i = 0; i < meter_titles; i++) delete [] db_titles[i]; - delete [] db_titles; - } - if(title_pixel) delete [] title_pixel; - meter_titles = labs((int)(min / 5)) + 1; - title_pixel = new int[meter_titles]; + db_titles.remove_all_objects(); + title_pixels.remove_all(); + tick_pixels.remove_all(); - if(use_titles) - { - db_titles = new char*[meter_titles]; - for(i = 0; i < meter_titles; i++) db_titles[i] = 0; - } + low_division = 0; + medium_division = 0; + high_division = pixels; - division = METER_MARGIN; - division_step = (float)(pixels - METER_MARGIN * 3) / (meter_titles - 1); - j = 0; // number for title - j_step = min / (meter_titles - 1); - - for(i = 0; i < meter_titles; i++) + int current_pixel; +// Create tick marks and titles in one pass + for(int current = min; current <= max; current++) { - - if(use_titles) + if(orientation == METER_VERT) { - sprintf(string, "%.0f", fabs(-j)); - db_titles[i] = new char[strlen(string) + 1]; - strcpy(db_titles[i], string); +// Create tick mark + current_pixel = (pixels - METER_MARGIN * 2 - 2) * + (current - min) / + (max - min) + 2; + tick_pixels.append(current_pixel); + +// Create titles in selected positions + if(current == min || + current == max || + current == 0 || + (current - min > 4 && max - current > 4 && !(current % 5))) + { + int title_pixel = (pixels - + METER_MARGIN * 2) * + (current - min) / + (max - min); + sprintf(string, "%d", labs(current)); + new_string = new char[strlen(string) + 1]; + strcpy(new_string, string); + db_titles.append(new_string); + title_pixels.append(title_pixel); + } + } + else + { + current_pixel = (pixels - METER_MARGIN * 2) * + (current - min) / + (max - min); + tick_pixels.append(current_pixel); +// Titles not supported for horizontal } - title_pixel[i] = (int)(division); - - division += division_step; - j += j_step; - } - -// Fix divisions at 5 and 20 - if(meter_titles > 4) - { - medium_division = pixels - title_pixel[1]; - low_division = pixels - title_pixel[4]; - } - else -// Boundary condition - { - medium_division = pixels - title_pixel[(meter_titles - 1) * 1 / 6]; - low_division = pixels - title_pixel[(meter_titles - 1) * 2 / 5]; +// Create color divisions + if(current == -20) + { + low_division = current_pixel; + } + else + if(current == -5) + { + medium_division = current_pixel; + } + else + if(current == 0) + { + high_division = current_pixel; + } } +// if(orientation == METER_VERT) +// printf("BC_Meter::get_divisions %d %d %d %d\n", +// low_division, medium_division, high_division, pixels); } void BC_Meter::draw_titles() @@ -254,9 +275,9 @@ void BC_Meter::draw_titles() { draw_top_background(parent_window, 0, 0, get_w(), get_title_w()); - for(int i = 0; i < meter_titles; i++) + for(int i = 0; i < db_titles.total; i++) { - draw_text(0, title_pixel[i], db_titles[i]); + draw_text(0, title_pixels.values[i], db_titles.values[i]); } flash(0, 0, get_w(), get_title_w()); @@ -266,50 +287,36 @@ void BC_Meter::draw_titles() { draw_top_background(parent_window, 0, 0, get_title_w(), get_h()); +// Titles + for(int i = 0; i < db_titles.total; i++) + { + int title_y = pixels - + title_pixels.values[i]; + if(i == 0) + title_y -= get_text_descent(SMALLFONT_3D); + else + if(i == db_titles.total - 1) + title_y += get_text_ascent(SMALLFONT_3D); + else + title_y += get_text_ascent(SMALLFONT_3D) / 2; - for(int i = 0; i < meter_titles; i++) + set_color(get_resources()->meter_font_color); + draw_text(0, + title_y, + db_titles.values[i]); + } + + for(int i = 0; i < tick_pixels.total; i++) { // Tick marks - if(i < meter_titles - 1) + int tick_y = pixels - tick_pixels.values[i] - METER_MARGIN; + set_color(get_resources()->meter_font_color); + draw_line(get_title_w() - 10 - 1, tick_y, get_title_w() - 1, tick_y); + if(get_resources()->meter_3d) { - for(int j = 0; j < 6; j++) - { - int y1; - int y2; - int y; - - y1 = title_pixel[i]; - y2 = title_pixel[i + 1]; - y = (int)((float)(y2 - y1) * j / 5 + 0.5) + y1; - - if(j == 0 || j == 5) - { - set_color(get_resources()->meter_font_color); - draw_line(get_title_w() - 10 - 1, y, get_title_w() - 1, y); - if(get_resources()->meter_3d) - { - set_color(BLACK); - draw_line(get_title_w() - 10, y + 1, get_title_w(), y + 1); - } - } - else - { - set_color(get_resources()->meter_font_color); - draw_line(get_title_w() - 5 - 1, y, get_title_w() - 1, y); - if(get_resources()->meter_3d) - { - set_color(BLACK); - draw_line(get_title_w() - 5, y + 1, get_title_w(), y + 1); - } - } - } + set_color(BLACK); + draw_line(get_title_w() - 10, tick_y + 1, get_title_w(), tick_y + 1); } - - set_color(get_resources()->meter_font_color); - if(i == 0) - draw_text(0, title_pixel[i] + get_text_height(SMALLFONT_3D) / 2, db_titles[i]); - else - draw_text(0, title_pixel[i] + get_text_height(SMALLFONT_3D) / 2, db_titles[i]); } flash(0, 0, get_title_w(), get_h()); @@ -374,7 +381,10 @@ void BC_Meter::draw_face() if(pixel < medium_division) image_number = METER_YELLOW; else + if(pixel < high_division) image_number = METER_RED; + else + image_number = METER_WHITE; } else { @@ -421,6 +431,9 @@ void BC_Meter::draw_face() else if(image_number == METER_YELLOW && pixel + in_span > medium_division) in_span = medium_division - pixel; + else + if(image_number == METER_RED && pixel + in_span > high_division) + in_span = high_division - pixel; // Clip length to regions if(pixel < left_pixel && pixel + in_span > left_pixel) @@ -450,6 +463,11 @@ void BC_Meter::draw_face() pixel += in_span; } + else + { +// Sanity check + break; + } } if(over_timer) @@ -470,6 +488,7 @@ void BC_Meter::draw_face() flash(0, 0, pixels, get_h()); else flash(x, 0, w, pixels); + flush(); } int BC_Meter::update(float new_value, int over) @@ -490,7 +509,8 @@ int BC_Meter::update(float new_value, int over) peak_timer = 0; } -//printf("BC_Meter::update %f\n", level); +// if(orientation == METER_HORIZ) +// printf("BC_Meter::update %f\n", level); if(over) over_timer = over_delay; // only draw if window is visible diff --git a/hvirtual/guicast/bcmeter.h b/hvirtual/guicast/bcmeter.h new file mode 100644 index 00000000..55376a47 --- /dev/null +++ b/hvirtual/guicast/bcmeter.h @@ -0,0 +1,87 @@ +#ifndef BCMETER_H +#define BCMETER_H + +#include "bcmeter.inc" +#include "bcsubwindow.h" +#include "units.h" + +#define METER_TYPES 2 + +#define METER_DB 0 +#define METER_INT 1 +#define METER_VERT 0 +#define METER_HORIZ 1 + +// Distance from subwindow border to top and bottom tick mark +#define METER_MARGIN 0 + +class BC_Meter : public BC_SubWindow +{ +public: + BC_Meter(int x, + int y, + int orientation, + int pixels, + int min, /* = -40, */ + int max, + int mode, /* = METER_DB, */ + int use_titles, /* = 0, */ +// Number of updates before over dissappears + long over_delay, /* = 150, */ +// Number of updates before peak updates + long peak_delay /* = 15 */); + virtual ~BC_Meter(); + + int initialize(); + void set_images(VFrame **data); + int set_delays(int over_delay, int peak_delay); + int region_pixel(int region); + int region_pixels(int region); + virtual int button_press_event(); + + static int get_title_w(); + static int get_meter_w(); + int update(float new_value, int over); + int reposition_window(int x, int y, int pixels); + int reset(); + int reset_over(); + int change_format(int mode, int min, int max); + +private: + void draw_titles(); + void draw_face(); + int level_to_pixel(float level); + void get_divisions(); + + BC_Pixmap *images[TOTAL_METER_IMAGES]; + int orientation; +// Number of pixels in the longest dimension + int pixels; + int low_division; + int medium_division; + int high_division; + int use_titles; +// Tick mark positions + ArrayList tick_pixels; +// Title positions + ArrayList title_pixels; + ArrayList db_titles; + float level, peak; + int mode; + DB db; + int peak_timer; + + + + + + + int peak_pixel, level_pixel, peak_pixel1, peak_pixel2; + int over_count, over_timer; + int min; + int max; + long over_delay; // Number of updates the over warning lasts. + long peak_delay; // Number of updates the peak lasts. +}; + +#endif diff --git a/hvirtual/guicast/bcmeter.inc b/hvirtual/guicast/bcmeter.inc new file mode 100644 index 00000000..0b3d311a --- /dev/null +++ b/hvirtual/guicast/bcmeter.inc @@ -0,0 +1,8 @@ +#ifndef BCMETER_INC +#define BCMETER_INC + +class BC_Meter; + +#define TOTAL_METER_IMAGES 6 + +#endif diff --git a/hvirtual/guicast/bcpixmap.C b/hvirtual/guicast/bcpixmap.C index 10c3e109..09a50fed 100644 --- a/hvirtual/guicast/bcpixmap.C +++ b/hvirtual/guicast/bcpixmap.C @@ -12,6 +12,9 @@ BC_Pixmap::BC_Pixmap(BC_WindowBase *parent_window, int icon_offset) { BC_Bitmap *opaque_bitmap, *alpha_bitmap, *mask_bitmap; + if(frame->get_color_model() != BC_RGBA8888 && + mode == PIXMAP_ALPHA) + mode = PIXMAP_OPAQUE; this->mode = mode; // Temporary bitmaps diff --git a/hvirtual/guicast/bcpopup.C b/hvirtual/guicast/bcpopup.C new file mode 100644 index 00000000..ed53a234 --- /dev/null +++ b/hvirtual/guicast/bcpopup.C @@ -0,0 +1,84 @@ +#include "bcpopup.h" + + +BC_FullScreen::BC_FullScreen(BC_WindowBase *parent_window, int w, int h, + int bg_color, + int vm_scale, + int hide, + BC_Pixmap *bg_pixmap) + : BC_WindowBase() +{ +#ifdef HAVE_LIBXXF86VM + if (vm_scale) + create_window(parent_window, + "Fullscreen", + 0, + 0, + w, + h, + w, + h, + 0, + parent_window->top_level->private_color, + hide, + bg_color, + NULL, + VIDMODE_SCALED_WINDOW, + bg_pixmap); + else +#endif + create_window(parent_window, + "Fullscreen", + 0, + 0, + w, + h, + w, + h, + 0, + parent_window->top_level->private_color, + hide, + bg_color, + NULL, + POPUP_WINDOW, + bg_pixmap); +} + + +BC_FullScreen::~BC_FullScreen() +{ +} + + +BC_Popup::BC_Popup(BC_WindowBase *parent_window, + int x, + int y, + int w, + int h, + int bg_color, + int hide, + BC_Pixmap *bg_pixmap) + : BC_WindowBase() +{ + create_window(parent_window, + "Popup", + x, + y, + w, + h, + w, + h, + 0, + parent_window->top_level->private_color, + hide, + bg_color, + NULL, + POPUP_WINDOW, + bg_pixmap); +} + + +BC_Popup::~BC_Popup() +{ +} + diff --git a/hvirtual/guicast/bcpopupmenu.C b/hvirtual/guicast/bcpopupmenu.C index 0f459346..2e5127dd 100644 --- a/hvirtual/guicast/bcpopupmenu.C +++ b/hvirtual/guicast/bcpopupmenu.C @@ -126,6 +126,10 @@ BC_MenuItem* BC_PopupMenu::get_item(int i) return menu_popup->menu_items.values[i]; } +#define MARGIN 10 +#define TRIANGLE_W 10 +#define TRIANGLE_H 10 + int BC_PopupMenu::draw_title() { if(!use_title) return 0; @@ -139,15 +143,11 @@ int BC_PopupMenu::draw_title() if(!icon) { set_font(MEDIUMFONT); - BC_WindowBase::draw_center_text(get_w() / 2, + BC_WindowBase::draw_center_text((get_w() - MARGIN - TRIANGLE_W) / 2, (int)((float)get_h() / 2 + get_text_ascent(MEDIUMFONT) / 2 - 2), text); } -#define MARGIN 10 -#define TRIANGLE_W 10 -#define TRIANGLE_H 10 - if(icon) { draw_pixmap(icon, @@ -187,8 +187,8 @@ int BC_PopupMenu::activate_menu() top_level->active_popup_menu = this; if(!use_title) { - x = top_level->get_abs_cursor_x() - get_w(); - y = top_level->get_abs_cursor_y() - get_h(); + x = top_level->get_abs_cursor_x(0) - get_w(); + y = top_level->get_abs_cursor_y(0) - get_h(); button_press_x = top_level->cursor_x; button_press_y = top_level->cursor_y; } diff --git a/hvirtual/guicast/bcpot.C b/hvirtual/guicast/bcpot.C index 62829b2e..bc380e46 100644 --- a/hvirtual/guicast/bcpot.C +++ b/hvirtual/guicast/bcpot.C @@ -68,7 +68,7 @@ int BC_Pot::draw() int x1, y1, x2, y2; draw_top_background(parent_window, 0, 0, get_w(), get_h()); draw_pixmap(images[status]); - set_color(BLACK); + set_color(get_resources()->pot_needle_color); angle_to_coords(x1, y1, x2, y2, percentage_to_angle(get_percentage())); draw_line(x1, y1, x2, y2); diff --git a/hvirtual/guicast/bcprogressbox.C b/hvirtual/guicast/bcprogressbox.C new file mode 100644 index 00000000..93cacca0 --- /dev/null +++ b/hvirtual/guicast/bcprogressbox.C @@ -0,0 +1,94 @@ +#include "bcbutton.h" +#include "bcprogress.h" +#include "bcprogressbox.h" +#include "bctitle.h" +#include "bcwindow.h" + +BC_ProgressBox::BC_ProgressBox(int x, int y, char *text, long length) + : Thread() +{ + set_synchronous(1); + pwindow = new BC_ProgressWindow(x, y); + pwindow->create_objects(text, length); + cancelled = 0; +} + +BC_ProgressBox::~BC_ProgressBox() +{ + delete pwindow; +} + +void BC_ProgressBox::run() +{ + int result = pwindow->run_window(); + if(result) cancelled = 1; +} + +int BC_ProgressBox::update(long position) +{ + if(!cancelled) + { + pwindow->lock_window("BC_ProgressBox::update"); + pwindow->bar->update(position); + pwindow->unlock_window(); + } + return cancelled; +} + +int BC_ProgressBox::update_title(char *title) +{ + pwindow->caption->update(title); + return cancelled; +} + +int BC_ProgressBox::update_length(long length) +{ + pwindow->bar->update_length(length); + return cancelled; +} + + +int BC_ProgressBox::is_cancelled() +{ + return cancelled; +} + +int BC_ProgressBox::stop_progress() +{ + pwindow->set_done(0); + Thread::join(); + return 0; +} + +void BC_ProgressBox::lock_window() +{ + pwindow->lock_window("BC_ProgressBox::lock_window"); +} + +void BC_ProgressBox::unlock_window() +{ + pwindow->unlock_window(); +} + + + +BC_ProgressWindow::BC_ProgressWindow(int x, int y) + : BC_Window("Progress", x, y, 340, 120, 0, 0, 0) +{ +} + +BC_ProgressWindow::~BC_ProgressWindow() +{ +} + +int BC_ProgressWindow::create_objects(char *text, long length) +{ + int x = 10, y = 10; + this->text = text; + add_tool(caption = new BC_Title(x, y, text)); + y += caption->get_h() + 20; + add_tool(bar = new BC_ProgressBar(x, y, get_w() - 20, length)); + y += 40; + add_tool(new BC_CancelButton(x, y)); + return 0; +} diff --git a/hvirtual/guicast/bcrepeater.C b/hvirtual/guicast/bcrepeater.C index 978ea6ec..bc95e0fc 100644 --- a/hvirtual/guicast/bcrepeater.C +++ b/hvirtual/guicast/bcrepeater.C @@ -1,4 +1,5 @@ #include "bcrepeater.h" +#include "bcsignals.h" #include "bcwindow.h" #include "condition.h" diff --git a/hvirtual/guicast/bcresources.C b/hvirtual/guicast/bcresources.C index 1fd9e9ad..b59d6cb4 100644 --- a/hvirtual/guicast/bcresources.C +++ b/hvirtual/guicast/bcresources.C @@ -40,8 +40,11 @@ VFrame* BC_Resources::type_to_icon[] = }; char* BC_Resources::small_font = N_("-*-helvetica-medium-r-normal-*-10-*"); +char* BC_Resources::small_font2 = N_("-*-helvetica-medium-r-normal-*-11-*"); char* BC_Resources::medium_font = N_("-*-helvetica-bold-r-normal-*-14-*"); +char* BC_Resources::medium_font2 = N_("-*-helvetica-bold-r-normal-*-14-*"); char* BC_Resources::large_font = N_("-*-helvetica-bold-r-normal-*-18-*"); +char* BC_Resources::large_font2 = N_("-*-helvetica-bold-r-normal-*-20-*"); char* BC_Resources::small_fontset = "6x12,*"; char* BC_Resources::medium_fontset = "7x14,*"; @@ -380,11 +383,13 @@ BC_Resources::BC_Resources() #include "images/xmeter_green_png.h" #include "images/xmeter_red_png.h" #include "images/xmeter_yellow_png.h" +#include "images/xmeter_white_png.h" #include "images/over_horiz_png.h" #include "images/ymeter_normal_png.h" #include "images/ymeter_green_png.h" #include "images/ymeter_red_png.h" #include "images/ymeter_yellow_png.h" +#include "images/ymeter_white_png.h" #include "images/over_vertical_png.h" static VFrame* default_xmeter_data[] = { @@ -392,6 +397,7 @@ BC_Resources::BC_Resources() new VFrame(xmeter_green_png), new VFrame(xmeter_red_png), new VFrame(xmeter_yellow_png), + new VFrame(xmeter_white_png), new VFrame(over_horiz_png) }; @@ -401,6 +407,7 @@ BC_Resources::BC_Resources() new VFrame(ymeter_green_png), new VFrame(ymeter_red_png), new VFrame(ymeter_yellow_png), + new VFrame(ymeter_white_png), new VFrame(over_vertical_png) }; @@ -468,7 +475,7 @@ BC_Resources::BC_Resources() }; hscroll_data = default_hscroll_data; vscroll_data = default_vscroll_data; - + scroll_minhandle = 10; @@ -481,6 +488,9 @@ BC_Resources::BC_Resources() bg_light1 = WHITE; bg_light2 = bg_color; + default_text_color = BLACK; + disabled_text_color = MEGREY; + button_light = WHITE; // bright corner button_highlighted = LTGREY; // face when highlighted button_down = MDGREY; // face when down @@ -545,6 +555,7 @@ BC_Resources::BC_Resources() pot_x1 = pot_images[0]->get_w() / 2 - 2; pot_y1 = pot_images[0]->get_h() / 2 - 2;; pot_r = pot_x1; + pot_needle_color = BLACK; progress_images = default_progress_images; diff --git a/hvirtual/guicast/bcresources.h b/hvirtual/guicast/bcresources.h index 72f1b5f5..4baa5a56 100644 --- a/hvirtual/guicast/bcresources.h +++ b/hvirtual/guicast/bcresources.h @@ -45,6 +45,8 @@ public: int bg_shadow2; int bg_light1; int bg_light2; + int default_text_color; + int disabled_text_color; // beveled box colors @@ -121,8 +123,10 @@ public: VFrame **horizontal_slider_data; VFrame **vertical_slider_data; VFrame **hscroll_data; - VFrame **vscroll_data; + VFrame **vscroll_data; +// Minimum pixels in handle + int scroll_minhandle; // Pans VFrame **pan_data; @@ -131,6 +135,7 @@ public: // Pots VFrame **pot_images; int pot_x1, pot_y1, pot_r; + int pot_needle_color; // Meters VFrame **xmeter_images, **ymeter_images; @@ -164,6 +169,10 @@ public: static char *large_font; static char *medium_font; static char *small_font; +// Backup of fonts in case the first choices don't exist + static char *large_font2; + static char *medium_font2; + static char *small_font2; static char *large_fontset; static char *medium_fontset; diff --git a/hvirtual/guicast/bcscrollbar.C b/hvirtual/guicast/bcscrollbar.C index 38b465cc..8e297a7d 100644 --- a/hvirtual/guicast/bcscrollbar.C +++ b/hvirtual/guicast/bcscrollbar.C @@ -341,9 +341,9 @@ void BC_ScrollBar::draw() void BC_ScrollBar::get_handle_dimensions() { - double total_pixels = pixels - get_arrow_pixels() * 2; + int total_pixels = pixels - + get_arrow_pixels() * 2; -//printf("BC_ScrollBar::get_handle_dimensions %ld\n", length); if(length > 0) { handle_pixels = (int64_t)((double)handlelength / @@ -351,16 +351,20 @@ void BC_ScrollBar::get_handle_dimensions() total_pixels + .5); + if(handle_pixels < get_resources()->scroll_minhandle) + handle_pixels = get_resources()->scroll_minhandle; - handle_pixel = (int64_t)((double)position / length * total_pixels + .5) + + + handle_pixel = (int64_t)((double)position / + length * + total_pixels + .5) + get_arrow_pixels(); - if(handle_pixels < MINHANDLE) handle_pixels = MINHANDLE; // Handle pixels is beyond minimum right position. Clamp it. - if(handle_pixel > pixels - get_arrow_pixels() - MINHANDLE) + if(handle_pixel > pixels - get_arrow_pixels() - get_resources()->scroll_minhandle) { - handle_pixel = pixels - get_arrow_pixels() - MINHANDLE; - handle_pixels = MINHANDLE; + handle_pixel = pixels - get_arrow_pixels() - get_resources()->scroll_minhandle; + handle_pixels = get_resources()->scroll_minhandle; } // Shrink handle_pixels until it fits inside scrollbar if(handle_pixel > pixels - get_arrow_pixels() - handle_pixels) @@ -372,18 +376,21 @@ void BC_ScrollBar::get_handle_dimensions() handle_pixels = handle_pixel + handle_pixels - get_arrow_pixels(); handle_pixel = get_arrow_pixels(); } - if(handle_pixels < MINHANDLE) handle_pixels = MINHANDLE; + if(handle_pixels < get_resources()->scroll_minhandle) handle_pixels = get_resources()->scroll_minhandle; } else { - handle_pixels = (int)(total_pixels); + handle_pixels = total_pixels; handle_pixel = get_arrow_pixels(); } CLAMP(handle_pixel, get_arrow_pixels(), (int)(pixels - get_arrow_pixels())); - CLAMP(handle_pixels, 0, (int)total_pixels); + CLAMP(handle_pixels, 0, total_pixels); -//printf("BC_ScrollBar::get_handle_dimensions %d %d %f\n", handle_pixel, handle_pixels, total_pixels); +// printf("BC_ScrollBar::get_handle_dimensions %d %d %d\n", +// total_pixels, +// handle_pixel, +// handle_pixels); } int BC_ScrollBar::cursor_enter_event() diff --git a/hvirtual/guicast/bcscrollbar.h b/hvirtual/guicast/bcscrollbar.h index 3283cab4..56964f4a 100644 --- a/hvirtual/guicast/bcscrollbar.h +++ b/hvirtual/guicast/bcscrollbar.h @@ -35,7 +35,6 @@ -#define MINHANDLE 10 class BC_ScrollBar : public BC_SubWindow { diff --git a/hvirtual/guicast/bcsignals.C b/hvirtual/guicast/bcsignals.C index 5c57e7ae..5009e8a4 100644 --- a/hvirtual/guicast/bcsignals.C +++ b/hvirtual/guicast/bcsignals.C @@ -6,24 +6,18 @@ BC_Signals* BC_Signals::global_signals = 0; static int signal_done = 0; +static int table_id = 0; - -// Need to use structs to avoid the memory manager -typedef struct -{ - void *ptr; - char *title; - char *location; - int is_lock; -} bc_locktrace_t; - -static bc_locktrace_t* new_bc_locktrace(void *ptr, char *title, char *location, int is_lock) +static bc_locktrace_t* new_bc_locktrace(void *ptr, + char *title, + char *location) { bc_locktrace_t *result = (bc_locktrace_t*)malloc(sizeof(bc_locktrace_t)); result->ptr = ptr; result->title = title; result->location = location; - result->is_lock = is_lock; + result->is_owner = 0; + result->id = table_id++; return result; } @@ -160,7 +154,7 @@ static void signal_entry(int signum) pthread_mutex_unlock(handler_lock); - printf("signal_entry: got %s my pid=%d execution table %d:\n", + printf("signal_entry: got %s my pid=%d execution table size=%d:\n", signal_titles[signum], getpid(), execution_table.size); @@ -194,15 +188,15 @@ void BC_Signals::dump_traces() void BC_Signals::dump_locks() { // Dump lock table - printf("signal_entry: lock table %d\n", lock_table.size); + printf("signal_entry: lock table size=%d\n", lock_table.size); for(int i = 0; i < lock_table.size; i++) { bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i]; - if(table->is_lock) - printf(" %p %s %s\n", - table->ptr, - table->title, - table->location); + printf(" %p %s %s %s\n", + table->ptr, + table->title, + table->location, + table->is_owner ? "*" : ""); } } @@ -211,7 +205,7 @@ void BC_Signals::dump_buffers() { pthread_mutex_lock(lock); // Dump buffer table - printf("BC_Signals::dump_buffers: buffer table %d\n", memory_table.size); + printf("BC_Signals::dump_buffers: buffer table size=%d\n", memory_table.size); for(int i = 0; i < memory_table.size; i++) { bc_buffertrace_t *entry = (bc_buffertrace_t*)memory_table.values[i]; @@ -305,64 +299,99 @@ void BC_Signals::delete_traces() pthread_mutex_unlock(lock); } -void BC_Signals::set_lock(void *ptr, char *title, char *location) +#define TOTAL_LOCKS 100 + +int BC_Signals::set_lock(void *ptr, + char *title, + char *location) +{ + if(!global_signals) return 0; + bc_locktrace_t *table = 0; + int id_return = 0; + + pthread_mutex_lock(lock); + if(lock_table.size >= TOTAL_LOCKS) + clear_table(&lock_table, 0); + +// Put new lock entry + table = new_bc_locktrace(ptr, title, location); + append_table(&lock_table, table); + id_return = table->id; + + pthread_mutex_unlock(lock); + return id_return; +} + +void BC_Signals::set_lock2(int table_id) { if(!global_signals) return; + bc_locktrace_t *table = 0; pthread_mutex_lock(lock); -// Take off previous unlock entry. Without this, our table explodes. - int got_it = 0; - for(int i = 0; i < lock_table.size; i++) + for(int i = lock_table.size - 1; i >= 0; i--) { - bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i]; - if(table->ptr == ptr && !table->is_lock) + table = (bc_locktrace_t*)lock_table.values[i]; +// Got it. Hasn't been unlocked/deleted yet. + if(table->id == table_id) { - clear_table_entry(&lock_table, i, 1); - got_it = 1; - break; + table->is_owner = 1; + pthread_mutex_unlock(lock); + return; } } + pthread_mutex_unlock(lock); +} -// Put new lock entry - if(!got_it) +void BC_Signals::unset_lock2(int table_id) +{ + if(!global_signals) return; + + bc_locktrace_t *table = 0; + pthread_mutex_lock(lock); + for(int i = lock_table.size - 1; i >= 0; i--) { - bc_locktrace_t *table = new_bc_locktrace(ptr, title, location, 1); - append_table(&lock_table, table); + table = (bc_locktrace_t*)lock_table.values[i]; + if(table->id == table_id) + { + clear_table_entry(&lock_table, i, 1); + pthread_mutex_unlock(lock); + return; + } } - pthread_mutex_unlock(lock); } void BC_Signals::unset_lock(void *ptr) { if(!global_signals) return; + + bc_locktrace_t *table = 0; pthread_mutex_lock(lock); -// Take off previous lock entry - int got_it = 0; + +// Take off currently held entry for(int i = 0; i < lock_table.size; i++) { - bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i]; - if(table->ptr == ptr && table->is_lock) + table = (bc_locktrace_t*)lock_table.values[i]; + if(table->ptr == ptr) { - clear_table_entry(&lock_table, i, 1); - break; + if(table->is_owner) + { + clear_table_entry(&lock_table, i, 1); + pthread_mutex_unlock(lock); + return; + } } } -// Put new unlock entry - if(!got_it) - { - bc_locktrace_t *table = new_bc_locktrace(ptr, 0, 0, 0); - append_table(&lock_table, table); - } + pthread_mutex_unlock(lock); } + void BC_Signals::unset_all_locks(void *ptr) { if(!global_signals) return; pthread_mutex_lock(lock); // Take off previous lock entry - int got_it = 0; for(int i = 0; i < lock_table.size; i++) { bc_locktrace_t *table = (bc_locktrace_t*)lock_table.values[i]; diff --git a/hvirtual/guicast/bcsignals.h b/hvirtual/guicast/bcsignals.h index 41e93179..1fbdc9d0 100644 --- a/hvirtual/guicast/bcsignals.h +++ b/hvirtual/guicast/bcsignals.h @@ -12,10 +12,26 @@ // BC_Signals must be initialized at the start of every program using // debugging. #define ENABLE_TRACE -#define TRACE_LOCKS +//#define TRACE_LOCKS +#ifdef TRACE_LOCKS +#undef TRACE_LOCKS +#endif //#define TRACE_MEMORY +// Need to use structs to avoid the memory manager. +// One of these tables is created every time someone locks a lock. +// After successfully locking, the table is flagged as being the owner of the lock. +// In the unlock function, the table flagged as the owner of the lock is deleted. +typedef struct +{ + void *ptr; + char *title; + char *location; + int is_owner; + int id; +} bc_locktrace_t; + class BC_Signals { public: @@ -43,14 +59,25 @@ public: #ifdef TRACE_LOCKS -#define SET_LOCK(ptr, title, location) BC_Signals::set_lock(ptr, title, location); +// Before user acquires +#define SET_LOCK(ptr, title, location) int table_id = BC_Signals::set_lock(ptr, title, location); +// After successful acquisition +#define SET_LOCK2 BC_Signals::set_lock2(table_id); +// Release current lock table after failing to acquire +#define UNSET_LOCK2 BC_Signals::unset_lock2(table_id); + +// Release current owner of lock #define UNSET_LOCK(ptr) BC_Signals::unset_lock(ptr); + +// Delete a lock #define UNSET_ALL_LOCKS(ptr) BC_Signals::unset_all_locks(ptr); #else #define SET_LOCK(ptr, title, location) ; +#define SET_LOCK2 ; #define UNSET_LOCK(ptr) ; +#define UNSET_LOCK2 ; #define UNSET_ALL_LOCKS(ptr) ; #endif @@ -84,7 +111,9 @@ public: - static void set_lock(void *ptr, char *title, char *location); + static int set_lock(void *ptr, char *title, char *location); + static void set_lock2(int table_id); + static void unset_lock2(int table_id); static void unset_lock(void *ptr); // Used in lock destructors so takes away all references static void unset_all_locks(void *ptr); diff --git a/hvirtual/guicast/bcsubwindow.C b/hvirtual/guicast/bcsubwindow.C new file mode 100644 index 00000000..c088a7c9 --- /dev/null +++ b/hvirtual/guicast/bcsubwindow.C @@ -0,0 +1,52 @@ +#include "bcsubwindow.h" + + + +BC_SubWindow::BC_SubWindow(int x, int y, int w, int h, int bg_color) + : BC_WindowBase() +{ + this->x = x; + this->y = y; + this->w = w; + this->h = h; + this->bg_color = bg_color; +//printf("BC_SubWindow::BC_SubWindow 1\n"); +} + +BC_SubWindow::~BC_SubWindow() +{ +} + +int BC_SubWindow::initialize() +{ + create_window(parent_window, + "Sub Window", + x, + y, + w, + h, + 0, + 0, + 0, + 0, + 0, + bg_color, + NULL, + SUB_WINDOW, + 0); + return 0; +} + + + + + + +BC_SubWindowList::BC_SubWindowList() + : ArrayList() +{ +} + +BC_SubWindowList::~BC_SubWindowList() +{ +} diff --git a/hvirtual/guicast/bctextbox.C b/hvirtual/guicast/bctextbox.C index f91a5b43..628075d5 100644 --- a/hvirtual/guicast/bctextbox.C +++ b/hvirtual/guicast/bctextbox.C @@ -173,7 +173,6 @@ int BC_TextBox::update(float value) sprintf(string, "%f", value); char *ptr = strchr(string, '.'); -//printf("BC_TextBox::update 1 %d\n", precision); if(ptr) ptr[precision + 1] = 0; update(string); @@ -199,6 +198,11 @@ void BC_TextBox::enable() } } +int BC_TextBox::get_enabled() +{ + return enabled; +} + int BC_TextBox::pixels_to_rows(BC_WindowBase *window, int font, int pixels) { return (pixels - 4) / @@ -408,6 +412,7 @@ void BC_TextBox::draw() // Border draw_border(); flash(); + flush(); } int BC_TextBox::focus_in_event() @@ -433,6 +438,7 @@ int BC_TextBox::cursor_enter_event() highlighted = 1; draw_border(); flash(); + flush(); } } return 0; @@ -446,6 +452,7 @@ int BC_TextBox::cursor_leave_event() draw_border(); hide_tooltip(); flash(); + flush(); } return 0; } @@ -606,6 +613,7 @@ int BC_TextBox::repeat_event(int64_t duration) } draw_cursor(); flash(); + flush(); result = 1; } return result; diff --git a/hvirtual/guicast/bctextbox.h b/hvirtual/guicast/bctextbox.h index 683723c6..adcb2b49 100644 --- a/hvirtual/guicast/bctextbox.h +++ b/hvirtual/guicast/bctextbox.h @@ -53,6 +53,7 @@ public: int update(float value); void disable(); void enable(); + int get_enabled(); int initialize(); diff --git a/hvirtual/guicast/bctheme.C b/hvirtual/guicast/bctheme.C index 14ad0bb0..bc88e6d6 100644 --- a/hvirtual/guicast/bctheme.C +++ b/hvirtual/guicast/bctheme.C @@ -1,7 +1,6 @@ #include "bctheme.h" #include "bcwindowbase.h" #include "clip.h" -#include "filesystem.h" #include "language.h" #include "vframe.h" @@ -11,96 +10,24 @@ BC_Theme::BC_Theme() { - char *path_env = getenv("PATH"); - char executable_name[BCTEXTLEN]; - char *path_ptr = path_env; - -// Get location of executable - FILE *fd = fopen("/proc/self/cmdline", "r"); - if(!fd) - { - perror(_("BC_Theme::BC_Theme: can't open /proc/self/cmdline.\n")); - return; - } - else - { - fread(executable_name, 1, BCTEXTLEN, fd); - strcpy(path, executable_name); - fclose(fd); - } - - int done = 0; - fd = 0; - -// Search path environment for executable - do - { - FileSystem fs; -// Ignore directories - if(!fs.is_dir(path)) - fd = 0; - else - fd = fopen(path, "r"); - - - if(!fd) - { -// Get next entry out of path_env - while(*path_ptr) - { - if(*path_ptr != ':') - break; - else - path_ptr++; - } - - if(!*path_ptr) break; - - char *new_ptr = path; - while(*path_ptr) - { - if(*path_ptr == ':') - break; - else - *new_ptr++ = *path_ptr++; - } - - *new_ptr = 0; - if(new_ptr - path > 0 && *(new_ptr - 1) != '/') - { - *new_ptr++ = '/'; - *new_ptr = 0; - } - strcat(path, executable_name); - } - else - { - fclose(fd); - done = 1; - } - }while(!done); - - strcpy(default_path, path); - data_buffer = 0; - contents_buffer = 0; + data_ptr = 0; + contents_ptr = 0; last_image = 0; + last_pointer = 0; } BC_Theme::~BC_Theme() { image_sets.remove_all_objects(); - if(data_buffer) delete [] data_buffer; - if(contents_buffer) delete [] contents_buffer; } void BC_Theme::dump() { - printf("BC_Theme::dump 1 image_sets=%d path=%s contents=%d\n", + printf("BC_Theme::dump 1 image_sets=%d contents=%d\n", image_sets.total, - path, contents.total); for(int i = 0; i < contents.total; i++) - printf(" %s %x\n", contents.values[i], offsets.values[i]); + printf(" %s %p\n", contents.values[i], pointers.values[i]); } BC_Resources* BC_Theme::get_resources() @@ -346,97 +273,45 @@ void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2) } } -void BC_Theme::set_path(char *path) +void BC_Theme::set_data(unsigned char *ptr) { - strcpy(this->path, path); -} - -void BC_Theme::unset_path() -{ - strcpy(this->path, default_path); - if(data_buffer) delete [] data_buffer; - if(contents_buffer) delete [] contents_buffer; - data_buffer = 0; - contents_buffer = 0; - last_image = 0; - contents.remove_all(); - offsets.remove_all(); - used.remove_all(); -} + contents_ptr = (char*)(ptr + sizeof(int)); + int contents_size = *(int*)ptr - sizeof(int); + data_ptr = contents_ptr + contents_size; -unsigned char* BC_Theme::get_image_data(char *title) -{ -// Read contents - if(!data_buffer) + for(int i = 0; i < contents_size; ) { - FileSystem fs; - if(!fs.is_dir(path)) - { - fprintf(stderr, _("Theme::get_image: %s is a directory.\n"), path); - return 0; - } - FILE *fd = fopen(path, "r"); - int result = 0; - - if(!fd) - { - fprintf(stderr, _("Theme::get_image: %s when opening %s\n"), strerror(errno), path); - } - int data_offset, contents_offset; - int total_bytes; - int data_size; - int contents_size; - - if(fseek(fd, -8, SEEK_END) < 0) - { - fprintf(stderr, _("BC_Theme::get_image_data fseek %s\n"), strerror(errno)); - return 0; - } - total_bytes = ftell(fd); - if(fread(&data_offset, 1, 4, fd) != 4) + used.append(0); + contents.append(contents_ptr + i); + while(contents_ptr[i] && i < contents_size) + i++; + if(i < contents_size) { - fprintf(stderr, _("BC_Theme::get_image_data fread 1 %s\n"), strerror(errno)); - return 0; + i++; + pointers.append((unsigned char*)data_ptr + + *(unsigned int*)(contents_ptr + i)); + i += 4; } - if(fread(&contents_offset, 1, 4, fd) != 4) + else { - fprintf(stderr, _("BC_Theme::get_image_data fread 2 %s\n"), strerror(errno)); - return 0; + pointers.append((unsigned char*)data_ptr); + break; } + } +} - - fseek(fd, data_offset, SEEK_SET); - data_size = contents_offset - data_offset; - data_buffer = new char[data_size]; - fread(data_buffer, 1, data_size, fd); - - fseek(fd, contents_offset, SEEK_SET); - contents_size = total_bytes - contents_offset; - contents_buffer = new char[contents_size]; - fread(contents_buffer, 1, contents_size, fd); - - char *start_of_title = contents_buffer; - for(int i = 0; i < contents_size; ) - { - if(contents_buffer[i] == 0) - { - contents.append(start_of_title); - i++; - offsets.append(*(int*)(contents_buffer + i)); - i += 4; - start_of_title = contents_buffer + i; - used.append(0); - } - else - i++; - } - fclose(fd); +unsigned char* BC_Theme::get_image_data(char *title) +{ + if(!data_ptr) + { + fprintf(stderr, "BC_Theme::get_image_data: no data set\n"); + return 0; } // Image is the same as the last one if(last_image && !strcasecmp(last_image, title)) { - return (unsigned char*)(data_buffer + last_offset); + return last_pointer; } else // Search for image anew. @@ -444,10 +319,10 @@ unsigned char* BC_Theme::get_image_data(char *title) { if(!strcasecmp(contents.values[i], title)) { - last_offset = offsets.values[i]; + last_pointer = pointers.values[i]; last_image = contents.values[i]; used.values[i] = 1; - return (unsigned char*)(data_buffer + offsets.values[i]); + return pointers.values[i]; } } diff --git a/hvirtual/guicast/bctheme.h b/hvirtual/guicast/bctheme.h index 376e19a5..a0b6b257 100644 --- a/hvirtual/guicast/bctheme.h +++ b/hvirtual/guicast/bctheme.h @@ -18,13 +18,9 @@ public: BC_Theme(); virtual ~BC_Theme(); -// Must set path of resource file before loading first image. -// Path defaults to executable path. - void set_path(char *path); - -// Reverts the path to the executable path. Useful for base classes -// which need to fill unset images with defaults after they've been created. - void unset_path(); +// Set pointer to binary object containing images and contents. +// Immediately loads the contents from the object. + void set_data(unsigned char *ptr); VFrame** new_button(char *overlay_path, char *up_path, @@ -88,13 +84,13 @@ private: char default_path[BCTEXTLEN]; // Compressed images are loaded in here. - char *data_buffer; - char *contents_buffer; + char *data_ptr; + char *contents_ptr; ArrayList contents; - ArrayList offsets; + ArrayList pointers; ArrayList used; char *last_image; - int last_offset; + unsigned char *last_pointer; }; class BC_ThemeSet diff --git a/hvirtual/guicast/bctitle.C b/hvirtual/guicast/bctitle.C index e60cef61..0734a7d6 100644 --- a/hvirtual/guicast/bctitle.C +++ b/hvirtual/guicast/bctitle.C @@ -1,3 +1,4 @@ +#include "bcresources.h" #include "bctitle.h" #include #include @@ -12,7 +13,10 @@ BC_Title::BC_Title(int x, : BC_SubWindow(x, y, -1, -1, -1) { this->font = font; - this->color = color; + if(color < 0) + this->color = get_resources()->default_text_color; + else + this->color = color; this->centered = centered; this->fixed_w = fixed_w; strcpy(this->text, text); diff --git a/hvirtual/guicast/bctitle.h b/hvirtual/guicast/bctitle.h index b7873d1c..4802d16c 100644 --- a/hvirtual/guicast/bctitle.h +++ b/hvirtual/guicast/bctitle.h @@ -12,7 +12,7 @@ public: int y, char *text, int font = MEDIUMFONT, - int color = BLACK, + int color = -1, int centered = 0, int fixed_w = 0); virtual ~BC_Title(); diff --git a/hvirtual/guicast/bctoggle.C b/hvirtual/guicast/bctoggle.C index db34c87c..dface830 100644 --- a/hvirtual/guicast/bctoggle.C +++ b/hvirtual/guicast/bctoggle.C @@ -23,9 +23,14 @@ BC_Toggle::BC_Toggle(int x, int y, strcpy(this->caption, caption); this->bottom_justify = bottom_justify; this->font = font; - this->color = color; + if(color >= 0) + this->color = color; + else + this->color = get_resources()->default_text_color; select_drag = 0; enabled = 1; + underline = -1; + is_radial = 0; } @@ -88,6 +93,12 @@ int BC_Toggle::set_images(VFrame **data) return 0; } +void BC_Toggle::set_underline(int number) +{ + this->underline = number; +} + + void BC_Toggle::set_select_drag(int value) { this->select_drag = value; @@ -112,10 +123,22 @@ int BC_Toggle::draw_face() set_color(MEGREY); set_font(font); draw_text(text_x, text_line, caption); + + + if(underline >= 0) + { + int x = text_x; + int y = text_line + 1; + int x1 = get_text_width(current_font, caption, underline) + x; + int x2 = get_text_width(current_font, caption, underline + 1) + x; + draw_line(x1, y, x2, y); + draw_line(x1, y + 1, (x2 + x1) / 2, y + 1); + } } draw_pixmap(images[status]); flash(); + flush(); return 0; } @@ -168,12 +191,13 @@ int BC_Toggle::cursor_enter_event() int BC_Toggle::cursor_leave_event() { hide_tooltip(); - if(!value) + if(!value && status == BC_Toggle::TOGGLE_UPHI) { status = BC_Toggle::TOGGLE_UP; draw_face(); } else + if(status == BC_Toggle::TOGGLE_CHECKEDHI) { status = BC_Toggle::TOGGLE_CHECKED; draw_face(); @@ -187,7 +211,20 @@ int BC_Toggle::button_press_event() if(top_level->event_win == win && get_buttonpress() == 1 && enabled) { status = BC_Toggle::TOGGLE_DOWN; - top_level->toggle_value = !this->value; + +// Change value now for select drag mode. +// Radial always goes to 1 + if(select_drag) + { + if(!is_radial) + value = !value; + else + value = 1; + top_level->toggle_drag = 1; + top_level->toggle_value = value; + handle_event(); + } + draw_face(); return 1; } @@ -196,35 +233,55 @@ int BC_Toggle::button_press_event() int BC_Toggle::button_release_event() { + int result = 0; hide_tooltip(); - if(top_level->event_win == win && status == BC_Toggle::TOGGLE_DOWN) + + if(top_level->event_win == win) { - if((!value && !select_drag) || (value && select_drag)) +// Keep value regardless of status if drag mode. + if(select_drag) { - status = BC_Toggle::TOGGLE_CHECKEDHI; - value = 1; + if(value) + status = BC_Toggle::TOGGLE_CHECKEDHI; + else + status = BC_Toggle::TOGGLE_UPHI; + top_level->toggle_drag = 0; } else +// Change value only if button down for default mode. + if(status == BC_Toggle::TOGGLE_DOWN) { - status = BC_Toggle::TOGGLE_UPHI; - value = 0; +// Radial always goes to 1. + if(!value || is_radial) + { + status = BC_Toggle::TOGGLE_CHECKEDHI; + value = 1; + } + else + { + status = BC_Toggle::TOGGLE_UPHI; + value = 0; + } + result = handle_event(); } draw_face(); - return handle_event(); + return result; } return 0; } int BC_Toggle::cursor_motion_event() { - if(select_drag) return 0; if(top_level->button_down && top_level->event_win == win && !cursor_inside()) { if(status == BC_Toggle::TOGGLE_DOWN) { - status = BC_Toggle::TOGGLE_UP; + if(value) + status = BC_Toggle::TOGGLE_CHECKED; + else + status = BC_Toggle::TOGGLE_UP; draw_face(); } else @@ -306,6 +363,7 @@ BC_Radial::BC_Radial(int x, font, color) { + is_radial = 1; } BC_CheckBox::BC_CheckBox(int x, diff --git a/hvirtual/guicast/bctoggle.h b/hvirtual/guicast/bctoggle.h index 0c116a6f..c1dd0f28 100644 --- a/hvirtual/guicast/bctoggle.h +++ b/hvirtual/guicast/bctoggle.h @@ -17,7 +17,7 @@ public: char *caption = "", int bottom_justify = 0, int font = MEDIUMFONT, - int color = BLACK); + int color = -1); virtual ~BC_Toggle(); virtual int handle_event() { return 0; }; @@ -32,6 +32,7 @@ public: int initialize(); int set_images(VFrame **data); + void set_underline(int number); int cursor_enter_event(); int cursor_leave_event(); // In select drag mode these 3 need to be overridden and called back to. @@ -69,6 +70,8 @@ public: int color; int select_drag; int enabled; + int underline; + int is_radial; }; class BC_Radial : public BC_Toggle @@ -79,7 +82,7 @@ public: int value, char *caption = "", int font = MEDIUMFONT, - int color = BLACK); + int color = -1); }; class BC_CheckBox : public BC_Toggle @@ -90,13 +93,13 @@ public: int value, char *caption = "", int font = MEDIUMFONT, - int color = BLACK); + int color = -1); BC_CheckBox(int x, int y, int *value, char *caption = "", int font = MEDIUMFONT, - int color = BLACK); + int color = -1); virtual int handle_event(); int *value; @@ -109,7 +112,7 @@ public: int y, int value, int font = MEDIUMFONT, - int color = BLACK); + int color = -1); }; #endif diff --git a/hvirtual/guicast/bctumble.C b/hvirtual/guicast/bctumble.C index 3339a57b..db3bac4f 100644 --- a/hvirtual/guicast/bctumble.C +++ b/hvirtual/guicast/bctumble.C @@ -325,6 +325,6 @@ void BC_FTumbler::set_boundaries(float min, float max) void BC_FTumbler::set_increment(float value) { - this->increment = increment; + this->increment = value; } diff --git a/hvirtual/guicast/bcwindowbase.C b/hvirtual/guicast/bcwindowbase.C index fd23330e..cc9ab825 100644 --- a/hvirtual/guicast/bcwindowbase.C +++ b/hvirtual/guicast/bcwindowbase.C @@ -10,6 +10,7 @@ #include "bcsignals.h" #include "bcsubwindow.h" #include "bcwindowbase.h" +#include "bcwindowevents.h" #include "colormodels.h" #include "colors.h" #include "condition.h" @@ -38,71 +39,10 @@ BC_ResizeCall::BC_ResizeCall(int w, int h) } -BC_WindowTree::BC_WindowTree(Display* display, - BC_WindowTree *parent_tree, - Window root_win) -{ - Window temp_win; - Window *stack; - int stack_total; - this->display = display; - this->win = root_win; - this->parent_tree = parent_tree; - XQueryTree(display, - root_win, - &temp_win, - &temp_win, &stack, - (unsigned int*)&stack_total); - - for(int i = 0; i < stack_total; i++) - { - windows.append(new BC_WindowTree(display, this, stack[i])); - } - XFree(stack); -} - -BC_WindowTree::~BC_WindowTree() -{ - windows.remove_all_objects(); -} - -BC_WindowTree* BC_WindowTree::get_node(Window win) -{ -//printf("BC_WindowTree::get_node 1\n"); - for(int i = 0; i < windows.total; i++) - { - BC_WindowTree *result = 0; -//printf("BC_WindowTree::get_node 2\n"); - if(windows.values[i]->win == win) - return windows.values[i]; - else - { -//printf("BC_WindowTree::get_node 3\n"); - result = windows.values[i]->get_node(win); -//printf("BC_WindowTree::get_node 4\n"); - if(result) return result; - } - } -} -void BC_WindowTree::dump(int indent, Window caller_win) -{ - XWindowAttributes attr; - XGetWindowAttributes(display, - win, - &attr); - for(int i = 0; i < indent; i++) - printf(" "); - printf("x=%d y=%d w=%d h=%d win=%x subwindows=%d ", - attr.x, attr.y, attr.width, attr.height, win, windows.total); - if(caller_win == win) printf("**"); - printf("\n"); - for(int i = 0; i < windows.total; i++) - windows.values[i]->dump(indent + 1, caller_win); -} @@ -110,7 +50,6 @@ void BC_WindowTree::dump(int indent, Window caller_win) Mutex BC_WindowBase::opengl_lock; BC_Resources BC_WindowBase::resources; -BC_WindowTree* BC_WindowBase::window_tree = 0; BC_WindowBase::BC_WindowBase() { @@ -128,7 +67,6 @@ BC_WindowBase::~BC_WindowBase() } #endif -//printf("BC_WindowBase::~BC_WindowBase 1\n"); hide_tooltip(); if(window_type != MAIN_WINDOW) { @@ -137,7 +75,6 @@ BC_WindowBase::~BC_WindowBase() if(top_level->active_subwindow == this) top_level->active_subwindow = 0; parent_window->subwindows->remove(this); } -//printf("BC_WindowBase::~BC_WindowBase 2\n"); if(subwindows) { @@ -145,46 +82,46 @@ BC_WindowBase::~BC_WindowBase() { delete subwindows->values[i]; } -//printf("BC_WindowBase::~BC_WindowBase 2.5 %p\n", subwindows); delete subwindows; } -//printf("BC_WindowBase::~BC_WindowBase 3\n"); XFreePixmap(top_level->display, pixmap); XDestroyWindow(top_level->display, win); -//printf("BC_WindowBase::~BC_WindowBase 4\n"); if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap; if(icon_pixmap) delete icon_pixmap; - if (temp_bitmap) delete temp_bitmap; -//printf("BC_WindowBase::~BC_WindowBase 5\n"); + if(temp_bitmap) delete temp_bitmap; if(window_type == MAIN_WINDOW) { - XFreeGC(top_level->display, gc); + XFreeGC(display, gc); #ifdef HAVE_XFT - if(top_level->largefont_xft) - XftFontClose (top_level->display, (XftFont*)top_level->largefont_xft); - if(top_level->mediumfont_xft) - XftFontClose (top_level->display, (XftFont*)top_level->mediumfont_xft); - if(top_level->smallfont_xft) - XftFontClose (top_level->display, (XftFont*)top_level->smallfont_xft); + if(largefont_xft) + XftFontClose (display, (XftFont*)largefont_xft); + if(mediumfont_xft) + XftFontClose (display, (XftFont*)mediumfont_xft); + if(smallfont_xft) + XftFontClose (display, (XftFont*)smallfont_xft); #endif flush(); // Can't close display if another thread is waiting for events - XCloseDisplay(top_level->display); + XCloseDisplay(display); +// XCloseDisplay(event_display); clipboard->stop_clipboard(); delete clipboard; - - } -//printf("BC_WindowBase::~BC_WindowBase 6\n"); + else + { + flush(); + } resize_history.remove_all_objects(); + common_events.remove_all_objects(); + delete event_lock; + delete event_condition; UNSET_ALL_LOCKS(this) -//printf("BC_WindowBase::~BC_WindowBase 10\n"); } int BC_WindowBase::initialize() @@ -233,6 +170,7 @@ int BC_WindowBase::initialize() tooltip_on = 0; temp_cursor = 0; toggle_value = 0; + toggle_drag = 0; has_focus = 0; #ifdef HAVE_LIBXXF86VM vm_switched = 0; @@ -241,6 +179,10 @@ int BC_WindowBase::initialize() largefont_xft = 0; mediumfont_xft = 0; smallfont_xft = 0; +// Need these right away since put_event is called before run_window sometimes. + event_lock = new Mutex("BC_WindowBase::event_lock"); + event_condition = new Condition(0, "BC_WindowBase::event_condition"); + event_thread = 0; return 0; } @@ -316,10 +258,11 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, // get the display connection display = init_display(display_name); +// event_display = init_display(display_name); // Fudge window placement - root_w = get_root_w(1); - root_h = get_root_h(); + root_w = get_root_w(1, 0); + root_h = get_root_h(0); if(this->x + this->w > root_w) this->x = root_w - this->w; if(this->y + this->h > root_h) this->y = root_h - this->h; if(this->x < 0) this->x = 0; @@ -539,7 +482,7 @@ Display* BC_WindowBase::init_display(char *display_name) if(display_name && display_name[0] == 0) display_name = NULL; if((display = XOpenDisplay(display_name)) == NULL) { - printf("BC_WindowBase::create_window: cannot connect to X server %s\n", + printf("BC_WindowBase::init_display: cannot connect to X server %s\n", display_name); if(getenv("DISPLAY") == NULL) { @@ -551,7 +494,7 @@ Display* BC_WindowBase::init_display(char *display_name) { if((display = XOpenDisplay(0)) == NULL) { - printf("BC_WindowBase::create_window: cannot connect to default X server.\n"); + printf("BC_WindowBase::init_display: cannot connect to default X server.\n"); exit(1); } } @@ -564,6 +507,9 @@ int BC_WindowBase::run_window() done = 0; return_value = 0; + +// Events may have been sent before run_window so can't initialize them here. + // Start tooltips if(window_type == MAIN_WINDOW) { @@ -571,27 +517,34 @@ int BC_WindowBase::run_window() set_repeat(get_resources()->tooltip_delay); } +// Start X server events + event_thread = new BC_WindowEvents(this); + event_thread->start(); + +// Start common events while(!done) { dispatch_event(); } -//printf("BC_WindowBase::run_window 3\n"); unset_all_repeaters(); -//printf("BC_WindowBase::run_window 4\n"); hide_tooltip(); + delete event_thread; + event_thread = 0; + event_condition->reset(); + common_events.remove_all_objects(); + done = 0; return return_value; } -int BC_WindowBase::get_key_masks(XEvent &event) +int BC_WindowBase::get_key_masks(XEvent *event) { // ctrl key down - ctrl_mask = (event.xkey.state & ControlMask) ? 1 : 0; + ctrl_mask = (event->xkey.state & ControlMask) ? 1 : 0; // shift key down - shift_mask = (event.xkey.state & ShiftMask) ? 1 : 0; - alt_mask = (event.xkey.state & Mod1Mask) ? 1 : 0; -//printf("BC_WindowBase::get_key_masks %x\n", event.xkey.state); + shift_mask = (event->xkey.state & ShiftMask) ? 1 : 0; + alt_mask = (event->xkey.state & Mod1Mask) ? 1 : 0; return 0; } @@ -603,7 +556,7 @@ int BC_WindowBase::get_key_masks(XEvent &event) int BC_WindowBase::dispatch_event() { - XEvent event; + XEvent *event = 0; Window tempwin; KeySym keysym; char keys_return[2]; @@ -616,10 +569,12 @@ int BC_WindowBase::dispatch_event() // If an event is waiting get it, otherwise // wait for next event only if there are no compressed events. - if(XPending(display) || + if(/* XPending(display) */ + get_event_count() || (!motion_events && !resize_events && !translation_events)) { - XNextEvent(display, &event); +// XNextEvent(display, event); + event = get_event(); // Lock out window deletions lock_window("BC_WindowBase::dispatch_event 1"); get_key_masks(event); @@ -641,7 +596,8 @@ int BC_WindowBase::dispatch_event() return 0; } - switch(event.type) +//printf("1 %s %p %d\n", title, event, event->type); + switch(event->type) { case ClientMessage: // Clear the resize buffer @@ -649,10 +605,9 @@ int BC_WindowBase::dispatch_event() // Clear the motion buffer since this can clear the window if(motion_events) dispatch_motion_event(); - ptr = (XClientMessageEvent*)&event; + ptr = (XClientMessageEvent*)event; -//printf("BC_WindowBase::dispatch_event 3 %d\n", ptr->data.l[0]); if(ptr->message_type == ProtoXAtom && ptr->data.l[0] == DelWinXAtom) { @@ -690,14 +645,14 @@ int BC_WindowBase::dispatch_event() break; case ButtonPress: - cursor_x = event.xbutton.x; - cursor_y = event.xbutton.y; - button_number = event.xbutton.button; - event_win = event.xany.window; + cursor_x = event->xbutton.x; + cursor_y = event->xbutton.y; + button_number = event->xbutton.button; + event_win = event->xany.window; button_down = 1; - button_pressed = event.xbutton.button; + button_pressed = event->xbutton.button; button_time1 = button_time2; - button_time2 = event.xbutton.time; + button_time2 = event->xbutton.time; drag_x = cursor_x; drag_y = cursor_y; drag_win = event_win; @@ -719,34 +674,30 @@ int BC_WindowBase::dispatch_event() break; case ButtonRelease: - button_number = event.xbutton.button; - event_win = event.xany.window; + button_number = event->xbutton.button; + event_win = event->xany.window; button_down = 0; dispatch_button_release(); break; case Expose: - event_win = event.xany.window; + event_win = event->xany.window; dispatch_expose_event(); break; case MotionNotify: // Dispatch previous motion event if this is a subsequent motion from a different window -{ -//Timer timer; -//timer.update(); - - if(motion_events && last_motion_win != event.xany.window) + if(motion_events && last_motion_win != event->xany.window) + { dispatch_motion_event(); + } // Buffer the current motion motion_events = 1; - last_motion_x = event.xmotion.x; - last_motion_y = event.xmotion.y; - last_motion_win = event.xany.window; -//printf("BC_WindowBase::dispatch_event 1 %lld\n", timer.get_difference()); -} + last_motion_x = event->xmotion.x; + last_motion_y = event->xmotion.y; + last_motion_win = event->xany.window; break; case ConfigureNotify: @@ -758,8 +709,8 @@ int BC_WindowBase::dispatch_event() &last_translate_x, &last_translate_y, &tempwin); - last_resize_w = event.xconfigure.width; - last_resize_h = event.xconfigure.height; + last_resize_w = event->xconfigure.width; + last_resize_h = event->xconfigure.height; cancel_resize = 0; cancel_translation = 0; @@ -797,7 +748,7 @@ int BC_WindowBase::dispatch_event() case KeyPress: keys_return[0] = 0; - XLookupString((XKeyEvent*)&event, keys_return, 1, &keysym, 0); + XLookupString((XKeyEvent*)event, keys_return, 1, &keysym, 0); //printf("BC_WindowBase::dispatch_event %08x\n", keys_return[0]); // block out control keys if(keysym > 0xffe0 && keysym < 0xffff) break; @@ -861,7 +812,7 @@ int BC_WindowBase::dispatch_event() break; } -//printf("BC_WindowBase::run_window %d %d %x\n", shift_down(), alt_down(), key_pressed); +//printf("BC_WindowBase::dispatch_event %d %d %x\n", shift_down(), alt_down(), key_pressed); result = dispatch_keypress_event(); // Handle some default keypresses if(!result) @@ -875,19 +826,21 @@ int BC_WindowBase::dispatch_event() break; case LeaveNotify: - event_win = event.xany.window; + event_win = event->xany.window; dispatch_cursor_leave(); break; case EnterNotify: - event_win = event.xany.window; - cursor_x = event.xcrossing.x; - cursor_y = event.xcrossing.y; + event_win = event->xany.window; + cursor_x = event->xcrossing.x; + cursor_y = event->xcrossing.y; dispatch_cursor_enter(); break; } +//printf("100 %s %p %d\n", title, event, event->type); unlock_window(); + if(event) delete event; return 0; } @@ -956,7 +909,6 @@ int BC_WindowBase::dispatch_translation_event() subwindows->values[i]->dispatch_translation_event(); } -//printf("BC_WindowBase::dispatch_translation_event 1 %p\n", this); translation_event(); return 0; } @@ -970,11 +922,9 @@ int BC_WindowBase::dispatch_motion_event() event_win = last_motion_win; motion_events = 0; -//printf("BC_WindowBase::dispatch_motion_event 1\n"); // Test for grab if(get_button_down() && !active_menubar && !active_popup_menu) { -//printf("BC_WindowBase::dispatch_motion_event 2\n"); if(!result) { cursor_x = last_motion_x; @@ -988,18 +938,6 @@ int BC_WindowBase::dispatch_motion_event() { cursor_x = drag_x; cursor_y = drag_y; -// if(window_tree) -// { -// delete window_tree; -// window_tree = 0; -// } -// if(!window_tree) -// { -// window_tree = new BC_WindowTree(display, -// 0, -// rootwin); -// //window_tree->dump(0, win); -// } result = dispatch_drag_start(); } @@ -1007,22 +945,17 @@ int BC_WindowBase::dispatch_motion_event() cursor_x = last_motion_x; cursor_y = last_motion_y; -//printf("BC_WindowBase::dispatch_motion_event 3\n"); if(active_menubar && !result) result = active_menubar->dispatch_motion_event(); if(active_popup_menu && !result) result = active_popup_menu->dispatch_motion_event(); if(active_subwindow && !result) result = active_subwindow->dispatch_motion_event(); -//printf("BC_WindowBase::dispatch_motion_event 4\n"); } -//printf("BC_WindowBase::dispatch_motion_event 5\n"); for(int i = 0; i < subwindows->total && !result; i++) { result = subwindows->values[i]->dispatch_motion_event(); } -//printf("BC_WindowBase::dispatch_motion_event 6\n"); if(!result) result = cursor_motion_event(); // give to user -//printf("BC_WindowBase::dispatch_motion_event 7\n"); return result; } @@ -1191,6 +1124,7 @@ int BC_WindowBase::dispatch_cursor_leave() { subwindows->values[i]->dispatch_cursor_leave(); } + cursor_leave_event(); return 0; } @@ -1321,6 +1255,7 @@ int BC_WindowBase::show_tooltip(int w, int h) draw_tooltip(); tooltip_popup->set_font(MEDIUMFONT); tooltip_popup->flash(); + tooltip_popup->flush(); } return 0; } @@ -1400,14 +1335,11 @@ int BC_WindowBase::unset_repeat(int64_t duration) int BC_WindowBase::unset_all_repeaters() { -//printf("BC_WindowBase::unset_all_repeaters 1\n"); for(int i = 0; i < repeaters.total; i++) { repeaters.values[i]->stop_repeating(); } -//printf("BC_WindowBase::unset_all_repeaters 1\n"); repeaters.remove_all_objects(); -//printf("BC_WindowBase::unset_all_repeaters 2\n"); return 0; } @@ -1418,15 +1350,21 @@ int BC_WindowBase::unset_all_repeaters() int BC_WindowBase::arm_repeat(int64_t duration) { - XEvent event; - XClientMessageEvent *ptr = (XClientMessageEvent*)&event; + XEvent *event = new XEvent; + XClientMessageEvent *ptr = (XClientMessageEvent*)event; ptr->type = ClientMessage; ptr->message_type = RepeaterXAtom; ptr->format = 32; ptr->data.l[0] = duration; - XSendEvent(display, win, 0, 0, &event); - flush(); +// Couldn't use XSendEvent since it locked up randomly. + put_event(event); +// XSendEvent(top_level->event_display, +// top_level->win, +// 0, +// 0, +// event); +// flush(); return 0; } @@ -1448,8 +1386,8 @@ void BC_WindowBase::init_cursors() vseparate_cursor = XCreateFontCursor(display, XC_sb_v_double_arrow); hseparate_cursor = XCreateFontCursor(display, XC_sb_h_double_arrow); move_cursor = XCreateFontCursor(display, XC_fleur); - left_cursor = XCreateFontCursor(display, XC_left_side); - right_cursor = XCreateFontCursor(display, XC_right_side); + left_cursor = XCreateFontCursor(display, XC_sb_left_arrow); + right_cursor = XCreateFontCursor(display, XC_sb_right_arrow); upright_arrow_cursor = XCreateFontCursor(display, XC_arrow); upleft_resize_cursor = XCreateFontCursor(display, XC_top_left_corner); upright_resize_cursor = XCreateFontCursor(display, XC_top_right_corner); @@ -1657,13 +1595,16 @@ int BC_WindowBase::init_gc() int BC_WindowBase::init_fonts() { - if((largefont = XLoadQueryFont(display, _(resources.large_font))) == NULL) + if((largefont = XLoadQueryFont(display, _(resources.large_font))) == NULL && + (largefont = XLoadQueryFont(display, _(resources.large_font2))) == NULL) largefont = XLoadQueryFont(display, "fixed"); - if((mediumfont = XLoadQueryFont(display, _(resources.medium_font))) == NULL) + if((mediumfont = XLoadQueryFont(display, _(resources.medium_font))) == NULL && + (mediumfont = XLoadQueryFont(display, _(resources.medium_font2))) == NULL) mediumfont = XLoadQueryFont(display, "fixed"); - if((smallfont = XLoadQueryFont(display, _(resources.small_font))) == NULL) + if((smallfont = XLoadQueryFont(display, _(resources.small_font))) == NULL && + (smallfont = XLoadQueryFont(display, _(resources.small_font2))) == NULL) smallfont = XLoadQueryFont(display, "fixed"); #ifdef HAVE_XFT @@ -2332,7 +2273,7 @@ int BC_WindowBase::grab_port_id(BC_WindowBase *window, int color_model) } // Get adaptor with desired color model - for(i = 0; i < numAdapt && port_id == -1; i++) + for(i = 0; i < numAdapt && xvideo_port_id == -1; i++) { /* adaptor supports XvImages */ if(info[i].type & XvImageMask) @@ -2343,7 +2284,7 @@ int BC_WindowBase::grab_port_id(BC_WindowBase *window, int color_model) // for(j = 0; j < numFormats; j++) // printf("%08x\n", formats[j].id); - for(j = 0; j < numFormats; j++) + for(j = 0; j < numFormats && xvideo_port_id < 0; j++) { /* this adaptor supports the desired format */ if(formats[j].id == x_color_model) @@ -2357,7 +2298,7 @@ int BC_WindowBase::grab_port_id(BC_WindowBase *window, int color_model) CurrentTime)) { //printf("BC_WindowBase::grab_port_id %llx\n", info[i].base_id); - port_id = info[i].base_id + k; + xvideo_port_id = info[i].base_id + k; break; } } @@ -2369,23 +2310,23 @@ int BC_WindowBase::grab_port_id(BC_WindowBase *window, int color_model) XvFreeAdaptorInfo(info); - return port_id; + return xvideo_port_id; } -int BC_WindowBase::show_window() -{ +int BC_WindowBase::show_window(int flush) +{ XMapWindow(top_level->display, win); - XFlush(top_level->display); + if(flush) XFlush(top_level->display); // XSync(top_level->display, 0); hidden = 0; return 0; } -int BC_WindowBase::hide_window() +int BC_WindowBase::hide_window(int flush) { - XUnmapWindow(display, win); - XFlush(top_level->display); + XUnmapWindow(top_level->display, win); + if(flush) XFlush(top_level->display); hidden = 1; return 0; } @@ -2421,7 +2362,7 @@ BC_WindowBase* BC_WindowBase::add_tool(BC_WindowBase *subwindow) return add_subwindow(subwindow); } -int BC_WindowBase::flash(int x, int y, int w, int h) +int BC_WindowBase::flash(int x, int y, int w, int h, int flush) { set_opaque(); XSetWindowBackgroundPixmap(top_level->display, win, pixmap); @@ -2433,9 +2374,17 @@ int BC_WindowBase::flash(int x, int y, int w, int h) { XClearWindow(top_level->display, win); } + + if(flush) + this->flush(); return 0; } +int BC_WindowBase::flash(int flush) +{ + flash(-1, -1, -1, -1, flush); +} + void BC_WindowBase::flush() { XFlush(top_level->display); @@ -2453,35 +2402,72 @@ int BC_WindowBase::get_window_lock() int BC_WindowBase::lock_window(char *location) { - SET_LOCK(this, title, location); - XLockDisplay(top_level->display); - top_level->window_lock = 1; + if(top_level && top_level != this) + { + top_level->lock_window(location); + } + else + if(top_level) + { + SET_LOCK(this, title, location); + XLockDisplay(top_level->display); + SET_LOCK2 + top_level->window_lock = 1; + } + else + { + printf("BC_WindowBase::lock_window top_level NULL\n"); + } return 0; } int BC_WindowBase::unlock_window() { - UNSET_LOCK(this); - top_level->window_lock = 0; - XUnlockDisplay(top_level->display); + if(top_level && top_level != this) + { + top_level->unlock_window(); + } + else + if(top_level) + { + UNSET_LOCK(this); + top_level->window_lock = 0; + XUnlockDisplay(top_level->display); + } + else + { + printf("BC_WindowBase::unlock_window top_level NULL\n"); + } return 0; } void BC_WindowBase::set_done(int return_value) { - if(window_type != MAIN_WINDOW) + if(window_type != MAIN_WINDOW) top_level->set_done(return_value); else + if(event_thread) { - XEvent event; - XClientMessageEvent *ptr = (XClientMessageEvent*)&event; + XEvent *event = new XEvent; + XClientMessageEvent *ptr = (XClientMessageEvent*)event; - event.type = ClientMessage; + event->type = ClientMessage; ptr->message_type = SetDoneXAtom; ptr->format = 32; - XSendEvent(top_level->display, top_level->win, 0, 0, &event); - top_level->return_value = return_value; + this->return_value = return_value; + +// May lock up here because XSendEvent doesn't work too well +// asynchronous with XNextEvent. +// This causes BC_WindowEvents to forward a copy of the event to run_window where +// it is deleted. + event_thread->done = 1; + XSendEvent(display, + win, + 0, + 0, + event); flush(); + put_event(event); } } @@ -2505,19 +2491,25 @@ int BC_WindowBase::get_y() return y; } -int BC_WindowBase::get_root_w(int ignore_dualhead) +int BC_WindowBase::get_root_w(int ignore_dualhead, int lock_display) { + if(lock_display) lock_window("BC_WindowBase::get_root_w"); Screen *screen_ptr = XDefaultScreenOfDisplay(display); int result = WidthOfScreen(screen_ptr); // Wider than 16:9, narrower than dual head if(!ignore_dualhead) if((float)result / HeightOfScreen(screen_ptr) > 1.8) result /= 2; + + if(lock_display) unlock_window(); return result; } -int BC_WindowBase::get_root_h() +int BC_WindowBase::get_root_h(int lock_display) { + if(lock_display) lock_window("BC_WindowBase::get_root_h"); Screen *screen_ptr = XDefaultScreenOfDisplay(display); - return HeightOfScreen(screen_ptr); + int result = HeightOfScreen(screen_ptr); + if(lock_display) unlock_window(); + return result; } // Bottom right corner @@ -2750,31 +2742,34 @@ int BC_WindowBase::get_relative_cursor_y() return y; } -int BC_WindowBase::get_abs_cursor_x() +int BC_WindowBase::get_abs_cursor_x(int lock_window) { int abs_x, abs_y, win_x, win_y; unsigned int temp_mask; Window temp_win; - XQueryPointer(top_level->display, - top_level->win, + if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor_x"); + XQueryPointer(top_level->display, + top_level->win, &temp_win, &temp_win, - &abs_x, + &abs_x, &abs_y, &win_x, &win_y, &temp_mask); + if(lock_window) this->unlock_window(); return abs_x; } -int BC_WindowBase::get_abs_cursor_y() +int BC_WindowBase::get_abs_cursor_y(int lock_window) { int abs_x, abs_y, win_x, win_y; unsigned int temp_mask; Window temp_win; - XQueryPointer(top_level->display, + if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor_y"); + XQueryPointer(top_level->display, top_level->win, &temp_win, &temp_win, @@ -2783,6 +2778,7 @@ int BC_WindowBase::get_abs_cursor_y() &win_x, &win_y, &temp_mask); + if(lock_window) this->unlock_window(); return abs_y; } @@ -2806,7 +2802,6 @@ int BC_WindowBase::get_cursor_over_window() int abs_x, abs_y, win_x, win_y; unsigned int temp_mask; Window temp_win1, temp_win2; -//printf("BC_WindowBase::get_cursor_over_window 2\n"); if (!XQueryPointer(display, win, @@ -2817,95 +2812,10 @@ int BC_WindowBase::get_cursor_over_window() &win_x, &win_y, &temp_mask)) - return(0); -//printf("BC_WindowBase::get_cursor_over_window 3 %p\n", window_tree); + return 0; int result = match_window(temp_win2) ; -// printf("t1: %p, t2: %p, win: %p, ret: %i\n", temp_win1, temp_win2, win, result); - return(result); -/*------------------------previous attempts ------------ -// Get location in window tree - BC_WindowTree *tree_node = window_tree->get_node(win); - -// KDE -> Window is overlapped by a transparent window. -// FVWM -> Window is bordered by different windows. - BC_WindowTree *parent_node = tree_node->parent_tree; - for( ; - parent_node->parent_tree != window_tree; - tree_node = parent_node, parent_node = parent_node->parent_tree) - { - ; - } - - int got_it = 0; - for(int i = 0; i < parent_node->windows.total; i++) - { - if(parent_node->windows.values[i] == tree_node) - { - got_it = 1; - } - else - if(got_it) - { - XWindowAttributes attr; - XGetWindowAttributes(display, - parent_node->windows.values[i]->win, - &attr); - -// Obstructed by overlapping window. - if(abs_x >= attr.x && abs_x < attr.x + attr.width && - abs_y >= attr.y && abs_y < attr.y + attr.height && - !attr.override_redirect) - { - return 0; - } - } - } -*/ -# if 0 -// Test every window after current node in same parent node. -// Test every parent node after current parent node. -// These are the overlapping windows. - while(parent_node && parent_node != window_tree) - { -//printf("BC_WindowBase::get_cursor_over_window 4\n"); - if(parent_node - for(int i = 0; i < parent_node->windows.total; i++) - { -//printf("BC_WindowBase::get_cursor_over_window 5\n"); - if(parent_node->windows.values[i] == tree_node) - { -//printf("BC_WindowBase::get_cursor_over_window 6\n"); - got_it = 1; - } - else - if(got_it) - { -//printf("BC_WindowBase::get_cursor_over_window 7\n"); - XWindowAttributes attr; - XGetWindowAttributes(display, - parent_node->windows.values[i]->win, - &attr); - -// Obstructed by overlapping window. - if(abs_x >= attr.x && abs_x < attr.x + attr.width && - abs_y >= attr.y && abs_y < attr.y + attr.height && - !attr.override_redirect) - { - return 0; - } - } -//printf("BC_WindowBase::get_cursor_over_window 8\n"); - } - tree_node = parent_node; - parent_node = tree_node->parent_tree; - } -//printf("BC_WindowBase::get_cursor_over_window 9\n"); - -#endif - -// Didn't find obstruction - return 1; + return result; } int BC_WindowBase::relative_cursor_x(BC_WindowBase *pov) @@ -3167,6 +3077,11 @@ int BC_WindowBase::get_toggle_value() return toggle_value; } +int BC_WindowBase::get_toggle_drag() +{ + return toggle_drag; +} + int BC_WindowBase::set_icon(VFrame *data) { if(icon_pixmap) delete icon_pixmap; @@ -3414,5 +3329,44 @@ void BC_WindowBase::flip_opengl() { glXSwapBuffers(top_level->display, win); } - #endif + +int BC_WindowBase::get_event_count() +{ + event_lock->lock("BC_WindowBase::get_event_count"); + int result = common_events.total; + event_lock->unlock(); + return result; +} + +XEvent* BC_WindowBase::get_event() +{ + XEvent *result = 0; + while(!done && !result) + { + event_condition->lock("BC_WindowBase::get_event"); + event_lock->lock("BC_WindowBase::get_event"); + if(common_events.total && !done) + { + result = common_events.values[0]; + common_events.remove_number(0); + } + event_lock->unlock(); + } + return result; +} + +void BC_WindowBase::put_event(XEvent *event) +{ + event_lock->lock("BC_WindowBase::put_event"); + common_events.append(event); + event_lock->unlock(); + event_condition->unlock(); +} + + + + + + + diff --git a/hvirtual/guicast/bcwindowbase.h b/hvirtual/guicast/bcwindowbase.h index f50a8f8b..d4769080 100644 --- a/hvirtual/guicast/bcwindowbase.h +++ b/hvirtual/guicast/bcwindowbase.h @@ -41,6 +41,8 @@ #include "bctumble.inc" #include "bcwindow.inc" #include "bcwindowbase.inc" +#include "bcwindowevents.inc" +#include "condition.inc" #include "defaults.inc" #include "linklist.h" #include "mutex.h" @@ -76,21 +78,6 @@ public: int w, h; }; -class BC_WindowTree -{ -public: - BC_WindowTree(Display* display, BC_WindowTree *parent_tree, Window root_win); - ~BC_WindowTree(); - - void dump(int indent, Window caller_win = 0); - BC_WindowTree* get_node(Window win); - ArrayList windows; - - Display* display; - Window win; - BC_WindowTree *parent_tree; -}; - // Windows, subwindows, popupwindows inherit from this class BC_WindowBase @@ -129,6 +116,7 @@ public: friend class BC_Toggle; friend class BC_Tumbler; friend class BC_Window; + friend class BC_WindowEvents; // Main loop int run_window(); @@ -160,8 +148,8 @@ public: int get_color(int64_t color); // return the currently selected color int64_t get_color(); - int show_window(); - int hide_window(); + int show_window(int flush = 1); + int hide_window(int flush = 1); int get_hidden(); void enable_opengl(); void disable_opengl(); @@ -169,7 +157,8 @@ public: void unlock_opengl(); void flip_opengl(); - int flash(int x = -1, int y = -1, int w = -1, int h = -1); + int flash(int x, int y, int w, int h, int flush = 1); + int flash(int flush = 1); void flush(); void sync_display(); // Lock out other threads @@ -187,11 +176,11 @@ public: virtual int get_h(); virtual int get_x(); virtual int get_y(); - int get_root_w(int ignore_dualhead = 0); - int get_root_h(); + int get_root_w(int ignore_dualhead = 0, int lock_display = 0); + int get_root_h(int lock_display); // Get current position - int get_abs_cursor_x(); - int get_abs_cursor_y(); + int get_abs_cursor_x(int lock_window); + int get_abs_cursor_y(int lock_window); int get_relative_cursor_x(); int get_relative_cursor_y(); // Return 1 if cursor is over an unobscured part of this window. @@ -242,6 +231,8 @@ public: void set_active_subwindow(BC_WindowBase *subwindow); // Get value of toggle value when dragging a selection int get_toggle_value(); +// Get if toggle is being dragged + int get_toggle_drag(); // Set the gc to the color @@ -427,9 +418,11 @@ public: int set_tooltips(int tooltips_enabled); int resize_window(int w, int h); int reposition_window(int x, int y, int w = -1, int h = -1); -// int64_t get_repeat_id(); +// Cause a repeat event to be dispatched every duration. +// duration is milliseconds int set_repeat(int64_t duration); - int unset_repeat(int64_t id); +// Stop a repeat event from being dispatched. + int unset_repeat(int64_t duration); int set_tooltip(char *text); int show_tooltip(int w = -1, int h = -1); int hide_tooltip(); @@ -494,7 +487,7 @@ private: void set_fontset(int font); int dispatch_event(); - int get_key_masks(XEvent &event); + int get_key_masks(XEvent *event); int trigger_tooltip(); int untrigger_tooltip(); @@ -503,6 +496,13 @@ private: // delete all repeater opjects for a close int unset_all_repeaters(); +// Block and get event from common events. + XEvent* get_event(); +// Return number of events in table. + int get_event_count(); +// Put event in common events. + void put_event(XEvent *event); + // Recursive event dispatchers int dispatch_resize_event(int w, int h); int dispatch_focus_in(); @@ -598,6 +598,7 @@ private: int key_pressed; // During a selection drag involving toggles, set the same value for each toggle int toggle_value; + int toggle_drag; // Whether the window has the focus int has_focus; @@ -646,9 +647,6 @@ private: int shared_bg_pixmap; char title[BCTEXTLEN]; -// Window tree for dragging operations - static BC_WindowTree *window_tree; - // X Window parameters int screen; Window rootwin; @@ -656,7 +654,10 @@ private: Window event_win, drag_win; Visual *vis; Colormap cmap; - Display* display; +// Display for all synchronous operations + Display *display; +// Display to send events on + Display *event_display; Window win; Pixmap pixmap; #ifdef HAVE_GL @@ -703,6 +704,16 @@ private: int vm_switched; XF86VidModeModeInfo orig_modeline; #endif + +// Common events coming from X server and repeater. + ArrayList common_events; +// Locks for common events +// Locking order: +// 1) event_condition +// 2) event_lock + Mutex *event_lock; + Condition *event_condition; + BC_WindowEvents *event_thread; }; diff --git a/hvirtual/guicast/filesystem.h b/hvirtual/guicast/filesystem.h index efc18c41..ffc7140c 100644 --- a/hvirtual/guicast/filesystem.h +++ b/hvirtual/guicast/filesystem.h @@ -66,7 +66,7 @@ public: int extract_name(char *out, const char *in, int test_dir = 1); // extract the name from the path int join_names(char *out, char *dir_in, char *name_in); // combine a directory and filename long get_date(char *filename); // get the date of the filename modification - int64_t get_size(char *filename); // Get the number of bytes in the file. + static int64_t get_size(char *filename); // Get the number of bytes in the file. int add_end_slash(char *new_dir); int total_files(); FileItem* get_entry(int entry); diff --git a/hvirtual/guicast/images/xmeter.xcf.bz2 b/hvirtual/guicast/images/xmeter.xcf.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5eb047e1cd1fd0ab32d1c0759d014df06f9c02c0 GIT binary patch literal 3756 zcwTjvdo&aN|Hn5LCf9A{652GQ2%A;zW^UVD=U$|_wkZ-zOrLURqK4(NA=kN7a*Luq zE=iKhTtbw}tt3Tmp-+DG{rt}FeE<19{&=3(d7bC$@%Q_UKSk9;o1R2Dos8GAivftL z?f${!#qR&ld-0EL0Kh>hz;9rDVAURtHh}*TXdu;FiC2)Gi5vV(U3K=O@nTq5tXLYx zhgLW|GMGG=%t(|PorC#QyF8 zOK?~WKwd2RkCKY{?U9%NJy02mF$+Q*q3D!kjt~!J6Ag&7%U|Ald`&73G<;1vjbO!*86D5#ORnVz{{ATDS|0>2RZcP$r*o({gQMR-`z_hfVZ8QnXFnkkoZwoAyS3m}w>Ws_BMV^tNx8J{ z`E;8c{DttVHaTSS&CM6c6yfm67haq9-mC(ep%K z7(im@&8?sHR~*8BmL$xvCG1@zCW{@pzMaN0QtYQA*ne}lEUoZADxZ$I$-eLgMdm?jx623zaextf^!FBw*J&r_#XHO;B$v^ zkfYF5k#zN%azjd6D#bjU2{buxI~1-hBIPI}9)c*i68=FaXeE%p?N9g9PoN@9GZ?VY>VCp z@KNg_;drMZ(W-mkM+&@wAK0-+oRdBpNgs0PBc!$qQCTVbBEA$7io)YzYB*MG8WjqZ z2m`W5Nb#}eA{G?nb(pdSUpZbr6{Z}&CxPiFchaE@ZY?CWZ?;{wP0|S7j`&)5dlm_u z%)jK6VTqXLthU)zl*r;%XfUL)Vqh7x{Tevg*V9NEP9~H+9a7cyJ}was6xIh~F1XFu z?)@&!wA(XQv-#n{bmF%zvHnzDZpbsSD|uYqq~}{;$PF=c%$!>H4aP8stcZq$CRVJZ zKTo%YEREfZl4+UE!|lT0%6JRuenOJDg9Rw7&`M5jk&x67+%%x(r6OC#X0)O{Pw=2g zm)c+u_)~?XH4~BGPl$e)5+uHvCE;dPb;mt4u11{|FCa+KkFH*>=!J+!#I=b!#F`7+ zNzVWLy3G<^4e)#-TB(iurudD;4y*hdw+6W%pWQg|9u|}~bmbdPD>|2_(77yNX!ibX zk{20ZEG`v%ea}j3VEMq0iM33DV!txBwmI9Lj=Kl9+doU?G$P0mKl!qQX z!3V^9ei5T2AWpvI!{e6OLZub-lOe}R=9(CwI)GwW{Ih2NIUMN&&_Eh3Fs<}*JlQE{ zYQO8lfUv582%G&LBMa4^JcS1zsqOB4eYS~y8=|P@B^UPQ=$>i9eyC)6H_-@ls#C(M zL)~f%6%W7e&~t7?4}l%#88zzjN8ltSCP1ALO_ z&+mXfg*IzxxGi^hon6VsN7W?^s`kcSAjXeQGb4>N7CAE7Z{zxsv(3z@sxfiPswaxi zCd!oLv0wI+&V1i`sMADyrGmiNfc{qh=2XAsSl(GEfjM8`z|NGiO}^4x(t*ABvZt%B zmcfqwzB>I6_j^(57V%pUebn@0P~g85oNimyWu}q)dI*-m{4sX(YXA>K4tBi^88=JoIHV_uck`t zJTIQ}^A=Qdp|akP7#=YZ;!mNt7F%So`xsJUnIzLxFNim8@0NINVkxnrWmk6Cwcwz$ zy;Obl8Lpvxz=huJ2=`6Xc}Fo+(2s0laO+6UI*K%|o~PrJy@6*qB4zi-=Nr_bsmRP5 zaYIZLnPG|W*~~i+T2SH})E@|`U9OO|N@c6VJl?;axwNHZie{Z=YGzzdzgbQXt`*(( zyD8UWT+)<}V_MINWy9WPPSSQ;)>&$^J;@WuFA&Tf-Pqh~kCpVm3xKl|b;t=IX+ ziuV05Gi3GCRuXsbjKYS~vPgh@^?~7tJS(lf?S{%P!zQIhIT@IF#ulOz{n07+SFW`|z$d+5prrVcksg z7~Q90mwyC#O+h29v!$AH()xQ31$^JZ*@4w}Wn?YuyVBZ3fzhxomgdbyZp;zcg>anW-OTajzplSYFhW=SifdAxaS;FR z*QxdQOowQq)Ho*fZjS}<#9Pa|n5&a(dl{Zb5iOz?zKsx{oBSTA?37Ct8Myw&?0s6O zlFCW*xr2m^!VR7dx_(ueuAqUiDm@hN=@+8RW^>vrUup52mR%H7XeP^l%&2Qg16(pBS{_K5+M4I&9~zSMWLFyC3$rD9t_L5x8b*CUm}BDP#M97+-s_2< z<+cXh_PyV11KBzG&U#Tr+~dheuu|F1wk9A;457Msg4m)fa8ZJvE%oX)%lbKT^VtX3 zOUhh6deE5oS2Kbo&!b?gc|Y~Xx^%4+>{vy+`+$RyVA|*}nMF+5LPi?-_^V_;@Rnf- zpf$h*kf%66E>OJ^=}$s|V^z}8olQUDNI{@s8x+v_iLq|ZeCcZ)uS{_52uHw`F(yCy zws$=8UhL>_&z(Cp^2PR#k&@cBEY8OZ;is;yCNWHBIA-VPmU4S_9zkDok{G^V&&>)^v;zArFotDC)bKj$x7>IOd!q0+{=77LPTnHYrO{T3H&PW6vtqi==egW{7bO(1~by53eZqo55)lDH{p$vxGlezJP-Xfs(AoRf7@PTuCmElMk` z;+T!|dtC>rpLQBmuc*JHDCQL>Qq`#bv)F>RGke;TCs%F!9_imTl&^PaqBZX3VgF&N zN$}+#YxIP@It|(lTMUV~$+NJiB*ILh)8)u{dND)uBDBcSb2;MqB208%Dnyj{#0&@% zlst35tmvTgV1`^H3LjvD#Cm_41{H?-o9;ehEDlTay<`q&;oL$FwBg?-yZa={nk5dV zXj#m*_y=cyFKy+J;Kr0Im!|wXHc$>jt^l;ZwT4RiBIN&;nOYj6dS0lE?c@EWW zFG4iWfzUseuQ8Pgd9V}! zA_#MW;*VS+S)RV`LFe-u9wqdfc@rxp&=Fz@PppVH5*;FAhs9}t= zjjIZ~u&XCLh^*OJlZH))XCl@+Us`Lq3Z^J5k4a1RDCQ!PT~+x<1V#mxX3#_^bvwX3 z-O$piFNkTXrg~#}%G&nUvBUA%F*ep{XE)7O>#3L7`8G~>|&`|ksVWJ_ElN}Tg^b5rw57@Uhz6H8K4 z6v{J8G895GQWe}ieFNU7sOA9`ns~Z6hE&{od)-iwfq~=jfddck8_h__e)M4bwg%M| vjS5AM!qXBCHnDPx=|pTuI9Ok7^;%a}R*qRVtVGxqsGq^p)z4*}Q$iB}7~MU< literal 0 HcwPel00001 diff --git a/hvirtual/guicast/images/xmeter_green_png.h b/hvirtual/guicast/images/xmeter_green_png.h new file mode 100644 index 00000000..40a9a266 --- /dev/null +++ b/hvirtual/guicast/images/xmeter_green_png.h @@ -0,0 +1,22 @@ +#ifndef XMETER_GREEN_PNG_H +#define XMETER_GREEN_PNG_H + +static unsigned char xmeter_green_png[] = +{ + 0x00, 0x00, 0x00, 0xd0, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x06, 0x00, 0x00, 0x00, 0xb8, 0x12, 0xac, + 0x71, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, + 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, + 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xd4, 0x06, 0x0b, 0x05, 0x1b, 0x01, 0xc5, 0xc0, 0xbf, 0xdf, 0x00, 0x00, 0x00, 0x1d, 0x74, + 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 0x00, 0x00, 0x00, 0x34, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd7, + 0x31, 0x11, 0x00, 0x00, 0x08, 0xc3, 0xc0, 0xc0, 0xe1, 0xdf, 0x32, 0x98, 0x60, 0x6b, 0xe2, 0xe0, + 0xb7, 0xb6, 0x80, 0x25, 0xa8, 0x81, 0x20, 0x72, 0x41, 0x13, 0x96, 0x60, 0xc1, 0x82, 0x05, 0x0b, + 0x16, 0x2c, 0x58, 0xb0, 0x60, 0xc1, 0x7f, 0x73, 0x3a, 0xeb, 0x2d, 0x1d, 0x1d, 0x1e, 0x03, 0x1d, + 0x56, 0x74, 0x13, 0x45, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + +#endif diff --git a/hvirtual/guicast/images/xmeter_normal.png b/hvirtual/guicast/images/xmeter_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..df4204f3161673f4809ce7f139fd21f95b89a210 GIT binary patch literal 211 zcwXxa@N?(olHy`uVBq!ia0vp^HbBhJ!3HFE2(2juQfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#3L7`8lUS^hvF*%H@?66gHf+|;}h2Ir#G#FEq$ zh4Rdj426)4R0VfW-+=cis(C<#=AJH&Ar-gYUN;nEFkm=z;KJ(q(^p)~h1mByHW*!D y&6v%aGfD24kWR#ggo912++sREuFs3B_U2zxz$Uvge#{XE)7O>#3L7`8w2))nKSrRCY>8_`iF1B#Zfaf$gL6@8Vo7R> zLV0FMhC)b2s)DgTe~DWM4faJD>R literal 0 HcwPel00001 diff --git a/hvirtual/guicast/images/xmeter_red_png.h b/hvirtual/guicast/images/xmeter_red_png.h new file mode 100644 index 00000000..a95a51d1 --- /dev/null +++ b/hvirtual/guicast/images/xmeter_red_png.h @@ -0,0 +1,22 @@ +#ifndef XMETER_RED_PNG_H +#define XMETER_RED_PNG_H + +static unsigned char xmeter_red_png[] = +{ + 0x00, 0x00, 0x00, 0xd0, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x06, 0x00, 0x00, 0x00, 0xb8, 0x12, 0xac, + 0x71, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, + 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, + 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xd4, 0x06, 0x0b, 0x05, 0x1b, 0x12, 0x41, 0x7e, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x74, + 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 0x00, 0x00, 0x00, 0x34, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd7, + 0x31, 0x11, 0x00, 0x00, 0x08, 0xc3, 0xc0, 0xc0, 0xe1, 0xdf, 0x32, 0x98, 0x60, 0x6b, 0xe2, 0xe0, + 0xb7, 0xb6, 0x80, 0x25, 0xa8, 0x21, 0x48, 0x5c, 0x40, 0x13, 0x96, 0x60, 0xc1, 0x82, 0x05, 0x0b, + 0x16, 0x2c, 0x58, 0xb0, 0x60, 0xc1, 0x8f, 0x7b, 0x3a, 0xea, 0x2d, 0x1d, 0x1e, 0x1e, 0x03, 0x1d, + 0x03, 0x00, 0xb1, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + +#endif diff --git a/hvirtual/guicast/images/xmeter_yellow.png b/hvirtual/guicast/images/xmeter_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..51a2fb9b39cde17646bc05458fbdd75e5e63a308 GIT binary patch literal 210 zcwXxa@N?(olHy`uVBq!ia0vp^HbBhJ!3HFE2(2juQfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#3L7`8wCu%$k0$_yWJ_ElN}Tg^b5rw57@Uhz6H8K4 z6v{J8G895GQWe}ieFNU7sOA9`nt8f7hE&{odwruIg8|PWhl!v6Y2Wr<;(Y6YHOB@K yQ-)|KzXyTS5)L-8a*OFiY)Ck`|69rJXe-yBEV2c<>IZ=)FnGH9xvX21sUt!~BmC;iS5OD+w$(FcAlsM<-=BDPAFgO>bCYGe8 zD3oWGWGIAWq$;?3`UbpDQOyG?H1>3H45_&F_PV3s0Rx@`2FuO=O$p~a8~%^GVfnA> qH>=(4N~2f~8}LBT`wux~AD9?5n9JE1mi+^2XYh3Ob6Mw<&;$VR9y?F~ literal 0 HcwPel00001 diff --git a/hvirtual/guicast/images/ymeter_green_png.h b/hvirtual/guicast/images/ymeter_green_png.h new file mode 100644 index 00000000..17898ec2 --- /dev/null +++ b/hvirtual/guicast/images/ymeter_green_png.h @@ -0,0 +1,22 @@ +#ifndef YMETER_GREEN_PNG_H +#define YMETER_GREEN_PNG_H + +static unsigned char ymeter_green_png[] = +{ + 0x00, 0x00, 0x00, 0xcf, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x00, 0x00, 0xb9, 0x38, 0xe0, + 0x49, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x8d, + 0xbf, 0x48, 0x1e, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, + 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xd4, 0x06, 0x0b, 0x05, 0x1c, 0x2e, 0x21, 0x50, 0x14, 0x41, 0x00, 0x00, 0x00, 0x1d, 0x74, + 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 0x00, 0x00, 0x00, 0x33, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd7, + 0x41, 0x11, 0xc0, 0x30, 0x0c, 0xc0, 0x30, 0xa7, 0x37, 0xfe, 0x94, 0x57, 0x0e, 0xcd, 0x57, 0xfe, + 0x0b, 0x80, 0xa7, 0xfa, 0x7b, 0xec, 0xab, 0x47, 0x3e, 0x75, 0x5a, 0x04, 0xc3, 0x30, 0x0c, 0xc3, + 0x30, 0x0c, 0xc3, 0x30, 0x0c, 0xef, 0xf0, 0x6c, 0x76, 0xf0, 0x02, 0x01, 0x28, 0x03, 0x77, 0x06, + 0x00, 0xa6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + +#endif diff --git a/hvirtual/guicast/images/ymeter_normal.png b/hvirtual/guicast/images/ymeter_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..82c6c75e1af95b116b02ca448bda318f0c1e72e6 GIT binary patch literal 210 zcwXxa@N?(olHy`uVBq!ia0vp^{6K8O!3HFET0HOsQfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#3L7`Ordpp}*J_}UY>8_`iF1B#Zfaf$gL6@8Vo7R> zLV0FMhC)b2s)D)z4*}Q$iB}h=@R? literal 0 HcwPel00001 diff --git a/hvirtual/guicast/images/ymeter_normal_png.h b/hvirtual/guicast/images/ymeter_normal_png.h new file mode 100644 index 00000000..1b6f32e3 --- /dev/null +++ b/hvirtual/guicast/images/ymeter_normal_png.h @@ -0,0 +1,23 @@ +#ifndef YMETER_NORMAL_PNG_H +#define YMETER_NORMAL_PNG_H + +static unsigned char ymeter_normal_png[] = +{ + 0x00, 0x00, 0x00, 0xd2, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x00, 0x00, 0xb9, 0x38, 0xe0, + 0x49, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, + 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, + 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xd4, 0x06, 0x0b, 0x07, 0x29, 0x26, 0x8e, 0x3e, 0x8a, 0xab, 0x00, 0x00, 0x00, 0x1d, 0x74, + 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 0x00, 0x00, 0x00, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd7, + 0xb1, 0x11, 0x00, 0x20, 0x10, 0x84, 0x40, 0xce, 0xb1, 0xff, 0x96, 0xdf, 0xc0, 0x0a, 0xf4, 0x52, + 0xc8, 0xb7, 0x00, 0x02, 0x0c, 0x9f, 0x6d, 0xae, 0xce, 0x2b, 0x0c, 0xcc, 0xa2, 0x48, 0x2c, 0x16, + 0x8b, 0xc5, 0x62, 0xb1, 0x58, 0x2c, 0x16, 0x8b, 0xc5, 0x1d, 0x4e, 0xb3, 0x83, 0x07, 0xd6, 0x1f, + 0x04, 0x77, 0x81, 0xe6, 0xf1, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, + 0x60, 0x82 +}; + +#endif diff --git a/hvirtual/guicast/images/ymeter_red.png b/hvirtual/guicast/images/ymeter_red.png new file mode 100644 index 0000000000000000000000000000000000000000..756e73925f816b3284057b35b888556cbd085d11 GIT binary patch literal 207 zcwXxa@N?(olHy`uVBq!ia0vp^{6K8O!3HFET0HOsQfx`y?k)`ffsmnhzlR)9gtNdS zvY3H^TNs2H8D`Cq01C2~c>21sUt!~Bl~K}o7Lf%Mk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(Xzc0Y7*cWT?R7`N0|q21sUt!~Bl@a3%T5}&LBwOMdQR1ARo12mghdkQhq3T>UE%g22WQ%mvv4FO#nFYJ5>Mx literal 0 HcwPel00001 diff --git a/hvirtual/guicast/images/ymeter_yellow_png.h b/hvirtual/guicast/images/ymeter_yellow_png.h new file mode 100644 index 00000000..46976472 --- /dev/null +++ b/hvirtual/guicast/images/ymeter_yellow_png.h @@ -0,0 +1,22 @@ +#ifndef YMETER_YELLOW_PNG_H +#define YMETER_YELLOW_PNG_H + +static unsigned char ymeter_yellow_png[] = +{ + 0x00, 0x00, 0x00, 0xd0, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x00, 0x00, 0xb9, 0x38, 0xe0, + 0x49, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x8d, + 0xbf, 0x48, 0x1e, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, + 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xd4, 0x06, 0x0b, 0x05, 0x1c, 0x16, 0x09, 0x52, 0xac, 0xdf, 0x00, 0x00, 0x00, 0x1d, 0x74, + 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 0x00, 0x00, 0x00, 0x34, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd7, + 0x31, 0x11, 0x00, 0x30, 0x0c, 0xc3, 0x40, 0xb9, 0x17, 0xfe, 0x94, 0x53, 0x0e, 0xf1, 0x2a, 0xed, + 0x0f, 0x40, 0x01, 0x96, 0x63, 0x03, 0xb0, 0x07, 0x9e, 0xc0, 0xa3, 0x48, 0x2c, 0x16, 0x8b, 0xc5, + 0x62, 0xb1, 0x58, 0x2c, 0x16, 0x8b, 0xc5, 0x1d, 0x4e, 0xb3, 0x83, 0x1f, 0x0b, 0xc6, 0x04, 0x77, + 0xc2, 0x63, 0x95, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + +#endif diff --git a/hvirtual/guicast/mutex.C b/hvirtual/guicast/mutex.C index 181fc213..790fd3e9 100644 --- a/hvirtual/guicast/mutex.C +++ b/hvirtual/guicast/mutex.C @@ -20,6 +20,7 @@ int Mutex::lock(char *location) { SET_LOCK(this, title, location); if(pthread_mutex_lock(&mutex)) perror("Mutex::lock"); + SET_LOCK2 return 0; } @@ -41,5 +42,6 @@ int Mutex::reset() pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutex_init(&mutex, &attr); + UNSET_ALL_LOCKS(this) return 0; } diff --git a/hvirtual/guicast/rotateframe.C b/hvirtual/guicast/rotateframe.C index fa1e99bf..d2efb78e 100644 --- a/hvirtual/guicast/rotateframe.C +++ b/hvirtual/guicast/rotateframe.C @@ -1,8 +1,10 @@ +#include "condition.h" #include "rotateframe.h" #include "vframe.h" #include #include +#include #define SQR(x) ((x) * (x)) @@ -218,6 +220,12 @@ int RotateFrame::rotate_rightangle(VFrame *input, case BC_RGBA8888: ROTATE_RIGHTANGLE(unsigned char, 4); break; + case BC_RGB_FLOAT: + ROTATE_RIGHTANGLE(float, 3); + break; + case BC_RGBA_FLOAT: + ROTATE_RIGHTANGLE(float, 4); + break; case BC_YUV888: ROTATE_RIGHTANGLE(unsigned char, 3); break; @@ -330,6 +338,12 @@ int RotateFrame::rotate_obliqueangle(VFrame *input, // Fill center pixel switch(input->get_color_model()) { + case BC_RGB_FLOAT: + FILL_CENTER(float, 3) + break; + case BC_RGBA_FLOAT: + FILL_CENTER(float, 4) + break; case BC_RGB888: case BC_YUV888: FILL_CENTER(unsigned char, 3) @@ -365,24 +379,26 @@ RotateEngine::RotateEngine(RotateFrame *plugin, int row1, int row2) : Thread() done = 0; this->row1 = row1; this->row2 = row2; - input_lock.lock(); - output_lock.lock(); + input_lock = new Condition(0, "RotateEngine::input_lock"); + output_lock = new Condition(0, "RotateEngine::output_lock"); } RotateEngine::~RotateEngine() { if(!done) { done = 1; - input_lock.unlock(); + input_lock->unlock(); join(); } + delete input_lock; + delete output_lock; } int RotateEngine::generate_matrix(int interpolate) { this->do_matrix = 1; this->interpolate = interpolate; - input_lock.unlock(); + input_lock->unlock(); return 0; } @@ -394,14 +410,14 @@ int RotateEngine::perform_rotation(VFrame *input, this->output = output; this->do_rotation = 1; this->interpolate = interpolate; - input_lock.unlock(); + input_lock->unlock(); return 0; } int RotateEngine::wait_completion() { - output_lock.lock(); + output_lock->lock("RotateEngine::wait_completion"); return 0; } @@ -547,8 +563,10 @@ int RotateEngine::create_matrix() { \ if(float_row[j].x < 0 || float_row[j].y < 0) \ { \ - for(int m = 0; m < components; m++) \ - output_rows[i][j * components + m] = 0; \ + output_rows[i][j * components + 0] = 0; \ + output_rows[i][j * components + 1] = black_chroma; \ + output_rows[i][j * components + 2] = black_chroma; \ + if(components == 4) output_rows[i][j * components + 3] = 0; \ } \ else \ { \ @@ -596,12 +614,18 @@ int RotateEngine::perform_rotation() case BC_RGB888: ROTATE_NEAREST(unsigned char, 3, 0x0); break; + case BC_RGB_FLOAT: + ROTATE_NEAREST(float, 3, 0x0); + break; case BC_YUV888: ROTATE_NEAREST(unsigned char, 3, 0x80); break; case BC_RGBA8888: ROTATE_NEAREST(unsigned char, 4, 0x0); break; + case BC_RGBA_FLOAT: + ROTATE_NEAREST(float, 4, 0x0); + break; case BC_YUVA8888: ROTATE_NEAREST(unsigned char, 4, 0x80); break; @@ -628,12 +652,18 @@ int RotateEngine::perform_rotation() case BC_RGB888: ROTATE_INTERPOLATE(unsigned char, 3, 0x0); break; + case BC_RGB_FLOAT: + ROTATE_INTERPOLATE(float, 3, 0x0); + break; case BC_YUV888: ROTATE_INTERPOLATE(unsigned char, 3, 0x80); break; case BC_RGBA8888: ROTATE_INTERPOLATE(unsigned char, 4, 0x0); break; + case BC_RGBA_FLOAT: + ROTATE_INTERPOLATE(float, 4, 0x0); + break; case BC_YUVA8888: ROTATE_INTERPOLATE(unsigned char, 4, 0x80); break; @@ -660,7 +690,7 @@ void RotateEngine::run() { while(!done) { - input_lock.lock(); + input_lock->lock("RotateEngine::run"); if(done) return; if(do_matrix) @@ -675,6 +705,6 @@ void RotateEngine::run() do_matrix = 0; do_rotation = 0; - output_lock.unlock(); + output_lock->unlock(); } } diff --git a/hvirtual/guicast/rotateframe.h b/hvirtual/guicast/rotateframe.h new file mode 100644 index 00000000..1fa630b2 --- /dev/null +++ b/hvirtual/guicast/rotateframe.h @@ -0,0 +1,83 @@ +#ifndef ROTATEFRAME_H +#define ROTATEFRAME_H + +#include "condition.inc" +#include "thread.h" +#include "vframe.inc" + +class RotateEngine; + +typedef struct +{ + float x, y; +} SourceCoord; + +class RotateFrame +{ +public: + RotateFrame(int cpus, int width, int height); + ~RotateFrame(); + + void rotate(VFrame *output, VFrame *input, double angle, int interpolate); + int rotate_rightangle(VFrame *input, + VFrame *output, + int angle); + int rotate_obliqueangle(VFrame *input, + VFrame *output, + double angle, + int interpolate); + int get_rightdimensions(VFrame *frame, + int &diameter, + int &in_x1, + int &in_y1, + int &in_x2, + int &in_y2, + int &out_x1, + int &out_y1, + int &out_x2, + int &out_y2); + + int cpus; + RotateEngine **engine; +// Matrix of source pixel offsets + int *int_matrix, **int_rows; +// Interpolation uses input coordinates for each output coordinate. + SourceCoord *float_matrix, **float_rows; + VFrame *output, *input; + int interpolate; + int last_interpolate; +// Compare new angle with old angle + double last_angle; + double angle; +}; + + +class RotateEngine : public Thread +{ +public: + RotateEngine(RotateFrame *plugin, int row1, int row2); + ~RotateEngine(); + + int generate_matrix(int interpolate); + int perform_rotation(VFrame *input, + VFrame *output, + int interpolate); + int wait_completion(); + int create_matrix(); + int coords_to_pixel(int &input_y, int &input_x); + int coords_to_pixel(SourceCoord &float_pixel, float &input_y, float &input_x); + int perform_rotation(); + void run(); + + int row1, row2; + int interpolate; + int do_matrix, do_rotation; + int done; + RotateFrame *plugin; + Condition *input_lock; + Condition *output_lock; + VFrame *output; + VFrame *input; +}; + +#endif diff --git a/hvirtual/guicast/sema.C b/hvirtual/guicast/sema.C index 8f75afa4..a24d4fe8 100644 --- a/hvirtual/guicast/sema.C +++ b/hvirtual/guicast/sema.C @@ -8,6 +8,7 @@ Sema::Sema(int init_value, char *title) { sem_init(&sem, 0, init_value); this->title = title; + this->init_value = init_value; } Sema::~Sema() @@ -21,6 +22,7 @@ void Sema::lock(char *location) { SET_LOCK(this, title, location); sem_wait(&sem); + SET_LOCK2 } void Sema::unlock() @@ -36,6 +38,12 @@ int Sema::get_value() return result; } +void Sema::reset() +{ + sem_destroy(&sem); + sem_init(&sem, 0, init_value); + UNSET_ALL_LOCKS(this) +} diff --git a/hvirtual/guicast/sema.h b/hvirtual/guicast/sema.h index 40245f3b..68358609 100644 --- a/hvirtual/guicast/sema.h +++ b/hvirtual/guicast/sema.h @@ -13,9 +13,11 @@ public: void lock(char *location = 0); void unlock(); int get_value(); + void reset(); sem_t sem; char *title; + int init_value; }; diff --git a/hvirtual/guicast/test.C b/hvirtual/guicast/test.C index e051ede7..2f90b307 100644 --- a/hvirtual/guicast/test.C +++ b/hvirtual/guicast/test.C @@ -122,13 +122,13 @@ public: switch(get_keypress()) { case UP: - current_cursor += 2; + current_cursor += 1; if(current_cursor >= XC_num_glyphs) current_cursor = 0; break; case DOWN: - current_cursor -= 2; - if(current_cursor <= 0) current_cursor = XC_num_glyphs - 2; + current_cursor -= 1; + if(current_cursor <= 0) current_cursor = XC_num_glyphs - 1; break; } printf("%d\n", current_cursor); diff --git a/hvirtual/guicast/thread.C b/hvirtual/guicast/thread.C index b78118d0..f1541339 100644 --- a/hvirtual/guicast/thread.C +++ b/hvirtual/guicast/thread.C @@ -13,6 +13,7 @@ Thread::Thread(int synchronous, int realtime, int autodelete) this->autodelete = autodelete; tid = (pthread_t)-1; thread_running = 0; + cancel_enabled = 0; } Thread::~Thread() @@ -27,6 +28,7 @@ void* Thread::entrypoint(void *parameters) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); // Disable cancellation by default. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); + thread->cancel_enabled = 0; //printf("Thread::entrypoint 1 %d\n", getpid()); thread->run(); @@ -100,6 +102,7 @@ int Thread::join() // join this thread int Thread::enable_cancel() { + cancel_enabled = 1; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); return 0; } @@ -107,9 +110,15 @@ int Thread::enable_cancel() int Thread::disable_cancel() { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + cancel_enabled = 0; return 0; } +int Thread::get_cancel_enabled() +{ + return cancel_enabled; +} + int Thread::exit_thread() { pthread_exit(0); diff --git a/hvirtual/guicast/thread.h b/hvirtual/guicast/thread.h index a85adc82..f10a3a11 100644 --- a/hvirtual/guicast/thread.h +++ b/hvirtual/guicast/thread.h @@ -28,6 +28,7 @@ public: int exit_thread(); // exit this thread int enable_cancel(); int disable_cancel(); + int get_cancel_enabled(); int running(); // Return if thread is running int set_synchronous(int value); int set_realtime(int value = 1); @@ -44,6 +45,7 @@ private: int autodelete; // set to 1 to autodelete when run() finishes int thread_running; pthread_t tid; + int cancel_enabled; }; #endif diff --git a/hvirtual/guicast/vframe.C b/hvirtual/guicast/vframe.C index ec614f20..a75dcbf7 100644 --- a/hvirtual/guicast/vframe.C +++ b/hvirtual/guicast/vframe.C @@ -288,7 +288,10 @@ int VFrame::allocate_data(unsigned char *data, else { shared = 0; - int size = calculate_data_size(this->w, this->h, this->bytes_per_line, this->color_model); + int size = calculate_data_size(this->w, + this->h, + this->bytes_per_line, + this->color_model); this->data = new unsigned char[size]; if(size > 2560 * 1920) @@ -346,7 +349,14 @@ int VFrame::reallocate(unsigned char *data, { clear_objects(); reset_parameters(); - allocate_data(data, y_offset, u_offset, v_offset, w, h, color_model, bytes_per_line); + allocate_data(data, + y_offset, + u_offset, + v_offset, + w, + h, + color_model, + bytes_per_line); return 0; } @@ -578,125 +588,13 @@ void VFrame::flip_vert() } -#define APPLY_FADE(equivalent, input_rows, output_rows, max, type, chroma_zero, components) \ -{ \ - int64_t opacity = (int64_t)(alpha * max); \ - int64_t transparency = (int64_t)(max - opacity); \ - \ - for(int i = 0; i < h; i++) \ - { \ - type *in_row = (type*)input_rows[i]; \ - type *out_row = (type*)output_rows[i]; \ - \ - for(int j = 0; j < w; j++) \ - { \ - if(components == 3) \ - { \ - out_row[j * components] = \ - (type)((int64_t)in_row[j * components] * opacity / max); \ - out_row[j * components + 1] = \ - (type)(((int64_t)in_row[j * components + 1] * opacity + \ - (int64_t)chroma_zero * transparency) / max); \ - out_row[j * components + 2] = \ - (type)(((int64_t)in_row[j * components + 2] * opacity + \ - (int64_t)chroma_zero * transparency) / max); \ - } \ - else \ - { \ - if(!equivalent) \ - { \ - out_row[j * components] = in_row[j * components]; \ - out_row[j * components + 1] = in_row[j * components + 1]; \ - out_row[j * components + 2] = in_row[j * components + 2]; \ - } \ - \ - out_row[j * components + 3] = \ - (type)((int64_t)in_row[j * components + 3] * opacity / max); \ - } \ - } \ - } \ -} - - -// Fade the frame but don't move data around -int VFrame::apply_fade(float alpha) -{ -printf("VFrame::apply_fade: Never call this. Use FadeEngine instead.\n"); - if(alpha != 1) - { - switch(color_model) - { - case BC_RGB888: - APPLY_FADE(1, rows, rows, 0xff, unsigned char, 0x0, 3); - break; - case BC_RGBA8888: - APPLY_FADE(1, rows, rows, 0xff, unsigned char, 0x0, 4); - break; - case BC_RGB161616: - APPLY_FADE(1, rows, rows, 0xffff, uint16_t, 0x0, 3); - break; - case BC_RGBA16161616: - APPLY_FADE(1, rows, rows, 0xffff, uint16_t, 0x0, 4); - break; - case BC_YUV888: - APPLY_FADE(1, rows, rows, 0xff, unsigned char, 0x80, 3); - break; - case BC_YUVA8888: - APPLY_FADE(1, rows, rows, 0xff, unsigned char, 0x80, 4); - break; - case BC_YUV161616: - APPLY_FADE(1, rows, rows, 0xffff, uint16_t, 0x8000, 3); - break; - case BC_YUVA16161616: - APPLY_FADE(1, rows, rows, 0xffff, uint16_t, 0x8000, 4); - break; - } - } - return 0; -} - -// Fade the frame while moving data around -int VFrame::replace_from(VFrame *frame, float alpha) -{ -printf("VFrame::replace_from: Never call this. Use FadeEngine instead.\n"); - if(alpha != 1) - { - switch(color_model) - { - case BC_RGB888: - APPLY_FADE(0, rows, frame->get_rows(), 0xff, unsigned char, 0x0, 3); - break; - case BC_RGBA8888: - APPLY_FADE(0, rows, frame->get_rows(), 0xff, unsigned char, 0x0, 4); - break; - case BC_RGB161616: - APPLY_FADE(0, rows, frame->get_rows(), 0xffff, uint16_t, 0x0, 3); - break; - case BC_RGBA16161616: - APPLY_FADE(0, rows, frame->get_rows(), 0xffff, uint16_t, 0x0, 4); - break; - case BC_YUV888: - APPLY_FADE(0, rows, frame->get_rows(), 0xff, unsigned char, 0x80, 3); - break; - case BC_YUVA8888: - APPLY_FADE(0, rows, frame->get_rows(), 0xff, unsigned char, 0x80, 4); - break; - case BC_YUV161616: - APPLY_FADE(0, rows, frame->get_rows(), 0xffff, uint16_t, 0x8000, 3); - break; - case BC_YUVA16161616: - APPLY_FADE(0, rows, frame->get_rows(), 0xffff, uint16_t, 0x8000, 4); - break; - } - } - else - copy_from(frame); - - return 0; -} int VFrame::copy_from(VFrame *frame) { + int w = MIN(this->w, frame->get_w()); + int h = MIN(this->h, frame->get_h()); + + switch(frame->color_model) { case BC_COMPRESSED: diff --git a/hvirtual/guicast/vframe.h b/hvirtual/guicast/vframe.h index 40cff7af..6131d7d5 100644 --- a/hvirtual/guicast/vframe.h +++ b/hvirtual/guicast/vframe.h @@ -69,10 +69,6 @@ public: // direct copy with no alpha int copy_from(VFrame *frame); -// Direct copy with alpha from 0 to 1. - int replace_from(VFrame *frame, float alpha); - - int apply_fade(float alpha); // Required for YUV int clear_frame(); int allocate_compressed_data(long bytes); diff --git a/hvirtual/libmpeg3/libmpeg3.c b/hvirtual/libmpeg3/libmpeg3.c index 79c7a6ee..681bc46d 100644 --- a/hvirtual/libmpeg3/libmpeg3.c +++ b/hvirtual/libmpeg3/libmpeg3.c @@ -613,7 +613,7 @@ mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) -//printf("mpeg3_open 1\n"); +//printf("mpeg3_open 1 %d\n", file->demuxer->total_titles); /* Create titles */ /* Copy timecodes from an old demuxer */ diff --git a/hvirtual/libmpeg3/mpeg3css.c b/hvirtual/libmpeg3/mpeg3css.c index 51802d16..b898e9e9 100644 --- a/hvirtual/libmpeg3/mpeg3css.c +++ b/hvirtual/libmpeg3/mpeg3css.c @@ -1,24 +1,1025 @@ -/* Stubs for deCSS which can't be distributed in source form */ +/* + * Copyright (C) 2000 Derek Fawcus et. al. + * Ported to libmpeg3 by et. al. + * + * This code may be used under the terms of Version 2 of the GPL, + * read the file COPYING for details. + * + */ + +/* + * These routines do some reordering of the supplied data before + * calling engine() to do the main work. + * + * The reordering seems similar to that done by the initial stages of + * the DES algorithm, in that it looks like it's just been done to + * try and make software decoding slower. I'm not sure that it + * actually adds anything to the security. + * + * The nature of the shuffling is that the bits of the supplied + * parameter 'varient' are reorganised (and some inverted), and + * the bytes of the parameter 'challenge' are reorganised. + * + * The reorganisation in each routine is different, and the first + * (CryptKey1) does not bother of play with the 'varient' parameter. + * + * Since this code is only run once per disk change, I've made the + * code table driven in order to improve readability. + * + * Since these routines are so similar to each other, one could even + * abstract them all to one routine supplied a parameter determining + * the nature of the reordering it has to do. + */ + + +#ifdef HAVE_CSS #include "mpeg3css.h" #include "mpeg3private.h" -mpeg3_css_t* mpeg3_new_css() +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef FIBMAP +#define FIBMAP _IO(0x00,1) /* bmap access */ +//#define FIBMAP 1 +#endif + +/* =================================== TABLES ================================ */ + +static unsigned char mpeg3css_varients[] = +{ + 0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73, + 0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42, + 0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B, + 0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 +}; + +static unsigned char mpeg3css_secret[] = {0x55, 0xD6, 0xC4, 0xC5, 0x28}; + +static unsigned char mpeg3css_table0[] = +{ + 0xB7, 0xF4, 0x82, 0x57, 0xDA, 0x4D, 0xDB, 0xE2, + 0x2F, 0x52, 0x1A, 0xA8, 0x68, 0x5A, 0x8A, 0xFF, + 0xFB, 0x0E, 0x6D, 0x35, 0xF7, 0x5C, 0x76, 0x12, + 0xCE, 0x25, 0x79, 0x29, 0x39, 0x62, 0x08, 0x24, + 0xA5, 0x85, 0x7B, 0x56, 0x01, 0x23, 0x68, 0xCF, + 0x0A, 0xE2, 0x5A, 0xED, 0x3D, 0x59, 0xB0, 0xA9, + 0xB0, 0x2C, 0xF2, 0xB8, 0xEF, 0x32, 0xA9, 0x40, + 0x80, 0x71, 0xAF, 0x1E, 0xDE, 0x8F, 0x58, 0x88, + 0xB8, 0x3A, 0xD0, 0xFC, 0xC4, 0x1E, 0xB5, 0xA0, + 0xBB, 0x3B, 0x0F, 0x01, 0x7E, 0x1F, 0x9F, 0xD9, + 0xAA, 0xB8, 0x3D, 0x9D, 0x74, 0x1E, 0x25, 0xDB, + 0x37, 0x56, 0x8F, 0x16, 0xBA, 0x49, 0x2B, 0xAC, + 0xD0, 0xBD, 0x95, 0x20, 0xBE, 0x7A, 0x28, 0xD0, + 0x51, 0x64, 0x63, 0x1C, 0x7F, 0x66, 0x10, 0xBB, + 0xC4, 0x56, 0x1A, 0x04, 0x6E, 0x0A, 0xEC, 0x9C, + 0xD6, 0xE8, 0x9A, 0x7A, 0xCF, 0x8C, 0xDB, 0xB1, + 0xEF, 0x71, 0xDE, 0x31, 0xFF, 0x54, 0x3E, 0x5E, + 0x07, 0x69, 0x96, 0xB0, 0xCF, 0xDD, 0x9E, 0x47, + 0xC7, 0x96, 0x8F, 0xE4, 0x2B, 0x59, 0xC6, 0xEE, + 0xB9, 0x86, 0x9A, 0x64, 0x84, 0x72, 0xE2, 0x5B, + 0xA2, 0x96, 0x58, 0x99, 0x50, 0x03, 0xF5, 0x38, + 0x4D, 0x02, 0x7D, 0xE7, 0x7D, 0x75, 0xA7, 0xB8, + 0x67, 0x87, 0x84, 0x3F, 0x1D, 0x11, 0xE5, 0xFC, + 0x1E, 0xD3, 0x83, 0x16, 0xA5, 0x29, 0xF6, 0xC7, + 0x15, 0x61, 0x29, 0x1A, 0x43, 0x4F, 0x9B, 0xAF, + 0xC5, 0x87, 0x34, 0x6C, 0x0F, 0x3B, 0xA8, 0x1D, + 0x45, 0x58, 0x25, 0xDC, 0xA8, 0xA3, 0x3B, 0xD1, + 0x79, 0x1B, 0x48, 0xF2, 0xE9, 0x93, 0x1F, 0xFC, + 0xDB, 0x2A, 0x90, 0xA9, 0x8A, 0x3D, 0x39, 0x18, + 0xA3, 0x8E, 0x58, 0x6C, 0xE0, 0x12, 0xBB, 0x25, + 0xCD, 0x71, 0x22, 0xA2, 0x64, 0xC6, 0xE7, 0xFB, + 0xAD, 0x94, 0x77, 0x04, 0x9A, 0x39, 0xCF, 0x7C +}; + +static unsigned char mpeg3css_table1[] = +{ + 0x8C, 0x47, 0xB0, 0xE1, 0xEB, 0xFC, 0xEB, 0x56, + 0x10, 0xE5, 0x2C, 0x1A, 0x5D, 0xEF, 0xBE, 0x4F, + 0x08, 0x75, 0x97, 0x4B, 0x0E, 0x25, 0x8E, 0x6E, + 0x39, 0x5A, 0x87, 0x53, 0xC4, 0x1F, 0xF4, 0x5C, + 0x4E, 0xE6, 0x99, 0x30, 0xE0, 0x42, 0x88, 0xAB, + 0xE5, 0x85, 0xBC, 0x8F, 0xD8, 0x3C, 0x54, 0xC9, + 0x53, 0x47, 0x18, 0xD6, 0x06, 0x5B, 0x41, 0x2C, + 0x67, 0x1E, 0x41, 0x74, 0x33, 0xE2, 0xB4, 0xE0, + 0x23, 0x29, 0x42, 0xEA, 0x55, 0x0F, 0x25, 0xB4, + 0x24, 0x2C, 0x99, 0x13, 0xEB, 0x0A, 0x0B, 0xC9, + 0xF9, 0x63, 0x67, 0x43, 0x2D, 0xC7, 0x7D, 0x07, + 0x60, 0x89, 0xD1, 0xCC, 0xE7, 0x94, 0x77, 0x74, + 0x9B, 0x7E, 0xD7, 0xE6, 0xFF, 0xBB, 0x68, 0x14, + 0x1E, 0xA3, 0x25, 0xDE, 0x3A, 0xA3, 0x54, 0x7B, + 0x87, 0x9D, 0x50, 0xCA, 0x27, 0xC3, 0xA4, 0x50, + 0x91, 0x27, 0xD4, 0xB0, 0x82, 0x41, 0x97, 0x79, + 0x94, 0x82, 0xAC, 0xC7, 0x8E, 0xA5, 0x4E, 0xAA, + 0x78, 0x9E, 0xE0, 0x42, 0xBA, 0x28, 0xEA, 0xB7, + 0x74, 0xAD, 0x35, 0xDA, 0x92, 0x60, 0x7E, 0xD2, + 0x0E, 0xB9, 0x24, 0x5E, 0x39, 0x4F, 0x5E, 0x63, + 0x09, 0xB5, 0xFA, 0xBF, 0xF1, 0x22, 0x55, 0x1C, + 0xE2, 0x25, 0xDB, 0xC5, 0xD8, 0x50, 0x03, 0x98, + 0xC4, 0xAC, 0x2E, 0x11, 0xB4, 0x38, 0x4D, 0xD0, + 0xB9, 0xFC, 0x2D, 0x3C, 0x08, 0x04, 0x5A, 0xEF, + 0xCE, 0x32, 0xFB, 0x4C, 0x92, 0x1E, 0x4B, 0xFB, + 0x1A, 0xD0, 0xE2, 0x3E, 0xDA, 0x6E, 0x7C, 0x4D, + 0x56, 0xC3, 0x3F, 0x42, 0xB1, 0x3A, 0x23, 0x4D, + 0x6E, 0x84, 0x56, 0x68, 0xF4, 0x0E, 0x03, 0x64, + 0xD0, 0xA9, 0x92, 0x2F, 0x8B, 0xBC, 0x39, 0x9C, + 0xAC, 0x09, 0x5E, 0xEE, 0xE5, 0x97, 0xBF, 0xA5, + 0xCE, 0xFA, 0x28, 0x2C, 0x6D, 0x4F, 0xEF, 0x77, + 0xAA, 0x1B, 0x79, 0x8E, 0x97, 0xB4, 0xC3, 0xF4 +}; + +static unsigned char mpeg3css_table2[] = +{ + 0xB7, 0x75, 0x81, 0xD5, 0xDC, 0xCA, 0xDE, 0x66, + 0x23, 0xDF, 0x15, 0x26, 0x62, 0xD1, 0x83, 0x77, + 0xE3, 0x97, 0x76, 0xAF, 0xE9, 0xC3, 0x6B, 0x8E, + 0xDA, 0xB0, 0x6E, 0xBF, 0x2B, 0xF1, 0x19, 0xB4, + 0x95, 0x34, 0x48, 0xE4, 0x37, 0x94, 0x5D, 0x7B, + 0x36, 0x5F, 0x65, 0x53, 0x07, 0xE2, 0x89, 0x11, + 0x98, 0x85, 0xD9, 0x12, 0xC1, 0x9D, 0x84, 0xEC, + 0xA4, 0xD4, 0x88, 0xB8, 0xFC, 0x2C, 0x79, 0x28, + 0xD8, 0xDB, 0xB3, 0x1E, 0xA2, 0xF9, 0xD0, 0x44, + 0xD7, 0xD6, 0x60, 0xEF, 0x14, 0xF4, 0xF6, 0x31, + 0xD2, 0x41, 0x46, 0x67, 0x0A, 0xE1, 0x58, 0x27, + 0x43, 0xA3, 0xF8, 0xE0, 0xC8, 0xBA, 0x5A, 0x5C, + 0x80, 0x6C, 0xC6, 0xF2, 0xE8, 0xAD, 0x7D, 0x04, + 0x0D, 0xB9, 0x3C, 0xC2, 0x25, 0xBD, 0x49, 0x63, + 0x8C, 0x9F, 0x51, 0xCE, 0x20, 0xC5, 0xA1, 0x50, + 0x92, 0x2D, 0xDD, 0xBC, 0x8D, 0x4F, 0x9A, 0x71, + 0x2F, 0x30, 0x1D, 0x73, 0x39, 0x13, 0xFB, 0x1A, + 0xCB, 0x24, 0x59, 0xFE, 0x05, 0x96, 0x57, 0x0F, + 0x1F, 0xCF, 0x54, 0xBE, 0xF5, 0x06, 0x1B, 0xB2, + 0x6D, 0xD3, 0x4D, 0x32, 0x56, 0x21, 0x33, 0x0B, + 0x52, 0xE7, 0xAB, 0xEB, 0xA6, 0x74, 0x00, 0x4C, + 0xB1, 0x7F, 0x82, 0x99, 0x87, 0x0E, 0x5E, 0xC0, + 0x8F, 0xEE, 0x6F, 0x55, 0xF3, 0x7E, 0x08, 0x90, + 0xFA, 0xB6, 0x64, 0x70, 0x47, 0x4A, 0x17, 0xA7, + 0xB5, 0x40, 0x8A, 0x38, 0xE5, 0x68, 0x3E, 0x8B, + 0x69, 0xAA, 0x9B, 0x42, 0xA5, 0x10, 0x01, 0x35, + 0xFD, 0x61, 0x9E, 0xE6, 0x16, 0x9C, 0x86, 0xED, + 0xCD, 0x2E, 0xFF, 0xC4, 0x5B, 0xA0, 0xAE, 0xCC, + 0x4B, 0x3B, 0x03, 0xBB, 0x1C, 0x2A, 0xAC, 0x0C, + 0x3F, 0x93, 0xC7, 0x72, 0x7A, 0x09, 0x22, 0x3D, + 0x45, 0x78, 0xA9, 0xA8, 0xEA, 0xC9, 0x6A, 0xF7, + 0x29, 0x91, 0xF0, 0x02, 0x18, 0x3A, 0x4E, 0x7C +}; + +static unsigned char mpeg3css_table3[] = +{ + 0x73, 0x51, 0x95, 0xE1, 0x12, 0xE4, 0xC0, 0x58, + 0xEE, 0xF2, 0x08, 0x1B, 0xA9, 0xFA, 0x98, 0x4C, + 0xA7, 0x33, 0xE2, 0x1B, 0xA7, 0x6D, 0xF5, 0x30, + 0x97, 0x1D, 0xF3, 0x02, 0x60, 0x5A, 0x82, 0x0F, + 0x91, 0xD0, 0x9C, 0x10, 0x39, 0x7A, 0x83, 0x85, + 0x3B, 0xB2, 0xB8, 0xAE, 0x0C, 0x09, 0x52, 0xEA, + 0x1C, 0xE1, 0x8D, 0x66, 0x4F, 0xF3, 0xDA, 0x92, + 0x29, 0xB9, 0xD5, 0xC5, 0x77, 0x47, 0x22, 0x53, + 0x14, 0xF7, 0xAF, 0x22, 0x64, 0xDF, 0xC6, 0x72, + 0x12, 0xF3, 0x75, 0xDA, 0xD7, 0xD7, 0xE5, 0x02, + 0x9E, 0xED, 0xDA, 0xDB, 0x4C, 0x47, 0xCE, 0x91, + 0x06, 0x06, 0x6D, 0x55, 0x8B, 0x19, 0xC9, 0xEF, + 0x8C, 0x80, 0x1A, 0x0E, 0xEE, 0x4B, 0xAB, 0xF2, + 0x08, 0x5C, 0xE9, 0x37, 0x26, 0x5E, 0x9A, 0x90, + 0x00, 0xF3, 0x0D, 0xB2, 0xA6, 0xA3, 0xF7, 0x26, + 0x17, 0x48, 0x88, 0xC9, 0x0E, 0x2C, 0xC9, 0x02, + 0xE7, 0x18, 0x05, 0x4B, 0xF3, 0x39, 0xE1, 0x20, + 0x02, 0x0D, 0x40, 0xC7, 0xCA, 0xB9, 0x48, 0x30, + 0x57, 0x67, 0xCC, 0x06, 0xBF, 0xAC, 0x81, 0x08, + 0x24, 0x7A, 0xD4, 0x8B, 0x19, 0x8E, 0xAC, 0xB4, + 0x5A, 0x0F, 0x73, 0x13, 0xAC, 0x9E, 0xDA, 0xB6, + 0xB8, 0x96, 0x5B, 0x60, 0x88, 0xE1, 0x81, 0x3F, + 0x07, 0x86, 0x37, 0x2D, 0x79, 0x14, 0x52, 0xEA, + 0x73, 0xDF, 0x3D, 0x09, 0xC8, 0x25, 0x48, 0xD8, + 0x75, 0x60, 0x9A, 0x08, 0x27, 0x4A, 0x2C, 0xB9, + 0xA8, 0x8B, 0x8A, 0x73, 0x62, 0x37, 0x16, 0x02, + 0xBD, 0xC1, 0x0E, 0x56, 0x54, 0x3E, 0x14, 0x5F, + 0x8C, 0x8F, 0x6E, 0x75, 0x1C, 0x07, 0x39, 0x7B, + 0x4B, 0xDB, 0xD3, 0x4B, 0x1E, 0xC8, 0x7E, 0xFE, + 0x3E, 0x72, 0x16, 0x83, 0x7D, 0xEE, 0xF5, 0xCA, + 0xC5, 0x18, 0xF9, 0xD8, 0x68, 0xAB, 0x38, 0x85, + 0xA8, 0xF0, 0xA1, 0x73, 0x9F, 0x5D, 0x19, 0x0B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x72, 0x39, 0x25, 0x67, 0x26, 0x6D, 0x71, + 0x36, 0x77, 0x3C, 0x20, 0x62, 0x23, 0x68, 0x74, + 0xC3, 0x82, 0xC9, 0x15, 0x57, 0x16, 0x5D, 0x81 +}; + +static struct mpeg3_playkey mpeg3_pkey1a1 = {0x36b, {0x51,0x67,0x67,0xc5,0xe0}}; +static struct mpeg3_playkey mpeg3_pkey2a1 = {0x762, {0x2c,0xb2,0xc1,0x09,0xee}}; +static struct mpeg3_playkey mpeg3_pkey1b1 = {0x36b, {0x90,0xc1,0xd7,0x84,0x48}}; + +static struct mpeg3_playkey mpeg3_pkey1a2 = {0x2f3, {0x51,0x67,0x67,0xc5,0xe0}}; +static struct mpeg3_playkey mpeg3_pkey2a2 = {0x730, {0x2c,0xb2,0xc1,0x09,0xee}}; +static struct mpeg3_playkey mpeg3_pkey1b2 = {0x2f3, {0x90,0xc1,0xd7,0x84,0x48}}; + +static struct mpeg3_playkey mpeg3_pkey1a3 = {0x235, {0x51,0x67,0x67,0xc5,0xe0}}; +static struct mpeg3_playkey mpeg3_pkey1b3 = {0x235, {0x90,0xc1,0xd7,0x84,0x48}}; + +static struct mpeg3_playkey mpeg3_pkey3a1 = {0x249, {0xb7,0x3f,0xd4,0xaa,0x14}}; /* DVD specific ? */ +static struct mpeg3_playkey mpeg3_pkey4a1 = {0x028, {0x53,0xd4,0xf7,0xd9,0x8f}}; /* DVD specific ? */ + +static struct mpeg3_playkey *mpeg3_playkeys[] = +{ + &mpeg3_pkey1a1, &mpeg3_pkey2a1, &mpeg3_pkey1b1, + &mpeg3_pkey1a2, &mpeg3_pkey2a2, &mpeg3_pkey1b2, + &mpeg3_pkey1a3, &mpeg3_pkey1b3, + &mpeg3_pkey3a1, &mpeg3_pkey4a1, + NULL +}; + +/* + * + * some tables used for descrambling sectors and/or decrypting title keys + * + */ + +static unsigned char csstab1[256]= +{ + 0x33,0x73,0x3b,0x26,0x63,0x23,0x6b,0x76,0x3e,0x7e,0x36,0x2b,0x6e,0x2e,0x66,0x7b, + 0xd3,0x93,0xdb,0x06,0x43,0x03,0x4b,0x96,0xde,0x9e,0xd6,0x0b,0x4e,0x0e,0x46,0x9b, + 0x57,0x17,0x5f,0x82,0xc7,0x87,0xcf,0x12,0x5a,0x1a,0x52,0x8f,0xca,0x8a,0xc2,0x1f, + 0xd9,0x99,0xd1,0x00,0x49,0x09,0x41,0x90,0xd8,0x98,0xd0,0x01,0x48,0x08,0x40,0x91, + 0x3d,0x7d,0x35,0x24,0x6d,0x2d,0x65,0x74,0x3c,0x7c,0x34,0x25,0x6c,0x2c,0x64,0x75, + 0xdd,0x9d,0xd5,0x04,0x4d,0x0d,0x45,0x94,0xdc,0x9c,0xd4,0x05,0x4c,0x0c,0x44,0x95, + 0x59,0x19,0x51,0x80,0xc9,0x89,0xc1,0x10,0x58,0x18,0x50,0x81,0xc8,0x88,0xc0,0x11, + 0xd7,0x97,0xdf,0x02,0x47,0x07,0x4f,0x92,0xda,0x9a,0xd2,0x0f,0x4a,0x0a,0x42,0x9f, + 0x53,0x13,0x5b,0x86,0xc3,0x83,0xcb,0x16,0x5e,0x1e,0x56,0x8b,0xce,0x8e,0xc6,0x1b, + 0xb3,0xf3,0xbb,0xa6,0xe3,0xa3,0xeb,0xf6,0xbe,0xfe,0xb6,0xab,0xee,0xae,0xe6,0xfb, + 0x37,0x77,0x3f,0x22,0x67,0x27,0x6f,0x72,0x3a,0x7a,0x32,0x2f,0x6a,0x2a,0x62,0x7f, + 0xb9,0xf9,0xb1,0xa0,0xe9,0xa9,0xe1,0xf0,0xb8,0xf8,0xb0,0xa1,0xe8,0xa8,0xe0,0xf1, + 0x5d,0x1d,0x55,0x84,0xcd,0x8d,0xc5,0x14,0x5c,0x1c,0x54,0x85,0xcc,0x8c,0xc4,0x15, + 0xbd,0xfd,0xb5,0xa4,0xed,0xad,0xe5,0xf4,0xbc,0xfc,0xb4,0xa5,0xec,0xac,0xe4,0xf5, + 0x39,0x79,0x31,0x20,0x69,0x29,0x61,0x70,0x38,0x78,0x30,0x21,0x68,0x28,0x60,0x71, + 0xb7,0xf7,0xbf,0xa2,0xe7,0xa7,0xef,0xf2,0xba,0xfa,0xb2,0xaf,0xea,0xaa,0xe2,0xff +}; + +static unsigned char lfsr1_bits0[256]= +{ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x49,0x48,0x4b,0x4a,0x4d,0x4c,0x4f,0x4e,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, + 0x5b,0x5a,0x59,0x58,0x5f,0x5e,0x5d,0x5c,0x52,0x53,0x50,0x51,0x56,0x57,0x54,0x55, + 0x6d,0x6c,0x6f,0x6e,0x69,0x68,0x6b,0x6a,0x64,0x65,0x66,0x67,0x60,0x61,0x62,0x63, + 0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x76,0x77,0x74,0x75,0x72,0x73,0x70,0x71, + 0x92,0x93,0x90,0x91,0x96,0x97,0x94,0x95,0x9b,0x9a,0x99,0x98,0x9f,0x9e,0x9d,0x9c, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x89,0x88,0x8b,0x8a,0x8d,0x8c,0x8f,0x8e, + 0xb6,0xb7,0xb4,0xb5,0xb2,0xb3,0xb0,0xb1,0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8, + 0xa4,0xa5,0xa6,0xa7,0xa0,0xa1,0xa2,0xa3,0xad,0xac,0xaf,0xae,0xa9,0xa8,0xab,0xaa, + 0xdb,0xda,0xd9,0xd8,0xdf,0xde,0xdd,0xdc,0xd2,0xd3,0xd0,0xd1,0xd6,0xd7,0xd4,0xd5, + 0xc9,0xc8,0xcb,0xca,0xcd,0xcc,0xcf,0xce,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, + 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf6,0xf7,0xf4,0xf5,0xf2,0xf3,0xf0,0xf1, + 0xed,0xec,0xef,0xee,0xe9,0xe8,0xeb,0xea,0xe4,0xe5,0xe6,0xe7,0xe0,0xe1,0xe2,0xe3 +}; + +static unsigned char lfsr1_bits1[512]= +{ + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff, + 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff +}; + +/* Reverse the order of the bits within a byte. + */ +static unsigned char bit_reverse[256]= +{ + 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0, + 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8, + 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4, + 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc, + 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2, + 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa, + 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6, + 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe, + 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1, + 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9, + 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5, + 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd, + 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3, + 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb, + 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7, + 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff +}; + +/* ================================= Functions ====================================== */ + +/* + * We use two LFSR's (seeded from some of the input data bytes) to + * generate two streams of pseudo-random bits. These two bit streams + * are then combined by simply adding with carry to generate a final + * sequence of pseudo-random bits which is stored in the buffer that + * 'output' points to the end of - len is the size of this buffer. + * + * The first LFSR is of degree 25, and has a polynomial of: + * x^13 + x^5 + x^4 + x^1 + 1 + * + * The second LSFR is of degree 17, and has a (primitive) polynomial of: + * x^15 + x^1 + 1 + * + * I don't know if these polynomials are primitive modulo 2, and thus + * represent maximal-period LFSR's. + * + * + * Note that we take the output of each LFSR from the new shifted in + * bit, not the old shifted out bit. Thus for ease of use the LFSR's + * are implemented in bit reversed order. + * + */ + +#define BIT0(x) ((x) & 1) +#define BIT1(x) (((x) >> 1) & 1) + +static void generate_bits(unsigned char *output, int len, struct mpeg3_block const *s) +{ + unsigned long lfsr0, lfsr1; + unsigned char carry; + + /* In order to ensure that the LFSR works we need to ensure that the + * initial values are non-zero. Thus when we initialise them from + * the seed, we ensure that a bit is set. + */ + lfsr0 = (s->b[0] << 17) | (s->b[1] << 9) | ((s->b[2] & ~7) << 1) | 8 | (s->b[2] & 7); + lfsr1 = (s->b[3] << 9) | 0x100 | s->b[4]; + + ++output; + + carry = 0; + do{ + int bit; + unsigned char val; + + for (bit = 0, val = 0; bit < 8; ++bit) + { + unsigned char o_lfsr0, o_lfsr1; /* Actually only 1 bit each */ + unsigned char combined; + + o_lfsr0 = ((lfsr0 >> 24) ^ (lfsr0 >> 21) ^ (lfsr0 >> 20) ^ (lfsr0 >> 12)) & 1; + lfsr0 = (lfsr0 << 1) | o_lfsr0; + + o_lfsr1 = ((lfsr1 >> 16) ^ (lfsr1 >> 2)) & 1; + lfsr1 = (lfsr1 << 1) | o_lfsr1; + + combined = !o_lfsr1 + carry + !o_lfsr0; + carry = BIT1(combined); + val |= BIT0(combined) << bit; + } + + *--output = val; + }while (--len > 0); +} + + +/* + * This encryption engine implements one of 32 variations + * one the same theme depending upon the choice in the + * varient parameter (0 - 31). + * + * The algorithm itself manipulates a 40 bit input into + * a 40 bit output. + * The parameter 'input' is 80 bits. It consists of + * the 40 bit input value that is to be encrypted followed + * by a 40 bit seed value for the pseudo random number + * generators. + */ +static void css_engine(int varient, unsigned char const *input, struct mpeg3_block *output) +{ + unsigned char cse, term, index; + struct mpeg3_block temp1; + struct mpeg3_block temp2; + unsigned char bits[30]; + + int i; + +/* Feed the secret into the input values such that + * we alter the seed to the LFSR's used above, then + * generate the bits to play with. + */ + for(i = 5; --i >= 0; ) + temp1.b[i] = input[5 + i] ^ mpeg3css_secret[i] ^ mpeg3css_table2[i]; + + generate_bits(&bits[29], sizeof bits, &temp1); + + /* This term is used throughout the following to + * select one of 32 different variations on the + * algorithm. + */ + cse = mpeg3css_varients[varient] ^ mpeg3css_table2[varient]; + + /* Now the actual blocks doing the encryption. Each + * of these works on 40 bits at a time and are quite + * similar. + */ + for(i = 5, term = 0; --i >= 0; term = input[i]) + { + index = bits[25 + i] ^ input[i]; + index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse; + + temp1.b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term; + } + temp1.b[4] ^= temp1.b[0]; + + for(i = 5, term = 0; --i >= 0; term = temp1.b[i]) + { + index = bits[20 + i] ^ temp1.b[i]; + index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse; + + temp2.b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term; + } + temp2.b[4] ^= temp2.b[0]; + + for (i = 5, term = 0; --i >= 0; term = temp2.b[i]) + { + index = bits[15 + i] ^ temp2.b[i]; + index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse; + index = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term; + + temp1.b[i] = mpeg3css_table0[index] ^ mpeg3css_table2[index]; + } + temp1.b[4] ^= temp1.b[0]; + + for (i = 5, term = 0; --i >= 0; term = temp1.b[i]) + { + index = bits[10 + i] ^ temp1.b[i]; + index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse; + + index = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term; + + temp2.b[i] = mpeg3css_table0[index] ^ mpeg3css_table2[index]; + } + temp2.b[4] ^= temp2.b[0]; + + for (i = 5, term = 0; --i >= 0; term = temp2.b[i]) + { + index = bits[5 + i] ^ temp2.b[i]; + index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse; + + temp1.b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term; + } + temp1.b[4] ^= temp1.b[0]; + + for (i = 5, term = 0; --i >= 0; term = temp1.b[i]) + { + index = bits[i] ^ temp1.b[i]; + index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse; + + output->b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term; + } +} + +static void crypt_key1(mpeg3_css_t *css, int varient, unsigned char const *challenge, struct mpeg3_block *key) { + static unsigned char perm_challenge[] = {1, 3, 0, 7, 5, 2, 9, 6, 4, 8}; + + unsigned char scratch[10]; + int i; + + for (i = 9; i >= 0; i--) + scratch[i] = challenge[perm_challenge[i]]; + + css_engine(varient, scratch, key); +} + +/* This shuffles the bits in varient to make perm_varient such that + * 4 -> !3 + * 3 -> 4 + * varient bits: 2 -> 0 perm_varient bits + * 1 -> 2 + * 0 -> !1 + */ +static void crypt_key2(mpeg3_css_t *css, int varient, unsigned char const *challenge, struct mpeg3_block *key) +{ + static unsigned char perm_challenge[] = {6, 1, 9, 3, 8, 5, 7, 4, 0, 2}; + + static unsigned char perm_varient[] = + { + 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d, + 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d, + 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05, + 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 + }; + + unsigned char scratch[10]; + int i; + + for(i = 9; i >= 0; i--) + scratch[i] = css->challenge[perm_challenge[i]]; + + css_engine(perm_varient[varient], scratch, key); +} + +/* This shuffles the bits in varient to make perm_varient such that + * 4 -> 0 + * 3 -> !1 + * varient bits: 2 -> !4 perm_varient bits + * 1 -> 2 + * 0 -> 3 + */ +static void crypt_bus_key(mpeg3_css_t *css, int varient, unsigned char const *challenge, struct mpeg3_block *key) +{ + static unsigned char perm_challenge[] = {4,0,3,5,7, 2,8,6,1,9}; + static unsigned char perm_varient[] = { + 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e, + 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c, + 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f, + 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d}; + + unsigned char scratch[10]; + int i; + + for(i = 9; i >= 0; i--) + scratch[i] = css->challenge[perm_challenge[i]]; + + css_engine(perm_varient[varient], scratch, key); +} + +static int get_asf(mpeg3_css_t *css) +{ + dvd_authinfo ai; + + ai.type = DVD_LU_SEND_ASF; + ai.lsasf.agid = 0; + ai.lsasf.asf = 0; + + if(ioctl(css->fd, DVD_AUTH, &ai)) + { +/* Exit here for a hard drive or unencrypted CD-ROM. */ + return 1; + } + return 0; } +static int authenticate_drive(mpeg3_css_t *css, const unsigned char *key) +{ + int i; + + for(i = 0; i < 5; i++) + css->key1.b[i] = key[4 - i]; + + for(i = 0; i < 32; ++i) + { + crypt_key1(css, i, css->challenge, &(css->keycheck)); + if(memcmp(css->keycheck.b, css->key1.b, 5) == 0) + { + css->varient = i; + return 0; + } + } + + if (css->varient == -1) return 1; + + return 0; +} + +/* Simulation of a non-CSS compliant host (i.e. the authentication fails, + * but idea is here for a real CSS compliant authentication scheme). */ +static int hostauth(mpeg3_css_t *css, dvd_authinfo *ai) +{ + int i; + + switch(ai->type) + { +/* Host data receive (host changes state) */ + case DVD_LU_SEND_AGID: + ai->type = DVD_HOST_SEND_CHALLENGE; + break; + + case DVD_LU_SEND_KEY1: +/* printf("Key 1: %02x %02x %02x %02x %02x\n", */ +/* ai->lsk.key[4], ai->lsk.key[3], ai->lsk.key[2], ai->lsk.key[1], ai->lsk.key[0]); */ + if(authenticate_drive(css, ai->lsk.key)) + { + ai->type = DVD_AUTH_FAILURE; + return 1; + } + ai->type = DVD_LU_SEND_CHALLENGE; + break; + + case DVD_LU_SEND_CHALLENGE: + for(i = 0; i < 10; i++) + css->challenge[i] = ai->hsc.chal[9-i]; + crypt_key2(css, css->varient, css->challenge, &(css->key2)); + ai->type = DVD_HOST_SEND_KEY2; + break; + +/* Host data send */ + case DVD_HOST_SEND_CHALLENGE: + for(i = 0; i < 10; i++) + ai->hsc.chal[9 - i] = css->challenge[i]; +/* Returning data, let LU change state */ + break; + + case DVD_HOST_SEND_KEY2: + for(i = 0; i < 5; i++) + { + ai->hsk.key[4 - i] = css->key2.b[i]; + } +/* printf("Key 2: %02x %02x %02x %02x %02x\n", */ +/* ai->hsk.key[4], ai->hsk.key[3], ai->hsk.key[2], ai->hsk.key[1], ai->hsk.key[0]); */ +/* Returning data, let LU change state */ + break; + + default: + fprintf(stderr, "Got invalid state %d\n", ai->type); + return 1; + } + + return 0; +} + +static int get_title_key(mpeg3_css_t *css, int agid, int lba, unsigned char *key) +{ + dvd_authinfo ai; + int i; + + ai.type = DVD_LU_SEND_TITLE_KEY; + + ai.lstk.agid = agid; + ai.lstk.lba = lba; + + if(ioctl(css->fd, DVD_AUTH, &ai)) + { + //perror("GetTitleKey"); + return 1; + } + + for (i = 0; i < 5; i++) + { + ai.lstk.title_key[i] ^= key[4 - (i % 5)]; + } + +/* Save the title key */ + for(i = 0; i < 5; i++) + { + css->title_key[i] = ai.lstk.title_key[i]; + } + + return 0; +} + +static int get_disk_key(mpeg3_css_t *css, int agid, unsigned char *key) +{ + dvd_struct s; + int index, i; + + s.type = DVD_STRUCT_DISCKEY; + s.disckey.agid = agid; + memset(s.disckey.value, 0, MPEG3_DVD_PACKET_SIZE); + if(ioctl(css->fd, DVD_READ_STRUCT, &s) < 0) + { + /*perror("get_disk_key"); */ + return 1; + } + + for(index = 0; index < sizeof s.disckey.value; index ++) + s.disckey.value[index] ^= key[4 - (index%5)]; + +/* Save disk key */ + for(i = 0; i < MPEG3_DVD_PACKET_SIZE; i++) + css->disk_key[i] = s.disckey.value[i]; + + return 0; +} + +static int validate(mpeg3_css_t *css, int lba, int do_title) +{ + dvd_authinfo ai; + dvd_struct dvds; + int result = 0; + int i, rv, tries, agid; + + memset(&ai, 0, sizeof (ai)); + memset(&dvds, 0, sizeof (dvds)); + + if(get_asf(css)) return 1; + +/* Init sequence, request AGID */ + for(tries = 1, rv = -1; rv == -1 && tries < 4; tries++) + { + ai.type = DVD_LU_SEND_AGID; + ai.lsa.agid = 0; + rv = ioctl(css->fd, DVD_AUTH, &ai); + if(rv == -1) + { +/* perror("validate: request AGID"); */ + ai.type = DVD_INVALIDATE_AGID; + ai.lsa.agid = 0; + ioctl(css->fd, DVD_AUTH, &ai); + } + } + if(tries >= 4) return 1; + + for(i = 0; i < 10; i++) css->challenge[i] = i; + +/* Send AGID to host */ + if(hostauth(css, &ai)) return 1; + +/* Get challenge from host */ + if(hostauth(css, &ai)) return 1; + agid = ai.lsa.agid; + +/* Send challenge to LU */ + if(ioctl(css->fd, DVD_AUTH, &ai) < 0) return 1; + +/* Get key1 from LU */ + if(ioctl(css->fd, DVD_AUTH, &ai) < 0) return 1; + +/* Send key1 to host */ + if(hostauth(css, &ai)) return 1; + +/* Get challenge from LU */ + if(ioctl(css->fd, DVD_AUTH, &ai) < 0) return 1; + +/* Send challenge to host */ + if(hostauth(css, &ai)) return 1; + +/* Get key2 from host */ + if(hostauth(css, &ai)) return 1; + +/* Send key2 to LU */ + if(ioctl(css->fd, DVD_AUTH, &ai) < 0) + { + perror("validate: Send key2 to LU"); + return 1; + } + + if(ai.type == DVD_AUTH_FAILURE) + { + fprintf(stderr, "validate: authorization failed\n"); + return 1; + } + memcpy(css->challenge, css->key1.b, 5); + memcpy(css->challenge + 5, css->key2.b, 5); + crypt_bus_key(css, css->varient, css->challenge, &(css->keycheck)); + + get_asf(css); + + if(do_title) + return get_title_key(css, agid, lba, css->keycheck.b); + else + return get_disk_key(css, agid, css->keycheck.b); + + return 0; +} + +static int validate_path(mpeg3_css_t *css, int do_title) +{ + int result = 0; + int lba = 0, file_fd; + + if(do_title) + { + if((file_fd = open(css->path, O_RDONLY)) == -1) + { + perror("validate_path: open"); + return 1; + } + + if(ioctl(file_fd, FIBMAP, &lba) != 0) + { + perror("validate_path: FIBMAP"); + close(file_fd); + return 1; + } + + close(file_fd); + } + + result = mpeg3io_device(css->path, css->device_path); + +//printf("validate_path 1 %d\n", result); + if(!result) result = (css->fd = open(css->device_path, O_RDONLY | O_NONBLOCK)) < 0; +//printf("validate_path 2 %d\n", result); + + if(!result) result = validate(css, lba, do_title); + +//printf("validate_path 3 %d\n", result); +/* Definitely encrypted if we got here. */ + + + if(!result) css->encrypted = 1; + + close(css->fd); + return result; +} + +/* + * + * this function is only used internally when decrypting title key + * + */ +static void title_key(unsigned char *key, unsigned char *im, unsigned char invert) +{ + unsigned int lfsr1_lo, lfsr1_hi, lfsr0, combined; + unsigned char o_lfsr0, o_lfsr1; + unsigned char k[5]; + int i; + + lfsr1_lo = im[0] | 0x100; + lfsr1_hi = im[1]; + + lfsr0 = ((im[4] << 17) | (im[3] << 9) | (im[2] << 1)) + 8 - (im[2]&7); + lfsr0 = (bit_reverse[lfsr0 & 0xff] << 24) | (bit_reverse[(lfsr0 >> 8) & 0xff] << 16) + | (bit_reverse[(lfsr0 >> 16) & 0xff] << 8) | bit_reverse[(lfsr0 >> 24) & 0xff]; + + combined = 0; + for (i = 0; i < 5; ++i) { + o_lfsr1 = lfsr1_bits0[lfsr1_hi] ^ lfsr1_bits1[lfsr1_lo]; + lfsr1_hi = lfsr1_lo>>1; + lfsr1_lo = ((lfsr1_lo&1)<<8) ^ o_lfsr1; + o_lfsr1 = bit_reverse[o_lfsr1]; + + /*o_lfsr0 = (lfsr0>>7)^(lfsr0>>10)^(lfsr0>>11)^(lfsr0>>19);*/ + o_lfsr0 = (((((((lfsr0>>8)^lfsr0)>>1)^lfsr0)>>3)^lfsr0)>>7); + lfsr0 = (lfsr0>>8)|(o_lfsr0<<24); + + combined += (o_lfsr0 ^ invert) + o_lfsr1; + k[i] = combined & 0xff; + combined >>= 8; + } + + key[4] = k[4] ^ csstab1[key[4]] ^ key[3]; + key[3] = k[3] ^ csstab1[key[3]] ^ key[2]; + key[2] = k[2] ^ csstab1[key[2]] ^ key[1]; + key[1] = k[1] ^ csstab1[key[1]] ^ key[0]; + key[0] = k[0] ^ csstab1[key[0]] ^ key[4]; + + key[4] = k[4] ^ csstab1[key[4]] ^ key[3]; + key[3] = k[3] ^ csstab1[key[3]] ^ key[2]; + key[2] = k[2] ^ csstab1[key[2]] ^ key[1]; + key[1] = k[1] ^ csstab1[key[1]] ^ key[0]; + key[0] = k[0] ^ csstab1[key[0]]; +} + +/* + * + * this function decrypts a title key with the specified disk key + * + * tkey: the unobfuscated title key (XORed with BusKey) + * dkey: the unobfuscated disk key (XORed with BusKey) + * 2048 bytes in length (though only 5 bytes are needed, see below) + * + * use the result returned in tkey with css_descramble + * + */ + +static int decrypt_title_key(mpeg3_css_t *css, unsigned char *dkey, unsigned char *tkey) +{ + unsigned char test[5], pretkey[5]; + int i = 0; + + for(i = 0; mpeg3_playkeys[i]; i++) + { + memcpy(pretkey, dkey + mpeg3_playkeys[i]->offset, 5); + title_key(pretkey, mpeg3_playkeys[i]->key, 0); + + memcpy(test, dkey, 5); + title_key(test, pretkey, 0); + + if(memcmp(test, pretkey, 5) == 0) + break; + } + + if(!mpeg3_playkeys[i]) + { + fprintf(stderr, "mpeg3_decrypttitlekey: Shit - Need key %d\n", i + 1); + return 1; + } + + title_key(css->title_key, pretkey, 0xff); + + return 0; +} + +/* + * + * The descrambling core + * + * sec: encrypted sector (2048 bytes) + * key: decrypted title key obtained from css_decrypttitlekey + * + */ + +#define SALTED(i) (key[i] ^ sec[0x54 - offset + (i)]) + +static void descramble(unsigned char *sec, unsigned char *key, int offset) +{ + unsigned int lfsr1_lo, lfsr1_hi, lfsr0, combined; + unsigned char o_lfsr0, o_lfsr1; + unsigned char *end = sec + 0x800 - offset; + + if(offset > 0x54) + fprintf(stderr, "mpeg3css.c: descramble: offset > 0x54 offset=%x\n", offset); + + lfsr1_lo = SALTED(0) | 0x100; + lfsr1_hi = SALTED(1); + + lfsr0 = ((SALTED(4) << 17) | (SALTED(3) << 9) | (SALTED(2) << 1)) + 8 - (SALTED(2) & 7); + lfsr0 = (bit_reverse[lfsr0 & 0xff] << 24) | (bit_reverse[(lfsr0 >> 8) & 0xff] << 16) + | (bit_reverse[(lfsr0 >> 16) & 0xff] << 8) | bit_reverse[(lfsr0 >> 24) & 0xff]; + + sec += 0x80 - offset; + combined = 0; + while(sec != end) + { + o_lfsr1 = lfsr1_bits0[lfsr1_hi] ^ lfsr1_bits1[lfsr1_lo]; + lfsr1_hi = lfsr1_lo >> 1; + lfsr1_lo = ((lfsr1_lo&1) << 8) ^ o_lfsr1; + o_lfsr1 = bit_reverse[o_lfsr1]; + + /*o_lfsr0 = (lfsr0 >> 7) ^ (lfsr0 >> 10) ^ (lfsr0 >> 11) ^ (lfsr0 >> 19);*/ + o_lfsr0 = (((((((lfsr0 >> 8) ^ lfsr0) >> 1) ^ lfsr0) >> 3) ^ lfsr0) >> 7); + lfsr0 = (lfsr0 >> 8) | (o_lfsr0 << 24); + + combined += o_lfsr0 + (unsigned char)~o_lfsr1; + + *sec = csstab1[*sec] ^ (combined & 0xff); + sec++; + + combined >>= 8; + } +//printf("descramble\n"); +} + +/* =============================== Entry Points ================================= */ + +mpeg3_css_t* mpeg3_new_css() +{ + mpeg3_css_t *css = calloc(1, sizeof(mpeg3_css_t)); + css->varient = -1; + return css; +} + int mpeg3_delete_css(mpeg3_css_t *css) { + free(css); return 0; } int mpeg3_get_keys(mpeg3_css_t *css, char *path) { - return 1; + int result = 0; + + strcpy(css->path, path); +/* Get disk key */ + result = validate_path(css, 0); +/* Get title key */ + if(!result) result = validate_path(css, 1); +/* Descramble the title key */ + if(!result) result = decrypt_title_key(css, css->disk_key, css->title_key); + + return css->encrypted ? result : 0; } -int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector) +/* sector is the full 2048 byte sector */ +int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector, int offset) { - return 1; +//printf("mpeg3_decrypt_packet %d\n", css->encrypted); + if(!css->encrypted) return 0; /* Not encrypted */ + descramble(sector, css->title_key, offset); + return 0; } + +#else // HAVE_CSS + +#include "mpeg3css_fake.c" + +#endif diff --git a/hvirtual/libmpeg3/mpeg3demux.c b/hvirtual/libmpeg3/mpeg3demux.c index 0fa65e7b..7799e0eb 100644 --- a/hvirtual/libmpeg3/mpeg3demux.c +++ b/hvirtual/libmpeg3/mpeg3demux.c @@ -471,7 +471,9 @@ demuxer->dump = 0; //printf("read_transport 4 %x\n", demuxer->pid); if(demuxer->transport_error_indicator) { - fprintf(stderr, "demuxer->transport_error_indicator\n"); + fprintf(stderr, + "demuxer->transport_error_indicator at %llx\n", + mpeg3io_tell(title->fs)); demuxer->absolute_byte = mpeg3io_tell(title->fs) + title->start_byte; return 1; @@ -556,14 +558,12 @@ demuxer->dump = 0; - if(demuxer->adaptation_field_control == 2 || - demuxer->adaptation_field_control == 3) + if(demuxer->adaptation_field_control & 0x2) result = get_adaptation_field(demuxer); // Need to enter in astream and vstream table: // PID ored with stream_id - if(demuxer->adaptation_field_control == 1 || - demuxer->adaptation_field_control == 3) + if(demuxer->adaptation_field_control & 0x1) result = get_payload(demuxer); demuxer->absolute_byte = mpeg3io_tell(title->fs) + diff --git a/hvirtual/libmpeg3/mpeg3title.c b/hvirtual/libmpeg3/mpeg3title.c index 3e713ec6..b64abf0d 100644 --- a/hvirtual/libmpeg3/mpeg3title.c +++ b/hvirtual/libmpeg3/mpeg3title.c @@ -187,6 +187,7 @@ int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, title->end_byte = title->total_bytes; +//printf("mpeg3demux_create_title 1 %d %d\n", file->is_transport_stream, file->is_program_stream, toc); /* Get information about file */ if(file->is_transport_stream || file->is_program_stream) @@ -200,7 +201,11 @@ int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, /* Just get the first bytes if not building a toc to get the stream ID's. */ if(next_byte > 0x1000000 && (!cell_search || !toc)) done = 1; -//printf("mpeg3demux_create_title 1 %lld %d %p\n", next_byte, cell_search, toc); +/* + * printf("mpeg3demux_create_title 3 %lld %d %p\n", next_byte, cell_search, toc); + * printf("mpeg3demux_create_title 4 %d %d %d\n", + * done, result, mpeg3io_eof(title->fs)); + */ } /* Get the last cell */ diff --git a/hvirtual/plugins/aging/aging.C b/hvirtual/plugins/aging/aging.C index 3e0c1bc8..9210bfc2 100644 --- a/hvirtual/plugins/aging/aging.C +++ b/hvirtual/plugins/aging/aging.C @@ -167,35 +167,41 @@ AgingClient::AgingClient(AgingServer *server) #define COLORAGE(type, components) \ { \ - type a, b; \ + int a, b; \ int i, j, k; \ \ for(i = 0; i < h; i++) \ { \ for(j = 0; j < w; j++) \ { \ - for(k = 0; k < components; k++) \ + for(k = 0; k < 3; k++) \ { \ - a = ((type**)input_rows)[i][j * components + k]; \ + if(sizeof(type) == 4) \ + { \ + a = (int)(((type**)input_rows)[i][j * components + k] * 0xffff); \ + CLAMP(a, 0, 0xffff); \ + } \ + else \ + a = (int)((type**)input_rows)[i][j * components + k]; \ \ - if(k < 3) \ + if(sizeof(type) == 4) \ { \ - if(sizeof(type) == 2) \ - { \ - b = (a & 0xffff) >> 2; \ - ((type**)output_rows)[i][j * components + k] = \ - a - b + 0x1800 + (EffectTV::fastrand() & 0x1000); \ - } \ - else \ - { \ - b = (a & 0xff) >> 2; \ - ((type**)output_rows)[i][j * components + k] = \ - a - b + 0x18 + ((EffectTV::fastrand() >> 8) & 0x10); \ - } \ + b = (a & 0xffff) >> 2; \ + ((type**)output_rows)[i][j * components + k] = \ + (type)(a - b + 0x1800 + (EffectTV::fastrand() & 0x1000)) / 0xffff; \ } \ else \ + if(sizeof(type) == 2) \ { \ - ((type**)output_rows)[i][j * components + k] = a; \ + b = (a & 0xffff) >> 2; \ + ((type**)output_rows)[i][j * components + k] = \ + (type)(a - b + 0x1800 + (EffectTV::fastrand() & 0x1000)); \ + } \ + else \ + { \ + b = (a & 0xff) >> 2; \ + ((type**)output_rows)[i][j * components + k] = \ + (type)(a - b + 0x18 + ((EffectTV::fastrand() >> 8) & 0x10)); \ } \ } \ } \ @@ -215,6 +221,14 @@ void AgingClient::coloraging(unsigned char **output_rows, COLORAGE(uint8_t, 3); break; + case BC_RGB_FLOAT: + COLORAGE(float, 3); + break; + + case BC_RGBA_FLOAT: + COLORAGE(float, 4); + break; + case BC_RGBA8888: case BC_YUVA8888: COLORAGE(uint8_t, 4); @@ -240,7 +254,8 @@ void AgingClient::coloraging(unsigned char **output_rows, #define SCRATCHES(type, components, chroma) \ { \ int i, j, y, y1, y2; \ - type *p, a, b; \ + type *p; \ + int a, b; \ int w_256 = w * 256; \ \ for(i = 0; i < plugin->config.scratch_lines; i++) \ @@ -282,19 +297,31 @@ void AgingClient::coloraging(unsigned char **output_rows, { \ for(j = 0; j < (chroma ? 1 : 3); j++) \ { \ + if(sizeof(type) == 4) \ + { \ + int temp = (int)(p[j] * 0xffff); \ + CLAMP(temp, 0, 0xffff); \ + a = temp & 0xfeff; \ + a += 0x2000; \ + b = a & 0x10000; \ + p[j] = (type)(a | (b - (b >> 8))) / 0xffff; \ + } \ + else \ if(sizeof(type) == 2) \ { \ - a = p[j] & 0xfeff; \ + int temp = (int)p[j]; \ + a = temp & 0xfeff; \ a += 0x2000; \ b = a & 0x10000; \ - p[j] = a | (b - (b >> 8)); \ + p[j] = (type)(a | (b - (b >> 8))); \ } \ else \ { \ - a = p[j] & 0xfe; \ + int temp = (int)p[j]; \ + a = temp & 0xfe; \ a += 0x20; \ b = a & 0x100; \ - p[j] = a | (b - (b >> 8)); \ + p[j] = (type)(a | (b - (b >> 8))); \ } \ } \ \ @@ -332,10 +359,18 @@ void AgingClient::scratching(unsigned char **output_rows, SCRATCHES(uint8_t, 3, 0); break; + case BC_RGB_FLOAT: + SCRATCHES(float, 3, 0); + break; + case BC_YUV888: SCRATCHES(uint8_t, 3, 0x80); break; + case BC_RGBA_FLOAT: + SCRATCHES(float, 4, 0); + break; + case BC_RGBA8888: SCRATCHES(uint8_t, 4, 0); break; @@ -364,7 +399,7 @@ void AgingClient::scratching(unsigned char **output_rows, -#define PITS(type, components, chroma) \ +#define PITS(type, components, luma, chroma) \ { \ int i, j, k; \ int pnum, size, pnumscale; \ @@ -401,7 +436,9 @@ void AgingClient::scratching(unsigned char **output_rows, CLAMP(x, 0, w - 1); \ CLAMP(y, 0, h - 1); \ for(k = 0; k < (chroma ? 1 : 3); k++) \ - ((type**)output_rows)[y][x * components + k] = 0xc0; \ + { \ + ((type**)output_rows)[y][x * components + k] = luma; \ + } \ \ if(chroma) \ { \ @@ -426,37 +463,43 @@ void AgingClient::pits(unsigned char **output_rows, switch(color_model) { case BC_RGB888: - PITS(uint8_t, 3, 0); + PITS(uint8_t, 3, 0xc0, 0); + break; + case BC_RGB_FLOAT: + PITS(float, 3, (float)0xc0 / 0xff, 0); break; case BC_YUV888: - PITS(uint8_t, 3, 0x80); + PITS(uint8_t, 3, 0xc0, 0x80); break; + case BC_RGBA_FLOAT: + PITS(float, 4, (float)0xc0 / 0xff, 0); + break; case BC_RGBA8888: - PITS(uint8_t, 4, 0); + PITS(uint8_t, 4, 0xc0, 0); break; case BC_YUVA8888: - PITS(uint8_t, 4, 0x80); + PITS(uint8_t, 4, 0xc0, 0x80); break; case BC_RGB161616: - PITS(uint16_t, 3, 0); + PITS(uint16_t, 3, 0xc000, 0); break; case BC_YUV161616: - PITS(uint16_t, 3, 0x8000); + PITS(uint16_t, 3, 0xc000, 0x8000); break; case BC_RGBA16161616: - PITS(uint16_t, 4, 0); + PITS(uint16_t, 4, 0xc000, 0); break; case BC_YUVA16161616: - PITS(uint16_t, 4, 0x8000); + PITS(uint16_t, 4, 0xc000, 0x8000); break; } } -#define DUSTS(type, components, chroma) \ +#define DUSTS(type, components, luma, chroma) \ { \ int i, j, k; \ int dnum; \ @@ -486,7 +529,9 @@ void AgingClient::pits(unsigned char **output_rows, CLAMP(x, 0, w - 1); \ CLAMP(y, 0, h - 1); \ for(k = 0; k < (chroma ? 1 : 3); k++) \ - ((type**)output_rows)[y][x * components + k] = 0x10; \ + { \ + ((type**)output_rows)[y][x * components + k] = luma; \ + } \ \ if(chroma) \ { \ @@ -518,35 +563,43 @@ void AgingClient::dusts(unsigned char **output_rows, switch(color_model) { case BC_RGB888: - DUSTS(uint8_t, 3, 0); + DUSTS(uint8_t, 3, 0x10, 0); + break; + + case BC_RGB_FLOAT: + DUSTS(float, 3, (float)0x10 / 0xff, 0); break; case BC_YUV888: - DUSTS(uint8_t, 3, 0x80); + DUSTS(uint8_t, 3, 0x10, 0x80); break; + case BC_RGBA_FLOAT: + DUSTS(float, 4, (float)0x10 / 0xff, 0); + break; + case BC_RGBA8888: - DUSTS(uint8_t, 4, 0); + DUSTS(uint8_t, 4, 0x10, 0); break; case BC_YUVA8888: - DUSTS(uint8_t, 4, 0x80); + DUSTS(uint8_t, 4, 0x10, 0x80); break; case BC_RGB161616: - DUSTS(uint16_t, 3, 0); + DUSTS(uint16_t, 3, 0x1000, 0); break; case BC_YUV161616: - DUSTS(uint16_t, 3, 0x8000); + DUSTS(uint16_t, 3, 0x1000, 0x8000); break; case BC_RGBA16161616: - DUSTS(uint16_t, 4, 0); + DUSTS(uint16_t, 4, 0x1000, 0); break; case BC_YUVA16161616: - DUSTS(uint16_t, 4, 0x8000); + DUSTS(uint16_t, 4, 0x1000, 0x8000); break; } } diff --git a/hvirtual/plugins/aging/agingwindow.C b/hvirtual/plugins/aging/agingwindow.C index 66090f4e..052513a6 100644 --- a/hvirtual/plugins/aging/agingwindow.C +++ b/hvirtual/plugins/aging/agingwindow.C @@ -60,12 +60,7 @@ int AgingWindow::create_objects() return 0; } -int AgingWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(AgingWindow) diff --git a/hvirtual/plugins/bandslide/bandslide.C b/hvirtual/plugins/bandslide/bandslide.C index 3817ea2a..3d3fd51b 100644 --- a/hvirtual/plugins/bandslide/bandslide.C +++ b/hvirtual/plugins/bandslide/bandslide.C @@ -3,6 +3,7 @@ #include "defaults.h" #include "edl.inc" #include "filexml.h" +#include "language.h" #include "overlayframe.h" #include "picon_png.h" #include "vframe.h" @@ -11,9 +12,6 @@ #include #include #include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -361,10 +359,16 @@ int BandSlideMain::process_realtime(VFrame *incoming, VFrame *outgoing) case BC_YUV888: BANDSLIDE(unsigned char, 3) break; + case BC_RGB_FLOAT: + BANDSLIDE(float, 3); + break; case BC_RGBA8888: case BC_YUVA8888: BANDSLIDE(unsigned char, 4) break; + case BC_RGBA_FLOAT: + BANDSLIDE(float, 4); + break; case BC_RGB161616: case BC_YUV161616: BANDSLIDE(uint16_t, 3) diff --git a/hvirtual/plugins/bandwipe/bandwipe.C b/hvirtual/plugins/bandwipe/bandwipe.C index ea63f0f5..45eaf553 100644 --- a/hvirtual/plugins/bandwipe/bandwipe.C +++ b/hvirtual/plugins/bandwipe/bandwipe.C @@ -3,6 +3,7 @@ #include "defaults.h" #include "edl.inc" #include "filexml.h" +#include "language.h" #include "overlayframe.h" #include "picon_png.h" #include "vframe.h" @@ -11,11 +12,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -348,10 +344,16 @@ int BandWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing) case BC_YUV888: BANDWIPE(unsigned char, 3) break; + case BC_RGB_FLOAT: + BANDWIPE(float, 3); + break; case BC_RGBA8888: case BC_YUVA8888: BANDWIPE(unsigned char, 4) break; + case BC_RGBA_FLOAT: + BANDWIPE(float, 4); + break; case BC_RGB161616: case BC_YUV161616: BANDWIPE(uint16_t, 3) diff --git a/hvirtual/plugins/blur/blur.C b/hvirtual/plugins/blur/blur.C index 35154946..70413d42 100644 --- a/hvirtual/plugins/blur/blur.C +++ b/hvirtual/plugins/blur/blur.C @@ -3,16 +3,13 @@ #include "blurwindow.h" #include "defaults.h" #include "keyframe.h" +#include "language.h" #include "picon_png.h" #include "vframe.h" #include #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -481,10 +478,16 @@ void BlurEngine::run() case BC_YUV888: BLUR(unsigned char, 0xff, 3); break; + case BC_RGB_FLOAT: + BLUR(float, 1.0, 3); + break; case BC_RGBA8888: case BC_YUVA8888: BLUR(unsigned char, 0xff, 4); break; + case BC_RGBA_FLOAT: + BLUR(float, 1.0, 4); + break; case BC_RGB161616: case BC_YUV161616: BLUR(uint16_t, 0xffff, 3); diff --git a/hvirtual/plugins/blur/blur.h b/hvirtual/plugins/blur/blur.h index dd8a334a..8fa78c99 100644 --- a/hvirtual/plugins/blur/blur.h +++ b/hvirtual/plugins/blur/blur.h @@ -87,7 +87,7 @@ public: int blur_strip4(int &size); int color_model; - int vmax; + float vmax; pixel_f *val_p, *val_m, *vp, *vm; pixel_f *sp_p, *sp_m; float n_p[5], n_m[5]; diff --git a/hvirtual/plugins/brightness/brightness.C b/hvirtual/plugins/brightness/brightness.C index acf9426f..28a87ec0 100644 --- a/hvirtual/plugins/brightness/brightness.C +++ b/hvirtual/plugins/brightness/brightness.C @@ -2,17 +2,13 @@ #include "filexml.h" #include "brightness.h" #include "defaults.h" +#include "language.h" #include "picon_png.h" #include #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #define SQR(a) ((a) * (a)) REGISTER_PLUGIN(BrightnessMain) @@ -411,12 +407,126 @@ void BrightnessUnit::process_package(LoadPackage *package) } + +#define DO_BRIGHTNESS_F(components) \ +{ \ + float **input_rows = (float**)input->get_rows(); \ + float **output_rows = (float**)output->get_rows(); \ + int row1 = pkg->row1; \ + int row2 = pkg->row2; \ + int width = output->get_w(); \ + float r, g, b; \ + \ + if(!EQUIV(plugin->config.brightness, 0)) \ + { \ + float offset = plugin->config.brightness / 100; \ + \ + for(int i = row1; i < row2; i++) \ + { \ + float *input_row = input_rows[i]; \ + float *output_row = output_rows[i]; \ + \ + for(int j = 0; j < width; j++) \ + { \ + r = input_row[j * components] + offset; \ + g = input_row[j * components + 1] + offset; \ + b = input_row[j * components + 2] + offset; \ + \ + output_row[j * components] = r; \ + output_row[j * components + 1] = g; \ + output_row[j * components + 2] = b; \ + if(components == 4) \ + output_row[j * components + 3] = input_row[j * components + 3]; \ + } \ + } \ + \ +/* Data to be processed is now in the output buffer */ \ + input_rows = output_rows; \ + } \ + \ + if(!EQUIV(plugin->config.contrast, 0)) \ + { \ + float contrast = (plugin->config.contrast < 0) ? \ + (plugin->config.contrast + 100) / 100 : \ + (plugin->config.contrast + 25) / 25; \ + \ +/* Shift black level down so shadows get darker instead of lighter */ \ + float offset = 0.5 - contrast / 2; \ + float y, u, v; \ + \ + for(int i = row1; i < row2; i++) \ + { \ + float *input_row = input_rows[i]; \ + float *output_row = output_rows[i]; \ + \ + if(plugin->config.luma) \ + { \ + for(int j = 0; j < width; j++) \ + { \ + r = input_row[j * components]; \ + g = input_row[j * components + 1]; \ + b = input_row[j * components + 2]; \ + YUV::rgb_to_yuv_f( \ + r, \ + g, \ + b, \ + y, \ + u, \ + v); \ + \ + y = y * contrast + offset; \ + \ + \ + YUV::yuv_to_rgb_f( \ + r, \ + g, \ + b, \ + y, \ + u, \ + v); \ + input_row[j * components] = r; \ + input_row[j * components + 1] = g; \ + input_row[j * components + 2] = b; \ + \ + if(components == 4) \ + output_row[j * components + 3] = input_row[j * components + 3]; \ + } \ + } \ + else \ + { \ + for(int j = 0; j < width; j++) \ + { \ + r = input_row[j * components]; \ + g = input_row[j * components + 1]; \ + b = input_row[j * components + 2]; \ + \ + r = r * contrast + offset; \ + g = g * contrast + offset; \ + b = b * contrast + offset; \ + \ + output_row[j * components] = r; \ + output_row[j * components + 1] = g; \ + output_row[j * components + 2] = b; \ + \ + if(components == 4) \ + output_row[j * components + 3] = input_row[j * components + 3]; \ + } \ + } \ + } \ + } \ +} + + switch(input->get_color_model()) { case BC_RGB888: DO_BRIGHTNESS(0xff, unsigned char, 3, 0) break; + case BC_RGB_FLOAT: + DO_BRIGHTNESS_F(3) + break; + case BC_YUV888: DO_BRIGHTNESS(0xff, unsigned char, 3, 1) break; @@ -425,6 +535,10 @@ void BrightnessUnit::process_package(LoadPackage *package) DO_BRIGHTNESS(0xff, unsigned char, 4, 0) break; + case BC_RGBA_FLOAT: + DO_BRIGHTNESS_F(4) + break; + case BC_YUVA8888: DO_BRIGHTNESS(0xff, unsigned char, 4, 1) break; diff --git a/hvirtual/plugins/burn/burn.C b/hvirtual/plugins/burn/burn.C index 945969fe..62a6bcf4 100644 --- a/hvirtual/plugins/burn/burn.C +++ b/hvirtual/plugins/burn/burn.C @@ -2,7 +2,9 @@ #include "colormodels.h" #include "effecttv.h" #include "filexml.h" +#include "language.h" #include "picon_png.h" +#include "plugincolors.h" #include "burn.h" #include "burnwindow.h" @@ -10,15 +12,9 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) -PluginClient* new_plugin(PluginServer *server) -{ - return new BurnMain(server); -} + +REGISTER_PLUGIN(BurnMain) @@ -46,6 +42,7 @@ BurnMain::BurnMain(PluginServer *server) burn_server = 0; buffer = 0; effecttv = 0; + yuv = new YUV; PLUGIN_CONSTRUCTOR_MACRO } @@ -56,6 +53,7 @@ BurnMain::~BurnMain() if(buffer) delete [] buffer; if(burn_server) delete burn_server; if(effecttv) delete effecttv; + if(yuv) delete yuv; } char* BurnMain::plugin_title() { return N_("BurningTV"); } @@ -95,12 +93,13 @@ void BurnMain::read_data(KeyFrame *keyframe) #define MAXCOLOR 120 -static void HSItoRGB(double H, +void BurnMain::HSItoRGB(double H, double S, double I, int *r, int *g, - int *b) + int *b, + int color_model) { double T, Rv, Gv, Bv; @@ -116,7 +115,7 @@ static void HSItoRGB(double H, } -void BurnMain::make_palette() +void BurnMain::make_palette(int color_model) { int i, r, g, b; @@ -127,11 +126,12 @@ void BurnMain::make_palette() (double)i / MAXCOLOR, &r, &g, - &b); + &b, + color_model); palette[0][i] = r; palette[1][i] = g; palette[2][i] = b; -//printf("BurnMain::make_palette %d\n", palette[0][i]); +//printf("BurnMain::make_palette %d %d %d %d\n", i, palette[0][i], palette[1][i], palette[2][i]); } @@ -147,6 +147,7 @@ void BurnMain::make_palette() palette[0][i] = r; palette[1][i] = g; palette[2][i] = b; +//printf("BurnMain::make_palette %d %d %d %d\n", i, palette[0][i], palette[1][i], palette[2][i]); } } @@ -164,7 +165,7 @@ int BurnMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) { effecttv = new EffectTV(input_ptr->get_w(), input_ptr->get_h()); buffer = (unsigned char *)new unsigned char[input_ptr->get_w() * input_ptr->get_h()]; - make_palette(); + make_palette(input_ptr->get_color_model()); effecttv->image_set_threshold_y(config.threshold); total = 0; @@ -241,34 +242,93 @@ BurnClient::BurnClient(BurnServer *server) -#define BURN(type, components) \ +#define BURN(type, components, is_yuv) \ { \ i = 1; \ + type **rows = (type**)input_rows; \ for(y = 0; y < height; y++) \ { \ for(x = 1; x < width - 1; x++) \ { \ - for(c = 0; c < components; c++) \ + if(sizeof(type) == 4) \ + { \ + a1 = (int)(rows[0][i * components] * 0xff); \ + a2 = (int)(rows[0][i * components + 1] * 0xff); \ + a3 = (int)(rows[0][i * components + 2] * 0xff); \ + CLAMP(a1, 0, 0xff); \ + CLAMP(a2, 0, 0xff); \ + CLAMP(a3, 0, 0xff); \ + b1 = plugin->palette[0][plugin->buffer[i]]; \ + b2 = plugin->palette[1][plugin->buffer[i]]; \ + b3 = plugin->palette[2][plugin->buffer[i]]; \ + a1 += b1; \ + a2 += b2; \ + a3 += b3; \ + b1 = a1 & 0x100; \ + b2 = a2 & 0x100; \ + b3 = a3 & 0x100; \ + rows[0][i * components] = (type)(a1 | (b1 - (b1 >> 8))) / 0xff; \ + rows[0][i * components + 1] = (type)(a2 | (b2 - (b2 >> 8))) / 0xff; \ + rows[0][i * components + 2] = (type)(a3 | (b3 - (b3 >> 8))) / 0xff; \ + } \ + else \ + if(sizeof(type) == 2) \ { \ - if(c == 3) \ - output_rows[0][i * components + c] = input_rows[0][i * components + c]; \ - else \ - if(sizeof(type) == 2) \ + a1 = ((int)rows[0][i * components + 0]) >> 8; \ + a2 = ((int)rows[0][i * components + 1]) >> 8; \ + a3 = ((int)rows[0][i * components + 2]) >> 8; \ + b1 = plugin->palette[0][plugin->buffer[i]]; \ + b2 = plugin->palette[1][plugin->buffer[i]]; \ + b3 = plugin->palette[2][plugin->buffer[i]]; \ + if(is_yuv) plugin->yuv->yuv_to_rgb_8(a1, a2, a3); \ + a1 += b1; \ + a2 += b2; \ + a3 += b3; \ + b1 = a1 & 0x100; \ + b2 = a2 & 0x100; \ + b3 = a3 & 0x100; \ + a1 = (a1 | (b1 - (b1 >> 8))); \ + a2 = (a2 | (b2 - (b2 >> 8))); \ + a3 = (a3 | (b3 - (b3 >> 8))); \ + if(is_yuv) \ { \ - a = (input_rows[0][i * components + c] & 0xffff) >> 8; \ - b = plugin->palette[c][plugin->buffer[i]] & 0xff; \ - a += b; \ - b = a & 0x10000; \ - output_rows[0][i * components + c] = a | (b - (b >> 16)); \ + CLAMP(a1, 0, 0xff); \ + CLAMP(a2, 0, 0xff); \ + CLAMP(a3, 0, 0xff); \ + plugin->yuv->rgb_to_yuv_8(a1, a2, a3); \ } \ - else \ + rows[0][i * components + 0] = a1 | (a1 << 8); \ + rows[0][i * components + 1] = a2 | (a2 << 8); \ + rows[0][i * components + 2] = a3 | (a3 << 8); \ + } \ + else \ + { \ + a1 = (int)rows[0][i * components + 0]; \ + a2 = (int)rows[0][i * components + 1]; \ + a3 = (int)rows[0][i * components + 2]; \ + b1 = plugin->palette[0][plugin->buffer[i]]; \ + b2 = plugin->palette[1][plugin->buffer[i]]; \ + b3 = plugin->palette[2][plugin->buffer[i]]; \ + if(is_yuv) plugin->yuv->yuv_to_rgb_8(a1, a2, a3); \ + a1 += b1; \ + a2 += b2; \ + a3 += b3; \ + b1 = a1 & 0x100; \ + b2 = a2 & 0x100; \ + b3 = a3 & 0x100; \ + a1 = (a1 | (b1 - (b1 >> 8))); \ + a2 = (a2 | (b2 - (b2 >> 8))); \ + a3 = (a3 | (b3 - (b3 >> 8))); \ + if(is_yuv) \ { \ - a = input_rows[0][i * components + c] & 0xff; \ - b = plugin->palette[c][plugin->buffer[i]] & 0xff; \ - a += b; \ - b = a & 0x100; \ - output_rows[0][i * components + c] = a | (b - (b >> 8)); \ + CLAMP(a1, 0, 0xff); \ + CLAMP(a2, 0, 0xff); \ + CLAMP(a3, 0, 0xff); \ + plugin->yuv->rgb_to_yuv_8(a1, a2, a3); \ } \ + rows[0][i * components + 0] = a1; \ + rows[0][i * components + 1] = a2; \ + rows[0][i * components + 2] = a3; \ } \ i++; \ } \ @@ -290,7 +350,9 @@ void BurnClient::process_package(LoadPackage *package) int pitch = width * plugin->input_ptr->get_bytes_per_pixel(); int i, x, y; unsigned int v, w; - int a, b, c; + int a1, b1, c1; + int a2, b2, c2; + int a3, b3, c3; diff = plugin->effecttv->image_bgsubtract_y(input_rows, @@ -331,23 +393,39 @@ void BurnClient::process_package(LoadPackage *package) switch(plugin->input_ptr->get_color_model()) { case BC_RGB888: + BURN(uint8_t, 3, 0); + break; case BC_YUV888: - BURN(uint8_t, 3); + BURN(uint8_t, 3, 1); + break; + + case BC_RGB_FLOAT: + BURN(float, 3, 0); + break; + + case BC_RGBA_FLOAT: + BURN(float, 4, 0); break; case BC_RGBA8888: + BURN(uint8_t, 4, 0); + break; case BC_YUVA8888: - BURN(uint8_t, 4); + BURN(uint8_t, 4, 1); break; case BC_RGB161616: + BURN(uint16_t, 3, 0); + break; case BC_YUV161616: - BURN(uint16_t, 3); + BURN(uint16_t, 3, 1); break; case BC_RGBA16161616: + BURN(uint16_t, 4, 0); + break; case BC_YUVA16161616: - BURN(uint16_t, 4); + BURN(uint16_t, 4, 1); break; } diff --git a/hvirtual/plugins/burn/burn.h b/hvirtual/plugins/burn/burn.h new file mode 100644 index 00000000..92615510 --- /dev/null +++ b/hvirtual/plugins/burn/burn.h @@ -0,0 +1,112 @@ +#ifndef BURN_H +#define BURN_H + +class BurnMain; + +#include "defaults.h" +#include "effecttv.inc" +#include "loadbalance.h" +#include "mutex.h" +#include "plugincolors.inc" +#include "pluginvclient.h" +#include "burnwindow.h" +#include + +class BurnConfig +{ +public: + BurnConfig(); + int threshold; + int decay; + double recycle; // Seconds to a recycle +}; + +class BurnPackage : public LoadPackage +{ +public: + BurnPackage(); + + int row1, row2; +}; + +class BurnServer : public LoadServer +{ +public: + BurnServer(BurnMain *plugin, int total_clients, int total_packages); + + LoadClient* new_client(); + LoadPackage* new_package(); + void init_packages(); + BurnMain *plugin; +}; + +class BurnClient : public LoadClient +{ +public: + BurnClient(BurnServer *server); + + void process_package(LoadPackage *package); + + BurnMain *plugin; +}; + + +class BurnMain : public PluginVClient +{ +public: + BurnMain(PluginServer *server); + ~BurnMain(); + +// required for all realtime plugins + int process_realtime(VFrame *input_ptr, VFrame *output_ptr); + int is_realtime(); + char* plugin_title(); + int show_gui(); + void raise_window(); + int set_string(); + void load_configuration(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + + int load_defaults(); + int save_defaults(); + VFrame* new_picon(); + + + + + void BurnMain::HSItoRGB(double H, + double S, + double I, + int *r, + int *g, + int *b, + int color_model); + void make_palette(int color_model); + +// a thread for the GUI + BurnThread *thread; + BurnServer *burn_server; + BurnConfig config; + + int palette[3][256]; + unsigned char *buffer; + + int total; + + EffectTV *effecttv; + Defaults *defaults; + VFrame *input_ptr, *output_ptr; + YUV *yuv; +}; + + + + + + + + + + +#endif diff --git a/hvirtual/plugins/burn/burnwindow.C b/hvirtual/plugins/burn/burnwindow.C index f8473d69..3d1d0475 100644 --- a/hvirtual/plugins/burn/burnwindow.C +++ b/hvirtual/plugins/burn/burnwindow.C @@ -44,11 +44,6 @@ int BurnWindow::create_objects() return 0; } -int BurnWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(BurnWindow) diff --git a/hvirtual/plugins/cdripper/cdripper.C b/hvirtual/plugins/cdripper/cdripper.C index d924f859..c4fbb055 100644 --- a/hvirtual/plugins/cdripper/cdripper.C +++ b/hvirtual/plugins/cdripper/cdripper.C @@ -194,8 +194,14 @@ int CDRipMain::get_toc() window.run_window(); result = 1; } + +// Clamp to highest track + if(track2 > tracks) + { + track2 = tracks; + } - if(track2 < track1 || track2 <= 0 || track2 > tracks) + if(track2 < track1 || track2 <= 0) { ioctl(cdrom, CDROMSTOP); close(cdrom); diff --git a/hvirtual/plugins/chromakey/chromakey.C b/hvirtual/plugins/chromakey/chromakey.C index 2d015ce6..78a099e7 100644 --- a/hvirtual/plugins/chromakey/chromakey.C +++ b/hvirtual/plugins/chromakey/chromakey.C @@ -5,6 +5,7 @@ #include "filexml.h" #include "guicast.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "plugincolors.h" @@ -14,10 +15,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -298,7 +295,6 @@ void ChromaKeyUnit::process_package(LoadPackage *package) float max_h = plugin->config.hue + plugin->config.threshold * 3.60 / 2; float min_v = (plugin->config.value - plugin->config.threshold / 2) / 100; float max_v = (plugin->config.value + plugin->config.threshold / 2) / 100; - int a; float run; if(plugin->config.use_value) @@ -309,9 +305,11 @@ void ChromaKeyUnit::process_package(LoadPackage *package) // printf("ChromaKeyUnit::process_package %f %f %f %f\n", // min_h, max_h, min_v, max_v); -#define CHROMAKEY(type, max, components, use_yuv) \ +#define CHROMAKEY(type, temp, max, components, use_yuv) \ { \ - int chroma_offset; \ + temp chroma_offset; \ + temp a; \ + \ if(use_yuv) \ chroma_offset = max / 2 + 1; \ else \ @@ -348,14 +346,14 @@ void ChromaKeyUnit::process_package(LoadPackage *package) if(va - min_v < max_v - va) \ { \ if(va - min_v < run) \ - a = (int)(max - (va - min_v) / run * max); \ + a = (temp)(max - (va - min_v) / run * max); \ else \ a = 0; \ } \ else \ { \ if(max_v - va < run) \ - a = (int)(max - (max_v - va) / run * max); \ + a = (temp)(max - (max_v - va) / run * max); \ else \ a = 0; \ } \ @@ -364,9 +362,9 @@ void ChromaKeyUnit::process_package(LoadPackage *package) row[3] = MIN(a, row[3]); \ else \ { \ - row[0] = (a * row[0]) / max; \ - row[1] = (a * row[1] + (max - a) * chroma_offset) / max; \ - row[2] = (a * row[2] + (max - a) * chroma_offset) / max; \ + row[0] = (type)((a * row[0]) / max); \ + row[1] = (type)((a * row[1] + (max - a) * chroma_offset) / max); \ + row[2] = (type)((a * row[2] + (max - a) * chroma_offset) / max); \ } \ } \ } \ @@ -377,14 +375,14 @@ void ChromaKeyUnit::process_package(LoadPackage *package) if(h - min_h < max_h - h) \ { \ if(h - min_h < run) \ - a = (int)(max - (h - min_h) / run * max); \ + a = (temp)(max - (h - min_h) / run * max); \ else \ a = 0; \ } \ else \ { \ if(max_h - h < run) \ - a = (int)(max - (max_h - h) / run * max); \ + a = (temp)(max - (max_h - h) / run * max); \ else \ a = 0; \ } \ @@ -393,9 +391,9 @@ void ChromaKeyUnit::process_package(LoadPackage *package) row[3] = MIN(a, row[3]); \ else \ { \ - row[0] = a * row[0] / max; \ - row[1] = (a * row[1] + (max - a) * chroma_offset) / max; \ - row[2] = (a * row[2] + (max - a) * chroma_offset) / max; \ + row[0] = (type)(a * row[0] / max); \ + row[1] = (type)((a * row[1] + (max - a) * chroma_offset) / max); \ + row[2] = (type)((a * row[2] + (max - a) * chroma_offset) / max); \ } \ } \ } \ @@ -411,28 +409,34 @@ void ChromaKeyUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { case BC_RGB888: - CHROMAKEY(unsigned char, 0xff, 3, 0); + CHROMAKEY(unsigned char, int, 0xff, 3, 0); + break; + case BC_RGB_FLOAT: + CHROMAKEY(float, float, 1.0, 3, 0); break; case BC_YUV888: - CHROMAKEY(unsigned char, 0xff, 3, 1); + CHROMAKEY(unsigned char, int, 0xff, 3, 1); break; case BC_RGBA8888: - CHROMAKEY(unsigned char, 0xff, 4, 0); + CHROMAKEY(unsigned char, int, 0xff, 4, 0); + break; + case BC_RGBA_FLOAT: + CHROMAKEY(float, float, 1.0, 4, 0); break; case BC_YUVA8888: - CHROMAKEY(unsigned char, 0xff, 4, 1); + CHROMAKEY(unsigned char, int, 0xff, 4, 1); break; case BC_RGB161616: - CHROMAKEY(uint16_t, 0xffff, 3, 0); + CHROMAKEY(uint16_t, int, 0xffff, 3, 0); break; case BC_YUV161616: - CHROMAKEY(uint16_t, 0xffff, 3, 1); + CHROMAKEY(uint16_t, int, 0xffff, 3, 1); break; case BC_RGBA16161616: - CHROMAKEY(uint16_t, 0xffff, 4, 0); + CHROMAKEY(uint16_t, int, 0xffff, 4, 0); break; case BC_YUVA16161616: - CHROMAKEY(uint16_t, 0xffff, 4, 1); + CHROMAKEY(uint16_t, int, 0xffff, 4, 1); break; } diff --git a/hvirtual/plugins/colorbalance/colorbalance.C b/hvirtual/plugins/colorbalance/colorbalance.C index c0c3beb3..f7da2d92 100644 --- a/hvirtual/plugins/colorbalance/colorbalance.C +++ b/hvirtual/plugins/colorbalance/colorbalance.C @@ -1,16 +1,12 @@ #include "filexml.h" #include "colorbalance.h" #include "defaults.h" +#include "language.h" #include "picon_png.h" #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #define SQR(a) ((a) * (a)) REGISTER_PLUGIN(ColorBalanceMain) @@ -102,6 +98,25 @@ int ColorBalanceEngine::wait_process_frame() return 0; } +float ColorBalanceEngine::calculate_highlight(float in) +{ + return 0.667 * (1.0 - SQR((in - 0.5) / 0.5)); +} + +float ColorBalanceEngine::calculate_r(float r) +{ + return r + cyan_f * calculate_highlight(r); +} + +float ColorBalanceEngine::calculate_g(float g) +{ + return g + magenta_f * calculate_highlight(g); +} + +float ColorBalanceEngine::calculate_b(float b) +{ + return b + yellow_f * calculate_highlight(b); +} void ColorBalanceEngine::run() { @@ -186,6 +201,53 @@ void ColorBalanceEngine::run() } \ } +#define PROCESS_F(components) \ +{ \ + int i, j, k; \ + float y, cb, cr, r, g, b, r_n, g_n, b_n; \ + float h, s, v, h_old, s_old, r_f, g_f, b_f; \ + float **input_rows, **output_rows; \ + input_rows = (float**)input->get_rows(); \ + output_rows = (float**)output->get_rows(); \ + cyan_f = (float)plugin->config.cyan / 100; \ + magenta_f = (float)plugin->config.magenta / 100; \ + yellow_f = (float)plugin->config.yellow / 100; \ + \ + for(j = row_start; j < row_end; j++) \ + { \ + for(k = 0; k < input->get_w() * components; k += components) \ + { \ + r = input_rows[j][k]; \ + g = input_rows[j][k + 1]; \ + b = input_rows[j][k + 2]; \ + \ + r_n = calculate_r(r); \ + g_n = calculate_g(g); \ + b_n = calculate_b(b); \ + \ + if(plugin->config.preserve) \ + { \ + HSV::rgb_to_hsv(r_n, g_n, b_n, h, s, v); \ + HSV::rgb_to_hsv(r, g, b, h_old, s_old, v); \ + HSV::hsv_to_rgb(r_f, g_f, b_f, h, s, v); \ + r = (float)r_f; \ + g = (float)g_f; \ + b = (float)b_f; \ + } \ + else \ + { \ + r = r_n; \ + g = g_n; \ + b = b_n; \ + } \ + \ + output_rows[j][k] = r; \ + output_rows[j][k + 1] = g; \ + output_rows[j][k + 2] = b; \ + } \ + } \ +} + switch(input->get_color_model()) { case BC_RGB888: @@ -200,6 +262,10 @@ void ColorBalanceEngine::run() 0); break; + case BC_RGB_FLOAT: + PROCESS_F(3); + break; + case BC_YUV888: PROCESS(yuv.yuv_to_rgb_8, yuv.rgb_to_yuv_8, @@ -212,6 +278,10 @@ void ColorBalanceEngine::run() 1); break; + case BC_RGBA_FLOAT: + PROCESS_F(4); + break; + case BC_RGBA8888: PROCESS(yuv.yuv_to_rgb_8, yuv.rgb_to_yuv_8, diff --git a/hvirtual/plugins/colorbalance/colorbalance.h b/hvirtual/plugins/colorbalance/colorbalance.h index 18beb4ea..1a702429 100644 --- a/hvirtual/plugins/colorbalance/colorbalance.h +++ b/hvirtual/plugins/colorbalance/colorbalance.h @@ -40,6 +40,10 @@ public: ColorBalanceEngine(ColorBalanceMain *plugin); ~ColorBalanceEngine(); + float calculate_highlight(float in); + float calculate_r(float r); + float calculate_g(float g); + float calculate_b(float b); int start_process_frame(VFrame *output, VFrame *input, int row_start, int row_end); int wait_process_frame(); void run(); @@ -50,6 +54,7 @@ public: Mutex input_lock, output_lock; VFrame *input, *output; YUV yuv; + float cyan_f, magenta_f, yellow_f; }; class ColorBalanceMain : public PluginVClient diff --git a/hvirtual/plugins/compressor/compressor.C b/hvirtual/plugins/compressor/compressor.C index 154ba4e5..cddad8f2 100644 --- a/hvirtual/plugins/compressor/compressor.C +++ b/hvirtual/plugins/compressor/compressor.C @@ -1,9 +1,11 @@ #include "bcdisplayinfo.h" +#include "bcsignals.h" #include "clip.h" #include "compressor.h" #include "cursors.h" #include "defaults.h" #include "filexml.h" +#include "language.h" #include "picon_png.h" #include "units.h" #include "vframe.h" @@ -11,11 +13,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -27,6 +24,28 @@ REGISTER_PLUGIN(CompressorEffect) +// More potential compressor algorithms: +// Use single reaction time parameter. Negative reaction time uses +// readahead. Positive reaction time uses slope. + +// Smooth input stage if readahead. +// Determine slope from current smoothed sample to every sample in readahead area. +// Once highest slope is found, count of number of samples remaining until it is +// reached. Only search after this count for the next highest slope. +// Use highest slope to determine smoothed value. + +// Smooth input stage if not readahead. +// For every sample, calculate slope needed to reach current sample from +// current smoothed value in the reaction time. If higher than current slope, +// make it the current slope and count number of samples remaining until it is +// reached. If this count is met and no higher slopes are found, base slope +// on current sample when count is met. + +// Gain stage. +// For every sample, calculate gain from smoothed input value. + + + CompressorEffect::CompressorEffect(PluginServer *server) @@ -50,37 +69,26 @@ void CompressorEffect::delete_dsp() delete [] input_buffer[i]; delete [] input_buffer; } - if(coefs) delete [] coefs; - if(reaction_buffer) delete [] reaction_buffer; input_buffer = 0; - coefs = 0; input_size = 0; input_allocated = 0; - reaction_buffer = 0; - reaction_allocated = 0; - reaction_position = 0; } void CompressorEffect::reset() { input_buffer = 0; - coefs = 0; input_size = 0; input_allocated = 0; - coefs_allocated = 0; - reaction_buffer = 0; - reaction_allocated = 0; - reaction_position = 0; - current_coef = 1.0; - last_peak_age = 0; - last_peak = 0.0; - previous_intercept = 1.0; - previous_slope = 0.0; - previous_max = 0.0; - max_counter = 0; + input_start = 0; + + next_target = 1.0; + previous_target = 1.0; + target_samples = 1; + target_current_sample = -1; + current_value = 1.0; } char* CompressorEffect::plugin_title() { return N_("Compressor"); } @@ -104,9 +112,11 @@ void CompressorEffect::read_data(KeyFrame *keyframe) { if(input.tag.title_is("COMPRESSOR")) { - config.preview_len = input.tag.get_property("PREVIEW_LEN", config.preview_len); config.reaction_len = input.tag.get_property("REACTION_LEN", config.reaction_len); + config.decay_len = input.tag.get_property("DECAY_LEN", config.decay_len); config.trigger = input.tag.get_property("TRIGGER", config.trigger); + config.smoothing_only = input.tag.get_property("SMOOTHING_ONLY", config.smoothing_only); + config.no_trigger = input.tag.get_property("NO_TRIGGER", config.no_trigger); } else if(input.tag.title_is("LEVEL")) @@ -127,9 +137,11 @@ void CompressorEffect::save_data(KeyFrame *keyframe) output.set_shared_string(keyframe->data, MESSAGESIZE); output.tag.set_title("COMPRESSOR"); - output.tag.set_property("PREVIEW_LEN", config.preview_len); output.tag.set_property("TRIGGER", config.trigger); output.tag.set_property("REACTION_LEN", config.reaction_len); + output.tag.set_property("DECAY_LEN", config.decay_len); + output.tag.set_property("SMOOTHING_ONLY", config.smoothing_only); + output.tag.set_property("NO_TRIGGER", config.no_trigger); output.append_tag(); output.append_newline(); @@ -154,9 +166,11 @@ int CompressorEffect::load_defaults() defaults = new Defaults(directory); defaults->load(); - config.preview_len = defaults->get("PREVIEW_LEN", config.preview_len); config.trigger = defaults->get("TRIGGER", config.trigger); config.reaction_len = defaults->get("REACTION_LEN", config.reaction_len); + config.decay_len = defaults->get("DECAY_LEN", config.decay_len); + config.smoothing_only = defaults->get("SMOOTHING_ONLY", config.smoothing_only); + config.no_trigger = defaults->get("NO_TRIGGER", config.no_trigger); config.levels.remove_all(); int total_levels = defaults->get("TOTAL_LEVELS", 0); @@ -176,10 +190,12 @@ int CompressorEffect::save_defaults() { char string[BCTEXTLEN]; - defaults->update("PREVIEW_LEN", config.preview_len); defaults->update("TRIGGER", config.trigger); defaults->update("REACTION_LEN", config.reaction_len); + defaults->update("DECAY_LEN", config.decay_len); + defaults->update("SMOOTHING_ONLY", config.smoothing_only); defaults->update("TOTAL_LEVELS", config.levels.total); + defaults->update("NO_TRIGGER", config.no_trigger); defaults->update("TOTAL_LEVELS", config.levels.total); for(int i = 0; i < config.levels.total; i++) @@ -200,10 +216,12 @@ void CompressorEffect::update_gui() { if(thread) { - load_configuration(); - thread->window->lock_window(); - thread->window->update(); - thread->window->unlock_window(); + if(load_configuration()) + { + thread->window->lock_window("CompressorEffect::update_gui"); + thread->window->update(); + thread->window->unlock_window(); + } } } @@ -216,237 +234,308 @@ LOAD_CONFIGURATION_MACRO(CompressorEffect, CompressorConfig) -int CompressorEffect::process_realtime(int64_t size, double **input_ptr, double **output_ptr) + + +int CompressorEffect::process_buffer(int64_t size, + double **buffer, + int64_t start_position, + int sample_rate) { -//printf("CompressorEffect::process_realtime 1 %f\n", DB::fromdb(-100)); - load_configuration(); - if(coefs_allocated < size) - { - if(coefs) delete [] coefs; - coefs = new double[size]; - coefs_allocated = size; - } + load_configuration(); -//printf("CompressorEffect::process_realtime 2\n"); - int preview_samples = (int)(config.preview_len * PluginAClient::project_sample_rate + 0.5); - int reaction_samples = (int)(config.reaction_len * PluginAClient::project_sample_rate + 0.5); + int reaction_samples = (int)(config.reaction_len * sample_rate + 0.5); + int decay_samples = (int)(config.decay_len * sample_rate + 0.5); int trigger = CLIP(config.trigger, 0, PluginAClient::total_in_buffers - 1); -// trigger = PluginAClient::total_in_buffers - trigger - 1; - CLAMP(reaction_samples, 1, 128000000); - CLAMP(preview_samples, 1, 128000000); - -//printf("CompressorEffect::process_realtime 3\n"); + CLAMP(reaction_samples, -1000000, 1000000); + CLAMP(decay_samples, reaction_samples, 1000000); + CLAMP(decay_samples, 1, 1000000); + if(labs(reaction_samples) < 1) reaction_samples = 1; + if(labs(decay_samples) < 1) decay_samples = 1; -// Append input buffers - if(input_size + size > input_allocated) + int total_buffers = get_total_buffers(); + if(reaction_samples > 0) { - double **new_input = new double*[PluginClient::total_in_buffers]; - for(int i = 0; i < PluginClient::total_in_buffers; i++) - new_input[i] = new double[input_size + size]; + if(target_current_sample < 0) target_current_sample = reaction_samples; + for(int i = 0; i < total_buffers; i++) + { + read_samples(buffer[i], + i, + sample_rate, + start_position, + size); + } - if(input_buffer) + double current_slope = (next_target - previous_target) / + reaction_samples; + double *trigger_buffer = buffer[trigger]; + for(int i = 0; i < size; i++) { - for(int i = 0; i < PluginClient::total_in_buffers; i++) +// Get slope required to reach current sample from smoothed sample over reaction +// length. + double sample; + if(config.no_trigger) { - memcpy(new_input[i], input_buffer[i], sizeof(double) * input_size); - delete [] input_buffer[i]; + double max = 0; + for(int j = 0; j < total_buffers; j++) + { + sample = fabs(buffer[j][i]); + if(sample > max) max = sample; + } + sample = max; + } + else + { + sample = fabs(trigger_buffer[i]); } - delete [] input_buffer; - } - - input_buffer = new_input; - input_allocated = input_size + size; - } - -//printf("CompressorEffect::process_realtime 4\n"); - for(int i = 0; i < PluginClient::total_in_buffers; i++) - memcpy(input_buffer[i] + input_size, - input_ptr[i], - size * sizeof(double)); - input_size += size; - + double new_slope = (sample - current_value) / + reaction_samples; +// Slope greater than current slope + if(new_slope >= current_slope && + (current_slope >= 0 || + new_slope >= 0)) + { + next_target = sample; + previous_target = current_value; + target_current_sample = 0; + target_samples = reaction_samples; + current_slope = new_slope; + } + else + if(sample > next_target && current_slope < 0) + { + next_target = sample; + previous_target = current_value; + target_current_sample = 0; + target_samples = decay_samples; + current_slope = (sample - current_value) / decay_samples; + } +// Current smoothed sample came up without finding higher slope + if(target_current_sample >= target_samples) + { + next_target = sample; + previous_target = current_value; + target_current_sample = 0; + target_samples = decay_samples; + current_slope = (sample - current_value) / decay_samples; + } -//printf("CompressorEffect::process_realtime 5 %d\n", size); +// Update current value and store gain + current_value = (next_target * target_current_sample + + previous_target * (target_samples - target_current_sample)) / + target_samples; + target_current_sample++; + if(config.smoothing_only) + { + for(int j = 0; j < total_buffers; j++) + buffer[j][i] = current_value; + } + else + { + double gain = calculate_gain(current_value); + for(int j = 0; j < total_buffers; j++) + { + buffer[j][i] *= gain; + } + } + } + } + else + { + if(target_current_sample < 0) target_current_sample = target_samples; + int64_t preview_samples = -reaction_samples; +// Start of new buffer is outside the current buffer. Start buffer over. + if(start_position < input_start || + start_position >= input_start + input_size) + { + input_size = 0; + input_start = start_position; + } + else +// Shift current buffer so the buffer starts on start_position + if(start_position > input_start && + start_position < input_start + input_size) + { + if(input_buffer) + { + int len = input_start + input_size - start_position; + for(int i = 0; i < total_buffers; i++) + { + memcpy(input_buffer[i], + input_buffer[i] + (start_position - input_start), + len * sizeof(double)); + } + input_size = len; + input_start = start_position; + } + } -// Have enough to send to output - if(input_size >= preview_samples) - { - int output_offset = 0; - if(input_size - preview_samples < size) +// Expand buffer to handle preview size + if(size + preview_samples > input_allocated) { - output_offset = size - (input_size - preview_samples); - size = input_size - preview_samples; - for(int i = 0; i < PluginAClient::total_in_buffers; i++) - bzero(output_ptr[i], output_offset * sizeof(double)); + double **new_input_buffer = new double*[total_buffers]; + for(int i = 0; i < total_buffers; i++) + { + new_input_buffer[i] = new double[size + preview_samples]; + if(input_buffer) + { + memcpy(new_input_buffer[i], + input_buffer[i], + input_size * sizeof(double)); + delete [] input_buffer[i]; + } + } + if(input_buffer) delete [] input_buffer; + + input_allocated = size + preview_samples; + input_buffer = new_input_buffer; } - -//printf("CompressorEffect::process_realtime 6 %d\n", reaction_samples); - if(reaction_allocated != reaction_samples) + +// Append data to input buffer to construct readahead area. +#define MAX_FRAGMENT_SIZE 131072 + while(input_size < size + preview_samples) { - double *new_buffer = new double[reaction_samples]; - if(reaction_buffer) + int fragment_size = MAX_FRAGMENT_SIZE; + if(fragment_size + input_size > size + preview_samples) + fragment_size = size + preview_samples - input_size; + for(int i = 0; i < total_buffers; i++) { - memcpy(new_buffer, - reaction_buffer, - sizeof(double) * MIN(reaction_allocated, reaction_samples)); - delete [] reaction_buffer; + read_samples(input_buffer[i] + input_size, + i, + sample_rate, + input_start + input_size, + fragment_size); } - if(reaction_samples - reaction_allocated > 0) - bzero(new_buffer + reaction_allocated, - sizeof(double) * (reaction_samples - reaction_allocated)); - reaction_buffer = new_buffer; - reaction_allocated = reaction_samples; - if(reaction_position >= reaction_allocated) reaction_position = 0; + input_size += fragment_size; } -//printf("CompressorEffect::process_realtime 7\n"); -// Calculate coef buffer for current size - double max = 0, min = 0; - int64_t max_age = 0; - int64_t min_age = 0; + double current_slope = (next_target - previous_target) / + target_samples; + double *trigger_buffer = input_buffer[trigger]; for(int i = 0; i < size; i++) { -// Put new sample in reaction buffer - reaction_buffer[reaction_position] = - input_buffer[trigger][i + preview_samples]; +// Get slope from current sample to every sample in preview_samples. +// Take highest one or first one after target_samples are up. + +// For optimization, calculate the first slope we really need. +// Assume every slope up to the end of preview_samples has been calculated and +// found <= to current slope. + int first_slope = preview_samples - 1; +// Need new slope immediately + if(target_current_sample >= target_samples) + first_slope = 1; + for(int j = first_slope; + j < preview_samples; + j++) + { + double sample; + if(config.no_trigger) + { + double max = 0; + for(int k = 0; k < total_buffers; k++) + { + sample = fabs(input_buffer[k][i + j]); + if(sample > max) max = sample; + } + sample = max; + } + else + { + sample = fabs(trigger_buffer[i + j]); + } -// Get peak in last reaction buffer size of samples - max = 0; - min = 0; -// Try to optimize - if(last_peak_age < reaction_samples) - { - if(fabs(input_buffer[trigger][i + preview_samples]) > last_peak) + + double new_slope = (sample - current_value) / + j; +// Got equal or higher slope + if(new_slope >= current_slope && + (current_slope >= 0 || + new_slope >= 0)) { - last_peak = fabs(input_buffer[trigger][i + preview_samples]); - last_peak_age = 0; + target_current_sample = 0; + target_samples = j; + current_slope = new_slope; + next_target = sample; + previous_target = current_value; } - max = last_peak; - } - else - { -// Rescan history - for(int j = 0; j < reaction_samples; j++) + else + if(sample > next_target && current_slope < 0) { - if(reaction_buffer[j] > max) - { - max = reaction_buffer[j]; - max_age = (j <= reaction_position) ? - (reaction_position - j) : - (reaction_samples - (j - reaction_position)); - } - else - if(reaction_buffer[j] < min) - { - min = reaction_buffer[j]; - min_age = (j <= reaction_position) ? - (reaction_position - j) : - (reaction_samples - (j - reaction_position)); - } + target_current_sample = 0; + target_samples = decay_samples; + current_slope = (sample - current_value) / + decay_samples; + next_target = sample; + previous_target = current_value; } - if(-min > max) +// Hit end of current slope range without finding higher slope + if(target_current_sample >= target_samples) { - max = -min; - max_age = min_age; + target_current_sample = 0; + target_samples = decay_samples; + current_slope = (sample - current_value) / decay_samples; + next_target = sample; + previous_target = current_value; } - - last_peak = max; - last_peak_age = max_age; } -// Here's the brain of the effect. +// Update current value and multiply gain + current_value = (next_target * target_current_sample + + previous_target * (target_samples - target_current_sample)) / + target_samples; +//buffer[0][i] = current_value; + target_current_sample++; -// Test expiration of previous max. If previous max is bigger than -// current max and still valid, it replaces the current max. -// Otherwise, the current max becomes the previous max and the counter -// is reset. - - if(max_counter > 0 && previous_max >= max) + if(config.smoothing_only) { - ; + for(int j = 0; j < total_buffers; j++) + buffer[j][i] = current_value; } else - if(max > 0.00001) { -// Get new slope based on current coef, peak, and reaction len. -// The slope has a counter which needs to expire before it can be -// replaced with a less steep value. - double x_db = DB::todb(max); - double y_db = config.calculate_db(x_db); - double y_linear = DB::fromdb(y_db); - double new_coef = y_linear / max; - double slope = (new_coef - current_coef) / reaction_samples; - previous_slope = slope; - previous_max = max; - previous_intercept = current_coef; - max_counter = reaction_samples; - } - else - { - previous_slope = 0.0; - previous_intercept = current_coef; - max_counter = 0; + double gain = calculate_gain(current_value); + for(int j = 0; j < total_buffers; j++) + { + buffer[j][i] = input_buffer[j][i] * gain; + } } - -//printf("%f %f %f %d\n", current_coef, previous_slope, previous_intercept, max_counter); - max_counter--; - current_coef = previous_intercept + - previous_slope * (reaction_samples - max_counter); - coefs[i] = current_coef; - - last_peak_age++; - reaction_position++; - if(reaction_position >= reaction_allocated) - reaction_position = 0; } -//printf("CompressorEffect::process_realtime 8 %f %f\n", input_buffer[0][0], coefs[0]); -// Multiply coef buffer by input buffer - for(int i = 0; i < PluginAClient::total_in_buffers; i++) - { - for(int j = 0; j < size; j++) - { - output_ptr[i][j + output_offset] = input_buffer[i][j] * coefs[j]; - } - } -//printf("CompressorEffect::process_realtime 9 %d\n", PluginAClient::total_in_buffers); -// Shift input forward - for(int i = 0; i < PluginAClient::total_in_buffers; i++) - { - for(int j = 0, k = size; k < input_size; j++, k++) - { - input_buffer[i][j] = input_buffer[i][k]; - } - } -//printf("CompressorEffect::process_realtime 10\n"); - input_size -= size; - } - else - { - for(int i = 0; i < PluginAClient::total_in_buffers; i++) - bzero(output_ptr[i], sizeof(double) * size); + } -//printf("CompressorEffect::process_realtime 11\n"); + + + return 0; } - +double CompressorEffect::calculate_gain(double input) +{ + double x_db = DB::todb(input); + double y_db = config.calculate_db(x_db); + double y_linear = DB::fromdb(y_db); + double gain; + if(input != 0) + gain = y_linear / input; + else + gain = 100000; + return gain; +} @@ -460,25 +549,29 @@ int CompressorEffect::process_realtime(int64_t size, double **input_ptr, double CompressorConfig::CompressorConfig() { reaction_len = 1.0; - preview_len = 1.0; min_db = -80.0; min_x = min_db; min_y = min_db; max_x = 0; max_y = 0; trigger = 0; + no_trigger = 1; + smoothing_only = 0; + decay_len = 1.0; } void CompressorConfig::copy_from(CompressorConfig &that) { this->reaction_len = that.reaction_len; - this->preview_len = that.preview_len; + this->decay_len = that.decay_len; this->min_db = that.min_db; this->min_x = that.min_x; this->min_y = that.min_y; this->max_x = that.max_x; this->max_y = that.max_y; this->trigger = that.trigger; + this->no_trigger = that.no_trigger; + this->smoothing_only = that.smoothing_only; levels.remove_all(); for(int i = 0; i < that.levels.total; i++) this->levels.append(that.levels.values[i]); @@ -486,7 +579,24 @@ void CompressorConfig::copy_from(CompressorConfig &that) int CompressorConfig::equivalent(CompressorConfig &that) { - return 0; + if(!EQUIV(this->reaction_len, that.reaction_len) || + !EQUIV(this->decay_len, that.decay_len) || + this->trigger != that.trigger || + this->no_trigger != that.no_trigger || + this->smoothing_only != that.smoothing_only) + return 0; + if(this->levels.total != that.levels.total) return 0; + for(int i = 0; + i < this->levels.total && i < that.levels.total; + i++) + { + compressor_point_t *this_level = &this->levels.values[i]; + compressor_point_t *that_level = &that.levels.values[i]; + if(!EQUIV(this_level->x, that_level->x) || + !EQUIV(this_level->y, that_level->y)) + return 0; + } + return 1; } void CompressorConfig::interpolate(CompressorConfig &prev, @@ -684,26 +794,32 @@ CompressorWindow::CompressorWindow(CompressorEffect *plugin, int x, int y) void CompressorWindow::create_objects() { int x = 35, y = 10; + int control_margin = 120; add_subwindow(canvas = new CompressorCanvas(plugin, x, y, - get_w() - x - 120, + get_w() - x - control_margin - 10, get_h() - y - 70)); canvas->set_cursor(CROSS_CURSOR); - x = get_w() - 110; - add_subwindow(new BC_Title(x, y, _("Preview secs:"))); - y += 20; - add_subwindow(preview = new CompressorPreview(plugin, x, y)); - y += 30; + x = get_w() - control_margin; add_subwindow(new BC_Title(x, y, _("Reaction secs:"))); y += 20; add_subwindow(reaction = new CompressorReaction(plugin, x, y)); y += 30; + add_subwindow(new BC_Title(x, y, _("Decay secs:"))); + y += 20; + add_subwindow(decay = new CompressorDecay(plugin, x, y)); + y += 30; add_subwindow(new BC_Title(x, y, _("Trigger:"))); y += 20; add_subwindow(trigger = new CompressorTrigger(plugin, x, y)); y += 30; + add_subwindow(no_trigger = new CompressorNoTrigger(plugin, x, y)); + if(plugin->config.no_trigger) trigger->disable(); + y += 30; + add_subwindow(smooth = new CompressorSmooth(plugin, x, y)); + y += 60; add_subwindow(clear = new CompressorClear(plugin, x, y)); x = 10; y = get_h() - 40; @@ -796,9 +912,22 @@ void CompressorWindow::update() void CompressorWindow::update_textboxes() { - preview->update((float)plugin->config.preview_len); - trigger->update((int64_t)plugin->config.trigger); - reaction->update((float)plugin->config.reaction_len); + if(atol(trigger->get_text()) != plugin->config.trigger) + trigger->update((int64_t)plugin->config.trigger); + if(no_trigger->get_value() != plugin->config.no_trigger) + no_trigger->update(plugin->config.no_trigger); + + if(plugin->config.no_trigger && trigger->get_enabled()) + trigger->disable(); + else + if(!plugin->config.no_trigger && !trigger->get_enabled()) + trigger->enable(); + + if(!EQUIV(atof(reaction->get_text()), plugin->config.reaction_len)) + reaction->update((float)plugin->config.reaction_len); + if(!EQUIV(atof(decay->get_text()), plugin->config.decay_len)) + decay->update((float)plugin->config.decay_len); + smooth->update(plugin->config.smoothing_only); if(canvas->current_operation == CompressorCanvas::DRAG) { x_text->update((float)plugin->config.levels.values[canvas->current_point].x); @@ -806,7 +935,7 @@ void CompressorWindow::update_textboxes() } } -#define POINT_W 6 +#define POINT_W 10 void CompressorWindow::update_canvas() { int y1, y2; @@ -822,9 +951,17 @@ void CompressorWindow::update_canvas() int x = canvas->get_w() * i / DIVISIONS; canvas->draw_line(x, 0, x, canvas->get_h()); } - - - + + + canvas->set_font(MEDIUMFONT); + canvas->draw_text(5, + canvas->get_h() / 2 - 20, + _("Output")); + canvas->draw_text(canvas->get_w() / 2 - canvas->get_text_width(MEDIUMFONT, _("Input level")) / 2, + canvas->get_h() - canvas->get_text_height(MEDIUMFONT), + _("Input")); + + canvas->set_color(BLACK); for(int i = 0; i < canvas->get_w(); i++) { @@ -956,19 +1093,6 @@ int CompressorCanvas::cursor_motion_event() -CompressorPreview::CompressorPreview(CompressorEffect *plugin, int x, int y) - : BC_TextBox(x, y, 100, 1, (float)plugin->config.preview_len) -{ - this->plugin = plugin; -} - -int CompressorPreview::handle_event() -{ - plugin->config.preview_len = atof(get_text()); - plugin->send_configure_change(); - return 1; -} - CompressorReaction::CompressorReaction(CompressorEffect *plugin, int x, int y) @@ -986,6 +1110,19 @@ int CompressorReaction::handle_event() return 1; } +CompressorDecay::CompressorDecay(CompressorEffect *plugin, int x, int y) + : BC_TextBox(x, y, 100, 1, (float)plugin->config.decay_len) +{ + this->plugin = plugin; +} +int CompressorDecay::handle_event() +{ + plugin->config.decay_len = atof(get_text()); + plugin->send_configure_change(); + return 1; +} + + CompressorX::CompressorX(CompressorEffect *plugin, int x, int y) : BC_TextBox(x, y, 100, 1, "") @@ -1024,6 +1161,9 @@ int CompressorY::handle_event() } + + + CompressorTrigger::CompressorTrigger(CompressorEffect *plugin, int x, int y) : BC_TextBox(x, y, (int64_t)100, (int64_t)1, (int64_t)plugin->config.trigger) { @@ -1040,6 +1180,24 @@ int CompressorTrigger::handle_event() +CompressorNoTrigger::CompressorNoTrigger(CompressorEffect *plugin, int x, int y) + : BC_CheckBox(x, y, plugin->config.no_trigger, "No trigger") +{ + this->plugin = plugin; +} +int CompressorNoTrigger::handle_event() +{ + plugin->config.no_trigger = get_value(); + plugin->thread->window->update(); + plugin->send_configure_change(); + return 1; +} + + + + + + CompressorClear::CompressorClear(CompressorEffect *plugin, int x, int y) : BC_GenericButton(x, y, _("Clear")) { @@ -1057,4 +1215,19 @@ int CompressorClear::handle_event() +CompressorSmooth::CompressorSmooth(CompressorEffect *plugin, int x, int y) + : BC_CheckBox(x, y, plugin->config.smoothing_only, _("Smooth only")) +{ + this->plugin = plugin; +} + +int CompressorSmooth::handle_event() +{ + plugin->config.smoothing_only = get_value(); + plugin->send_configure_change(); + return 1; +} + + + diff --git a/hvirtual/plugins/compressor/compressor.h b/hvirtual/plugins/compressor/compressor.h index a20158ba..c69c4290 100644 --- a/hvirtual/plugins/compressor/compressor.h +++ b/hvirtual/plugins/compressor/compressor.h @@ -36,14 +36,6 @@ public: }; -class CompressorPreview : public BC_TextBox -{ -public: - CompressorPreview(CompressorEffect *plugin, int x, int y); - int handle_event(); - CompressorEffect *plugin; -}; - class CompressorReaction : public BC_TextBox { public: @@ -84,7 +76,29 @@ public: CompressorEffect *plugin; }; +class CompressorDecay : public BC_TextBox +{ +public: + CompressorDecay(CompressorEffect *plugin, int x, int y); + int handle_event(); + CompressorEffect *plugin; +}; + +class CompressorSmooth : public BC_CheckBox +{ +public: + CompressorSmooth(CompressorEffect *plugin, int x, int y); + int handle_event(); + CompressorEffect *plugin; +}; +class CompressorNoTrigger : public BC_CheckBox +{ +public: + CompressorNoTrigger(CompressorEffect *plugin, int x, int y); + int handle_event(); + CompressorEffect *plugin; +}; @@ -101,12 +115,14 @@ public: CompressorCanvas *canvas; - CompressorPreview *preview; CompressorReaction *reaction; CompressorClear *clear; CompressorX *x_text; CompressorY *y_text; CompressorTrigger *trigger; + CompressorDecay *decay; + CompressorSmooth *smooth; + CompressorNoTrigger *no_trigger; CompressorEffect *plugin; }; @@ -144,11 +160,13 @@ public: void dump(); int trigger; + int no_trigger; double min_db; - double preview_len; double reaction_len; + double decay_len; double min_x, min_y; double max_x, max_y; + int smoothing_only; ArrayList levels; }; @@ -162,7 +180,11 @@ public: int is_realtime(); void read_data(KeyFrame *keyframe); void save_data(KeyFrame *keyframe); - int process_realtime(int64_t size, double **input_ptr, double **output_ptr); + int process_buffer(int64_t size, + double **buffer, + int64_t start_position, + int sample_rate); + double calculate_gain(double input); @@ -175,25 +197,25 @@ public: PLUGIN_CLASS_MEMBERS(CompressorConfig, CompressorThread) +// The raw input data for each channel with readahead double **input_buffer; +// Number of samples in the input buffer int64_t input_size; +// Number of samples allocated in the input buffer int64_t input_allocated; - double *reaction_buffer; - int64_t reaction_allocated; - int64_t reaction_position; - double current_coef; - double previous_slope; - double previous_intercept; - double previous_max; - double previous_coef; - int max_counter; - int total_samples; - -// Same coefs are applied to all channels - double *coefs; - int64_t coefs_allocated; - int64_t last_peak_age; - double last_peak; +// Starting sample of input buffer relative to project in requested rate. + int64_t input_start; + +// ending input value of smoothed input + double next_target; +// starting input value of smoothed input + double previous_target; +// samples between previous and next target value for readahead + int target_samples; +// current sample from 0 to target_samples + int target_current_sample; +// current smoothed input value + double current_value; }; diff --git a/hvirtual/plugins/defaulttheme/defaulttheme.C b/hvirtual/plugins/defaulttheme/defaulttheme.C index e174b7bc..b3eafbf1 100644 --- a/hvirtual/plugins/defaulttheme/defaulttheme.C +++ b/hvirtual/plugins/defaulttheme/defaulttheme.C @@ -53,7 +53,8 @@ char* DefaultThemeMain::plugin_title() Theme* DefaultThemeMain::new_theme() { theme = new DefaultTheme; - theme->set_path(PluginClient::get_path()); + extern unsigned char _binary_defaulttheme_data_start[]; + theme->set_data(_binary_defaulttheme_data_start); return theme; } @@ -113,6 +114,21 @@ void DefaultTheme::initialize() "pan_stick_small.png"); resources->pan_text_color = WHITE; + resources->xmeter_images = new_image_set(6, + "xmeter_normal.png", + "xmeter_green.png", + "xmeter_red.png", + "xmeter_yellow.png", + "xmeter_white.png", + "xmeter_over.png"); + resources->ymeter_images = new_image_set(6, + "ymeter_normal.png", + "ymeter_green.png", + "ymeter_red.png", + "ymeter_yellow.png", + "ymeter_white.png", + "ymeter_over.png"); + resources->hscroll_data = new_image_set(10, "hscroll_center_up.png", "hscroll_center_hi.png", @@ -184,22 +200,24 @@ void DefaultTheme::initialize() new_bg = new_image("new_bg.png"); - setformat_bg = new_image("setformat_bg.png"); + setformat_bg = new_image("setformat_bg2.png"); timebar_view_data = new_image("timebar_view.png"); + setformat_w = 600; + setformat_h = 560; setformat_x1 = 15; setformat_x2 = 100; setformat_x3 = 315; setformat_x4 = 415; setformat_y1 = 20; + setformat_y2 = 85; + setformat_y3 = 125; setformat_margin = 30; - setformat_w = 600; - setformat_h = 480; setformat_channels_x = 25; - setformat_channels_y = 173; + setformat_channels_y = 242; setformat_channels_w = 250; setformat_channels_h = 250; diff --git a/hvirtual/plugins/deinterlace/deinterlace.C b/hvirtual/plugins/deinterlace/deinterlace.C index 360efb41..01500f4b 100644 --- a/hvirtual/plugins/deinterlace/deinterlace.C +++ b/hvirtual/plugins/deinterlace/deinterlace.C @@ -4,14 +4,11 @@ #include "deinterwindow.h" #include "filexml.h" #include "keyframe.h" +#include "language.h" #include "picon_png.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -79,7 +76,7 @@ int DeInterlaceMain::is_realtime() { return 1; } -#define DEINTERLACE_EVEN_MACRO(type, components, dominance, max) \ +#define DEINTERLACE_EVEN_MACRO(type, components, dominance) \ { \ int w = input->get_w(); \ int h = input->get_h(); \ @@ -94,7 +91,7 @@ int DeInterlaceMain::is_realtime() { return 1; } } \ } -#define DEINTERLACE_AVG_EVEN_MACRO(type, components, dominance, max) \ +#define DEINTERLACE_AVG_EVEN_MACRO(type, temp_type, components, dominance) \ { \ int w = input->get_w(); \ int h = input->get_h(); \ @@ -103,7 +100,7 @@ int DeInterlaceMain::is_realtime() { return 1; } type **in_rows = (type**)input->get_rows(); \ type **out_rows = (type**)temp->get_rows(); \ int max_h = h - 1; \ - int64_t abs_diff = 0, total = 0; \ + temp_type abs_diff = 0, total = 0; \ \ for(int i = 0; i < max_h; i += 2) \ { \ @@ -121,8 +118,8 @@ int DeInterlaceMain::is_realtime() { return 1; } type *input_row3 = in_rows[out_number2]; \ type *temp_row1 = out_rows[out_number1]; \ type *temp_row2 = out_rows[out_number2]; \ - int64_t sum = 0; \ - int64_t accum_r, accum_b, accum_g, accum_a; \ + temp_type sum = 0; \ + temp_type accum_r, accum_b, accum_g, accum_a; \ \ memcpy(temp_row1, input_row1, w * components * sizeof(type)); \ for(int j = 0; j < w; j++) \ @@ -132,37 +129,37 @@ int DeInterlaceMain::is_realtime() { return 1; } accum_b = (*input_row1++) + (*input_row2++); \ if(components == 4) \ accum_a = (*input_row1++) + (*input_row2++); \ - accum_r >>= 1; \ - accum_g >>= 1; \ - accum_b >>= 1; \ - accum_a >>= 1; \ + accum_r /= 2; \ + accum_g /= 2; \ + accum_b /= 2; \ + accum_a /= 2; \ \ total += *input_row3; \ - sum = ((int)*input_row3++) - accum_r; \ + sum = ((temp_type)*input_row3++) - accum_r; \ abs_diff += (sum < 0 ? -sum : sum); \ *temp_row2++ = accum_r; \ \ total += *input_row3; \ - sum = ((int)*input_row3++) - accum_g; \ + sum = ((temp_type)*input_row3++) - accum_g; \ abs_diff += (sum < 0 ? -sum : sum); \ *temp_row2++ = accum_g; \ \ total += *input_row3; \ - sum = ((int)*input_row3++) - accum_b; \ + sum = ((temp_type)*input_row3++) - accum_b; \ abs_diff += (sum < 0 ? -sum : sum); \ *temp_row2++ = accum_b; \ \ if(components == 4) \ { \ total += *input_row3; \ - sum = ((int)*input_row3++) - accum_a; \ + sum = ((temp_type)*input_row3++) - accum_a; \ abs_diff += (sum < 0 ? -sum : sum); \ *temp_row2++ = accum_a; \ } \ } \ } \ \ - int64_t threshold = (int64_t)total * config.threshold / THRESHOLD_SCALAR; \ + temp_type threshold = (temp_type)total * config.threshold / THRESHOLD_SCALAR; \ /* printf("total=%lld threshold=%lld abs_diff=%lld\n", total, threshold, abs_diff); */ \ if(abs_diff > threshold || !config.adaptive) \ { \ @@ -177,7 +174,7 @@ int DeInterlaceMain::is_realtime() { return 1; } \ } -#define DEINTERLACE_AVG_MACRO(type, components) \ +#define DEINTERLACE_AVG_MACRO(type, temp_type, components) \ { \ int w = input->get_w(); \ int h = input->get_h(); \ @@ -192,7 +189,7 @@ int DeInterlaceMain::is_realtime() { return 1; } \ for(int j = 0; j < w * components; j++) \ { \ - result = ((uint64_t)input_row1[j] + input_row2[j]) >> 1; \ + result = ((temp_type)input_row1[j] + input_row2[j]) / 2; \ output_row1[j] = result; \ output_row2[j] = result; \ } \ @@ -229,19 +226,25 @@ void DeInterlaceMain::deinterlace_even(VFrame *input, VFrame *output, int domina { case BC_RGB888: case BC_YUV888: - DEINTERLACE_EVEN_MACRO(unsigned char, 3, dominance, 0xff); + DEINTERLACE_EVEN_MACRO(unsigned char, 3, dominance); + break; + case BC_RGB_FLOAT: + DEINTERLACE_EVEN_MACRO(float, 3, dominance); break; case BC_RGBA8888: case BC_YUVA8888: - DEINTERLACE_EVEN_MACRO(unsigned char, 4, dominance, 0xff); + DEINTERLACE_EVEN_MACRO(unsigned char, 4, dominance); + break; + case BC_RGBA_FLOAT: + DEINTERLACE_EVEN_MACRO(float, 4, dominance); break; case BC_RGB161616: case BC_YUV161616: - DEINTERLACE_EVEN_MACRO(uint16_t, 3, dominance, 0xffff); + DEINTERLACE_EVEN_MACRO(uint16_t, 3, dominance); break; case BC_RGBA16161616: case BC_YUVA16161616: - DEINTERLACE_EVEN_MACRO(uint16_t, 4, dominance, 0xffff); + DEINTERLACE_EVEN_MACRO(uint16_t, 4, dominance); break; } } @@ -252,19 +255,25 @@ void DeInterlaceMain::deinterlace_avg_even(VFrame *input, VFrame *output, int do { case BC_RGB888: case BC_YUV888: - DEINTERLACE_AVG_EVEN_MACRO(unsigned char, 3, dominance, 0xff); + DEINTERLACE_AVG_EVEN_MACRO(unsigned char, int64_t, 3, dominance); + break; + case BC_RGB_FLOAT: + DEINTERLACE_AVG_EVEN_MACRO(float, double, 3, dominance); break; case BC_RGBA8888: case BC_YUVA8888: - DEINTERLACE_AVG_EVEN_MACRO(unsigned char, 4, dominance, 0xff); + DEINTERLACE_AVG_EVEN_MACRO(unsigned char, int64_t, 4, dominance); + break; + case BC_RGBA_FLOAT: + DEINTERLACE_AVG_EVEN_MACRO(float, double, 4, dominance); break; case BC_RGB161616: case BC_YUV161616: - DEINTERLACE_AVG_EVEN_MACRO(uint16_t, 3, dominance, 0xffff); + DEINTERLACE_AVG_EVEN_MACRO(uint16_t, int64_t, 3, dominance); break; case BC_RGBA16161616: case BC_YUVA16161616: - DEINTERLACE_AVG_EVEN_MACRO(uint16_t, 4, dominance, 0xffff); + DEINTERLACE_AVG_EVEN_MACRO(uint16_t, int64_t, 4, dominance); break; } } @@ -275,19 +284,25 @@ void DeInterlaceMain::deinterlace_avg(VFrame *input, VFrame *output) { case BC_RGB888: case BC_YUV888: - DEINTERLACE_AVG_MACRO(unsigned char, 3); + DEINTERLACE_AVG_MACRO(unsigned char, uint64_t, 3); + break; + case BC_RGB_FLOAT: + DEINTERLACE_AVG_MACRO(float, double, 3); break; case BC_RGBA8888: case BC_YUVA8888: - DEINTERLACE_AVG_MACRO(unsigned char, 4); + DEINTERLACE_AVG_MACRO(unsigned char, uint64_t, 4); + break; + case BC_RGBA_FLOAT: + DEINTERLACE_AVG_MACRO(float, double, 4); break; case BC_RGB161616: case BC_YUV161616: - DEINTERLACE_AVG_MACRO(uint16_t, 3); + DEINTERLACE_AVG_MACRO(uint16_t, uint64_t, 3); break; case BC_RGBA16161616: case BC_YUVA16161616: - DEINTERLACE_AVG_MACRO(uint16_t, 4); + DEINTERLACE_AVG_MACRO(uint16_t, uint64_t, 4); break; } } @@ -300,10 +315,16 @@ void DeInterlaceMain::deinterlace_swap(VFrame *input, VFrame *output, int domina case BC_YUV888: DEINTERLACE_SWAP_MACRO(unsigned char, 3, dominance); break; + case BC_RGB_FLOAT: + DEINTERLACE_SWAP_MACRO(float, 3, dominance); + break; case BC_RGBA8888: case BC_YUVA8888: DEINTERLACE_SWAP_MACRO(unsigned char, 4, dominance); break; + case BC_RGBA_FLOAT: + DEINTERLACE_SWAP_MACRO(float, 4, dominance); + break; case BC_RGB161616: case BC_YUV161616: DEINTERLACE_SWAP_MACRO(uint16_t, 3, dominance); diff --git a/hvirtual/plugins/delayvideo/delayvideo.C b/hvirtual/plugins/delayvideo/delayvideo.C index 3e38e69b..6b003589 100644 --- a/hvirtual/plugins/delayvideo/delayvideo.C +++ b/hvirtual/plugins/delayvideo/delayvideo.C @@ -3,15 +3,11 @@ #include "defaults.h" #include "delayvideo.h" #include "filexml.h" +#include "language.h" #include "picon_png.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #include @@ -21,13 +17,7 @@ - -PluginClient* new_plugin(PluginServer *server) -{ - return new DelayVideo(server); -} - - +REGISTER_PLUGIN(DelayVideo) @@ -86,18 +76,12 @@ void DelayVideoWindow::create_objects() add_subwindow(new BC_Title(x, y, _("Delay seconds:"))); y += 20; add_subwindow(slider = new DelayVideoSlider(plugin, x, y)); - update_gui(); show_window(); flush(); } -int DelayVideoWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(DelayVideoWindow) void DelayVideoWindow::update_gui() { @@ -118,7 +102,7 @@ void DelayVideoWindow::update_gui() DelayVideoSlider::DelayVideoSlider(DelayVideo *plugin, int x, int y) - : BC_TextBox(x, y, 150, 1, "") + : BC_TextBox(x, y, 150, 1, plugin->config.length) { this->plugin = plugin; } @@ -140,40 +124,7 @@ int DelayVideoSlider::handle_event() - - -DelayVideoThread::DelayVideoThread(DelayVideo *plugin) - : Thread() -{ - this->plugin = plugin; - set_synchronous(0); - completion.lock(); -} - - -DelayVideoThread::~DelayVideoThread() -{ -// Window only deleted here - delete window; -} - - -void DelayVideoThread::run() -{ - BC_DisplayInfo info; - window = new DelayVideoWindow(plugin, - info.get_abs_cursor_x() - 105, - info.get_abs_cursor_y() - 60); - window->create_objects(); - int result = window->run_window(); - completion.unlock(); -// Last command executed in thread - if(result) plugin->client_side_close(); -} - - - - +PLUGIN_THREAD_OBJECT(DelayVideo, DelayVideoThread, DelayVideoWindow) @@ -190,14 +141,7 @@ DelayVideo::DelayVideo(PluginServer *server) DelayVideo::~DelayVideo() { -//printf("DelayVideo::~DelayVideo 1\n"); - if(thread) - { - thread->window->set_done(0); - thread->completion.lock(); - delete thread; - } -//printf("DelayVideo::~DelayVideo 1\n"); + PLUGIN_DESTRUCTOR_MACRO if(buffer) { @@ -209,11 +153,6 @@ DelayVideo::~DelayVideo() delete [] buffer; //printf("DelayVideo::~DelayVideo 1\n"); } - - save_defaults(); -//printf("DelayVideo::~DelayVideo 1\n"); - delete defaults; -//printf("DelayVideo::~DelayVideo 2\n"); } void DelayVideo::reset() @@ -342,7 +281,7 @@ void DelayVideo::update_gui() { load_configuration(); thread->window->lock_window(); - thread->window->update_gui(); + thread->window->slider->update(config.length); thread->window->unlock_window(); } } diff --git a/hvirtual/plugins/delayvideo/delayvideo.h b/hvirtual/plugins/delayvideo/delayvideo.h index 669f8c7c..e99fe197 100644 --- a/hvirtual/plugins/delayvideo/delayvideo.h +++ b/hvirtual/plugins/delayvideo/delayvideo.h @@ -30,7 +30,8 @@ public: int64_t next_frame, int64_t current_frame); - double length; + // kjb - match defined update() type of float instead of double. + float length; }; @@ -61,20 +62,7 @@ public: }; - -class DelayVideoThread : public Thread -{ -public: - DelayVideoThread(DelayVideo *plugin); - ~DelayVideoThread(); - - void run(); - - DelayVideo *plugin; - DelayVideoWindow *window; - Mutex completion; -}; - +PLUGIN_THREAD_HEADER(DelayVideo, DelayVideoThread, DelayVideoWindow) diff --git a/hvirtual/plugins/denoisefft/denoisefft.C b/hvirtual/plugins/denoisefft/denoisefft.C index 6ceb11b3..84c96da1 100644 --- a/hvirtual/plugins/denoisefft/denoisefft.C +++ b/hvirtual/plugins/denoisefft/denoisefft.C @@ -213,9 +213,9 @@ DenoiseFFTWindow::DenoiseFFTWindow(DenoiseFFTEffect *plugin, int x, int y) : BC_Window(plugin->gui_string, x, y, - 220, + 300, 120, - 220, + 300, 120, 0, 0, @@ -445,7 +445,7 @@ void DenoiseFFTEffect::collect_noise() step = -1; } - for(int i = 0; i < config.samples; i++) + for(int i = 0; i < config.samples; i += WINDOW_SIZE) { collect_engine->process_buffer(collection_start, WINDOW_SIZE, diff --git a/hvirtual/plugins/denoisevideo/denoisevideo.C b/hvirtual/plugins/denoisevideo/denoisevideo.C index 1601a570..53979bdd 100644 --- a/hvirtual/plugins/denoisevideo/denoisevideo.C +++ b/hvirtual/plugins/denoisevideo/denoisevideo.C @@ -4,6 +4,7 @@ #include "filexml.h" #include "guicast.h" #include "keyframe.h" +#include "language.h" #include "picon_png.h" #include "vframe.h" @@ -14,10 +15,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -271,6 +268,7 @@ int DenoiseVideo::process_realtime(VFrame *input, VFrame *output) *output_row = (type)(*accumulation_ptr); \ } \ else \ + if(sizeof(type) < 4) \ *output_row = (type)CLIP((*accumulation_ptr), 0, max); \ } \ else \ @@ -297,11 +295,19 @@ int DenoiseVideo::process_realtime(VFrame *input, VFrame *output) DENOISE_MACRO(unsigned char, 3, 0xff); break; + case BC_RGB_FLOAT: + DENOISE_MACRO(float, 3, 1.0); + break; + case BC_RGBA8888: case BC_YUVA8888: DENOISE_MACRO(unsigned char, 4, 0xff); break; + case BC_RGBA_FLOAT: + DENOISE_MACRO(float, 4, 1.0); + break; + case BC_RGB161616: case BC_YUV161616: DENOISE_MACRO(uint16_t, 3, 0xffff); diff --git a/hvirtual/plugins/dot/dot.C b/hvirtual/plugins/dot/dot.C index e0d32baf..4a0d6980 100644 --- a/hvirtual/plugins/dot/dot.C +++ b/hvirtual/plugins/dot/dot.C @@ -5,24 +5,18 @@ #include "dot.h" #include "dotwindow.h" #include "effecttv.h" +#include "language.h" #include #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) -PluginClient* new_plugin(PluginServer *server) -{ - return new DotMain(server); -} +REGISTER_PLUGIN(DotMain) @@ -282,6 +276,14 @@ DotClient::DotClient(DotServer *server) } \ else \ { \ + if(sizeof(type) == 4) \ + { \ + output[0] = (type)(pattern & 0xff0000) / 0xff0000; \ + output[1] = (type)(pattern & 0xff00) / 0xff00; \ + output[2] = (type)(pattern & 0xff) / 0xff; \ + if(components > 3) output[3] = 1; \ + } \ + else \ if(sizeof(type) == 2) \ { \ output[0] = (pattern & 0xff0000) >> 8; \ @@ -395,10 +397,18 @@ void DotClient::draw_dot(int xx, DRAW_DOT(uint8_t, 3, 0x0); break; + case BC_RGB_FLOAT: + DRAW_DOT(float, 3, 0x0); + break; + case BC_YUV888: DRAW_DOT(uint8_t, 3, 0x80); break; + case BC_RGBA_FLOAT: + DRAW_DOT(float, 4, 0x0); + break; + case BC_RGBA8888: DRAW_DOT(uint8_t, 4, 0x0); break; @@ -424,23 +434,45 @@ void DotClient::draw_dot(int xx, } } -#define RGB_TO_Y(type) \ +#define RGB_TO_Y(type, is_yuv) \ { \ type *row_local = (type*)row; \ \ + if(sizeof(type) == 4) \ + { \ + int r = (int)(row_local[0] * 0xff); \ + int g = (int)(row_local[0] * 0xff); \ + int b = (int)(row_local[0] * 0xff); \ + CLAMP(r, 0, 0xff); \ + CLAMP(g, 0, 0xff); \ + CLAMP(b, 0, 0xff); \ + i = plugin->effecttv->RtoY[r] + \ + plugin->effecttv->RtoY[g] + \ + plugin->effecttv->RtoY[b]; \ + } \ + else \ if(sizeof(type) == 2) \ { \ - i = plugin->effecttv->RtoY[row_local[0] >> 8]; \ - i += plugin->effecttv->GtoY[row_local[1] >> 8]; \ - i += plugin->effecttv->BtoY[row_local[2] >> 8]; \ + if(is_yuv) \ + i = (int)row_local[0] >> 8; \ + else \ + { \ + i = plugin->effecttv->RtoY[(int)row_local[0] >> 8]; \ + i += plugin->effecttv->GtoY[(int)row_local[1] >> 8]; \ + i += plugin->effecttv->BtoY[(int)row_local[2] >> 8]; \ + } \ } \ else \ { \ - i = plugin->effecttv->RtoY[row_local[0]]; \ - i += plugin->effecttv->GtoY[row_local[1]]; \ - i += plugin->effecttv->BtoY[row_local[2]]; \ + if(is_yuv) \ + i = (int)row_local[0]; \ + else \ + { \ + i = plugin->effecttv->RtoY[(int)row_local[0]]; \ + i += plugin->effecttv->GtoY[(int)row_local[1]]; \ + i += plugin->effecttv->BtoY[(int)row_local[2]]; \ + } \ } \ -/*printf("RGB_TO_Y %d %d %d %d\n", plugin->effecttv->RtoY[row_local[0]], plugin->effecttv->GtoY[row_local[1]], plugin->effecttv->BtoY[row_local[2]], i);*/ \ } unsigned char DotClient::RGBtoY(unsigned char *row, int color_model) @@ -450,20 +482,24 @@ unsigned char DotClient::RGBtoY(unsigned char *row, int color_model) switch(color_model) { case BC_RGB888: - case BC_YUV888: - RGB_TO_Y(uint8_t); - break; case BC_RGBA8888: + RGB_TO_Y(uint8_t, 0); + break; + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + RGB_TO_Y(float, 0); + break; + case BC_YUV888: case BC_YUVA8888: - RGB_TO_Y(uint8_t); + RGB_TO_Y(uint8_t, 1); break; case BC_RGB161616: - case BC_YUV161616: - RGB_TO_Y(uint16_t); - break; case BC_RGBA16161616: + RGB_TO_Y(uint16_t, 0); + break; + case BC_YUV161616: case BC_YUVA16161616: - RGB_TO_Y(uint16_t); + RGB_TO_Y(uint16_t, 1); break; } diff --git a/hvirtual/plugins/dot/dotwindow.C b/hvirtual/plugins/dot/dotwindow.C index fcc15030..59de3b3c 100644 --- a/hvirtual/plugins/dot/dotwindow.C +++ b/hvirtual/plugins/dot/dotwindow.C @@ -1,10 +1,7 @@ #include "bcdisplayinfo.h" #include "dotwindow.h" - -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) +#include "language.h" +#include "pluginclient.h" PLUGIN_THREAD_OBJECT(DotMain, DotThread, DotWindow) @@ -45,12 +42,7 @@ int DotWindow::create_objects() return 0; } -int DotWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(DotWindow) diff --git a/hvirtual/plugins/fieldframe/fieldframe.C b/hvirtual/plugins/fieldframe/fieldframe.C index 36804b01..ac99392b 100644 --- a/hvirtual/plugins/fieldframe/fieldframe.C +++ b/hvirtual/plugins/fieldframe/fieldframe.C @@ -55,23 +55,23 @@ public: FieldFrameWindow *gui; }; -class FieldFrameFirst : public BC_Radial -{ -public: - FieldFrameFirst(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y); - int handle_event(); - FieldFrame *plugin; - FieldFrameWindow *gui; -}; - -class FieldFrameSecond : public BC_Radial -{ -public: - FieldFrameSecond(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y); - int handle_event(); - FieldFrame *plugin; - FieldFrameWindow *gui; -}; +// class FieldFrameFirst : public BC_Radial +// { +// public: +// FieldFrameFirst(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y); +// int handle_event(); +// FieldFrame *plugin; +// FieldFrameWindow *gui; +// }; +// +// class FieldFrameSecond : public BC_Radial +// { +// public: +// FieldFrameSecond(FieldFrame *plugin, FieldFrameWindow *gui, int x, int y); +// int handle_event(); +// FieldFrame *plugin; +// FieldFrameWindow *gui; +// }; class FieldFrameWindow : public BC_Window { @@ -82,8 +82,8 @@ public: FieldFrame *plugin; FieldFrameTop *top; FieldFrameBottom *bottom; - FieldFrameFirst *first; - FieldFrameSecond *second; +// FieldFrameFirst *first; +// FieldFrameSecond *second; }; @@ -149,9 +149,9 @@ FieldFrameWindow::FieldFrameWindow(FieldFrame *plugin, int x, int y) x, y, 230, - 200, + 100, 230, - 200, + 100, 0, 0, 1) @@ -165,10 +165,10 @@ void FieldFrameWindow::create_objects() add_subwindow(top = new FieldFrameTop(plugin, this, x, y)); y += 30; add_subwindow(bottom = new FieldFrameBottom(plugin, this, x, y)); - y += 30; - add_subwindow(first = new FieldFrameFirst(plugin, this, x, y)); - y += 30; - add_subwindow(second = new FieldFrameSecond(plugin, this, x, y)); +// y += 30; +// add_subwindow(first = new FieldFrameFirst(plugin, this, x, y)); +// y += 30; +// add_subwindow(second = new FieldFrameSecond(plugin, this, x, y)); show_window(); flush(); @@ -238,50 +238,50 @@ int FieldFrameBottom::handle_event() -FieldFrameFirst::FieldFrameFirst(FieldFrame *plugin, - FieldFrameWindow *gui, - int x, - int y) - : BC_Radial(x, - y, - plugin->config.first_frame == 0, - _("First frame is first field")) -{ - this->plugin = plugin; - this->gui = gui; -} - -int FieldFrameFirst::handle_event() -{ - plugin->config.first_frame = 0; - gui->second->update(0); - plugin->send_configure_change(); - return 1; -} - - - - -FieldFrameSecond::FieldFrameSecond(FieldFrame *plugin, - FieldFrameWindow *gui, - int x, - int y) - : BC_Radial(x, - y, - plugin->config.first_frame == 1, - _("Second frame is first field")) -{ - this->plugin = plugin; - this->gui = gui; -} - -int FieldFrameSecond::handle_event() -{ - plugin->config.first_frame = 1; - gui->first->update(0); - plugin->send_configure_change(); - return 1; -} +// FieldFrameFirst::FieldFrameFirst(FieldFrame *plugin, +// FieldFrameWindow *gui, +// int x, +// int y) +// : BC_Radial(x, +// y, +// plugin->config.first_frame == 0, +// _("First frame is first field")) +// { +// this->plugin = plugin; +// this->gui = gui; +// } +// +// int FieldFrameFirst::handle_event() +// { +// plugin->config.first_frame = 0; +// gui->second->update(0); +// plugin->send_configure_change(); +// return 1; +// } +// +// +// +// +// FieldFrameSecond::FieldFrameSecond(FieldFrame *plugin, +// FieldFrameWindow *gui, +// int x, +// int y) +// : BC_Radial(x, +// y, +// plugin->config.first_frame == 1, +// _("Second frame is first field")) +// { +// this->plugin = plugin; +// this->gui = gui; +// } +// +// int FieldFrameSecond::handle_event() +// { +// plugin->config.first_frame = 1; +// gui->first->update(0); +// plugin->send_configure_change(); +// return 1; +// } @@ -407,8 +407,8 @@ void FieldFrame::update_gui() thread->window->lock_window(); thread->window->top->update(config.field_dominance == TOP_FIELD_FIRST); thread->window->bottom->update(config.field_dominance == BOTTOM_FIELD_FIRST); - thread->window->first->update(config.first_frame == 0); - thread->window->second->update(config.first_frame == 1); +// thread->window->first->update(config.first_frame == 0); +// thread->window->second->update(config.first_frame == 1); thread->window->unlock_window(); } } @@ -437,28 +437,31 @@ int FieldFrame::process_buffer(VFrame *frame, } // Get input frames - int64_t field1_position = start_position * 2 + config.first_frame; - int64_t field2_position = start_position * 2 + config.first_frame; - if(config.field_dominance == TOP_FIELD_FIRST) - field2_position++; - else - field1_position++; + int64_t field1_position = start_position * 2; + int64_t field2_position = start_position * 2 + 1; -//printf("FieldFrame::process_buffer %d %lld %lld\n", config.first_frame, field1_position, field2_position); +// printf("FieldFrame::process_buffer %d %lld %lld\n", +// config.field_dominance, +// field1_position, +// field2_position); read_frame(input, 0, field1_position, frame_rate * 2); - - apply_field(frame, input, 0); - + apply_field(frame, + input, + config.field_dominance == TOP_FIELD_FIRST ? 0 : 1); read_frame(input, 0, field2_position, frame_rate * 2); + apply_field(frame, + input, + config.field_dominance == TOP_FIELD_FIRST ? 1 : 0); + + - apply_field(frame, input, 1); return result; diff --git a/hvirtual/plugins/flash/flash.C b/hvirtual/plugins/flash/flash.C index 6e2b5893..64b5aa78 100644 --- a/hvirtual/plugins/flash/flash.C +++ b/hvirtual/plugins/flash/flash.C @@ -1,14 +1,11 @@ #include "flash.h" #include "edl.inc" #include "overlayframe.h" +#include "language.h" #include "picon_png.h" #include "vframe.h" #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) PluginClient* new_plugin(PluginServer *server) { @@ -36,13 +33,14 @@ int FlashMain::uses_gui() { return 0; } NEW_PICON_MACRO(FlashMain) -#define FLASH(type, components, max, chroma_offset) \ +#define FLASH(type, temp_type, components, max, chroma_offset) \ { \ - int foreground = (int)(fraction * max + 0.5); \ - int chroma_foreground = foreground; \ + float round_factor = (sizeof(type) < 4) ? 0.5 : 0; \ + temp_type foreground = (temp_type)(fraction * max + round_factor); \ + temp_type chroma_foreground = foreground; \ if(chroma_offset) chroma_foreground = foreground * chroma_offset / max; \ - int transparency = max - foreground; \ -/* printf("FLASH %d %d %d\n", foreground, transparency, is_before); */\ + temp_type transparency = max - foreground; \ + \ for(int i = 0; i < h; i++) \ { \ type *in_row = (type*)incoming->get_rows()[i]; \ @@ -100,28 +98,34 @@ int FlashMain::process_realtime(VFrame *incoming, VFrame *outgoing) switch(incoming->get_color_model()) { case BC_RGB888: - FLASH(unsigned char, 3, 0xff, 0x0); + FLASH(unsigned char, int, 3, 0xff, 0x0); + break; + case BC_RGB_FLOAT: + FLASH(float, float, 3, 1.0, 0x0); break; case BC_RGBA8888: - FLASH(unsigned char, 4, 0xff, 0x0); + FLASH(unsigned char, int, 4, 0xff, 0x0); + break; + case BC_RGBA_FLOAT: + FLASH(float, float, 4, 1.0, 0x0); break; case BC_YUV888: - FLASH(unsigned char, 3, 0xff, 0x80); + FLASH(unsigned char, int, 3, 0xff, 0x80); break; case BC_YUVA8888: - FLASH(unsigned char, 4, 0xff, 0x80); + FLASH(unsigned char, int, 4, 0xff, 0x80); break; case BC_RGB161616: - FLASH(uint16_t, 3, 0xffff, 0x0); + FLASH(uint16_t, int, 3, 0xffff, 0x0); break; case BC_RGBA16161616: - FLASH(uint16_t, 4, 0xffff, 0x0); + FLASH(uint16_t, int, 4, 0xffff, 0x0); break; case BC_YUV161616: - FLASH(uint16_t, 3, 0xffff, 0x8000); + FLASH(uint16_t, int, 3, 0xffff, 0x8000); break; case BC_YUVA16161616: - FLASH(uint16_t, 4, 0xffff, 0x8000); + FLASH(uint16_t, int, 4, 0xffff, 0x8000); break; } diff --git a/hvirtual/plugins/flip/flip.C b/hvirtual/plugins/flip/flip.C index a10b8be6..b306ed64 100644 --- a/hvirtual/plugins/flip/flip.C +++ b/hvirtual/plugins/flip/flip.C @@ -4,16 +4,12 @@ #include "filexml.h" #include "flip.h" #include "flipwindow.h" +#include "language.h" #include "picon_png.h" #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - REGISTER_PLUGIN(FlipMain) @@ -73,25 +69,25 @@ char* FlipMain::plugin_title() { return N_("Flip"); } int FlipMain::is_realtime() { return 1; } -#define SWAP_PIXELS(components, in, out) \ +#define SWAP_PIXELS(type, components, in, out) \ { \ - in[0] ^= out[0]; \ - out[0] ^= in[0]; \ - in[0] ^= out[0]; \ + type temp = in[0]; \ + in[0] = out[0]; \ + out[0] = temp; \ \ - in[1] ^= out[1]; \ - out[1] ^= in[1]; \ - in[1] ^= out[1]; \ + temp = in[1]; \ + in[1] = out[1]; \ + out[1] = temp; \ \ - in[2] ^= out[2]; \ - out[2] ^= in[2]; \ - in[2] ^= out[2]; \ + temp = in[2]; \ + in[2] = out[2]; \ + out[2] = temp; \ \ if(components == 4) \ { \ - in[3] ^= out[3]; \ - out[3] ^= in[3]; \ - in[3] ^= out[3]; \ + temp = in[3]; \ + in[3] = out[3]; \ + out[3] = temp; \ } \ } @@ -110,7 +106,7 @@ int FlipMain::is_realtime() { return 1; } output_row = output_rows[j]; \ for(k = 0; k < w; k++) \ { \ - SWAP_PIXELS(components, output_row, input_row); \ + SWAP_PIXELS(type, components, output_row, input_row); \ output_row += components; \ input_row += components; \ } \ @@ -125,7 +121,7 @@ int FlipMain::is_realtime() { return 1; } output_row = output_rows[i] + (w - 1) * components; \ for(k = 0; k < w / 2; k++) \ { \ - SWAP_PIXELS(components, output_row, input_row); \ + SWAP_PIXELS(type, components, output_row, input_row); \ input_row += components; \ output_row -= components; \ } \ @@ -147,6 +143,9 @@ int FlipMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) case BC_YUV888: FLIP_MACRO(unsigned char, 3); break; + case BC_RGB_FLOAT: + FLIP_MACRO(float, 3); + break; case BC_RGB161616: case BC_YUV161616: FLIP_MACRO(uint16_t, 3); @@ -155,6 +154,9 @@ int FlipMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) case BC_YUVA8888: FLIP_MACRO(unsigned char, 4); break; + case BC_RGBA_FLOAT: + FLIP_MACRO(float, 4); + break; case BC_RGBA16161616: case BC_YUVA16161616: FLIP_MACRO(uint16_t, 4); diff --git a/hvirtual/plugins/framefield/framefield.C b/hvirtual/plugins/framefield/framefield.C index fbe1e4ac..729fe605 100644 --- a/hvirtual/plugins/framefield/framefield.C +++ b/hvirtual/plugins/framefield/framefield.C @@ -442,7 +442,7 @@ int FrameField::process_buffer(VFrame *frame, } // Averaging 2 pixels -#define AVERAGE(type, components, offset) \ +#define AVERAGE(type, temp_type, components, offset) \ { \ type **rows = (type**)frame->get_rows(); \ int w = frame->get_w(); \ @@ -455,8 +455,8 @@ int FrameField::process_buffer(VFrame *frame, type *row3 = rows[i + 2]; \ for(int j = 0; j < row_size; j++) \ { \ - int64_t sum = (int64_t)*row1++ + (int64_t)*row3++; \ - *row2++ = (sum >> 1); \ + temp_type sum = (temp_type)*row1++ + (temp_type)*row3++; \ + *row2++ = (sum / 2); \ } \ } \ } @@ -523,19 +523,25 @@ void FrameField::average_rows(int offset, VFrame *frame) { case BC_RGB888: case BC_YUV888: - AVERAGE(unsigned char, 3, offset); + AVERAGE(unsigned char, int64_t, 3, offset); + break; + case BC_RGB_FLOAT: + AVERAGE(float, float, 3, offset); break; case BC_RGBA8888: case BC_YUVA8888: - AVERAGE(unsigned char, 4, offset); + AVERAGE(unsigned char, int64_t, 4, offset); + break; + case BC_RGBA_FLOAT: + AVERAGE(float, float, 4, offset); break; case BC_RGB161616: case BC_YUV161616: - AVERAGE(uint16_t, 3, offset); + AVERAGE(uint16_t, int64_t, 3, offset); break; case BC_RGBA16161616: case BC_YUVA16161616: - AVERAGE(uint16_t, 4, offset); + AVERAGE(uint16_t, int64_t, 4, offset); break; } } diff --git a/hvirtual/plugins/gradient/gradient.C b/hvirtual/plugins/gradient/gradient.C index 4427f047..e815ff51 100644 --- a/hvirtual/plugins/gradient/gradient.C +++ b/hvirtual/plugins/gradient/gradient.C @@ -608,10 +608,15 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) #define SQR(x) ((x) * (x)) -#define CREATE_GRADIENT(type, components, max) \ +#define CREATE_GRADIENT(type, components) \ { \ /* Synthesize linear gradient for lookups */ \ \ + r_table = malloc(sizeof(type) * gradient_size); \ + g_table = malloc(sizeof(type) * gradient_size); \ + b_table = malloc(sizeof(type) * gradient_size); \ + a_table = malloc(sizeof(type) * gradient_size); \ + \ for(int i = 0; i < gradient_size; i++) \ { \ float opacity; \ @@ -624,10 +629,10 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) else \ opacity = 1.0; \ transparency = 1.0 - opacity; \ - r_table[i] = (int)(out1 * opacity + in1 * transparency); \ - g_table[i] = (int)(out2 * opacity + in2 * transparency); \ - b_table[i] = (int)(out3 * opacity + in3 * transparency); \ - a_table[i] = (int)(out4 * opacity + in4 * transparency); \ + ((type*)r_table)[i] = (type)(out1 * opacity + in1 * transparency); \ + ((type*)g_table)[i] = (type)(out2 * opacity + in2 * transparency); \ + ((type*)b_table)[i] = (type)(out3 * opacity + in3 * transparency); \ + ((type*)a_table)[i] = (type)(out4 * opacity + in4 * transparency); \ } \ \ for(int i = pkg->y1; i < pkg->y2; i++) \ @@ -684,10 +689,10 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) } \ else \ { \ - out_row[0] = r_table[input_y]; \ - out_row[1] = g_table[input_y]; \ - out_row[2] = b_table[input_y]; \ - if(components == 4) out_row[3] = a_table[input_y]; \ + out_row[0] = ((type*)r_table)[input_y]; \ + out_row[1] = ((type*)g_table)[input_y]; \ + out_row[2] = ((type*)b_table)[input_y]; \ + if(components == 4) out_row[3] = ((type*)a_table)[input_y]; \ } \ \ out_row += components; \ @@ -698,8 +703,6 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) void GradientUnit::process_package(LoadPackage *package) { GradientPackage *pkg = (GradientPackage*)package; - int in1, in2, in3, in4; - int out1, out2, out3, out4; int h = plugin->input->get_h(); int w = plugin->input->get_w(); int half_w = w / 2; @@ -708,10 +711,10 @@ void GradientUnit::process_package(LoadPackage *package) int in_radius = (int)(plugin->config.in_radius / 100 * gradient_size); int out_radius = (int)(plugin->config.out_radius / 100 * gradient_size); double effect_angle = plugin->config.angle / 360 * 2 * M_PI; - int r_table[gradient_size]; - int g_table[gradient_size]; - int b_table[gradient_size]; - int a_table[gradient_size]; + void *r_table = 0; + void *g_table = 0; + void *b_table = 0; + void *a_table = 0; if(in_radius > out_radius) { @@ -722,50 +725,93 @@ void GradientUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { case BC_RGB888: - in1 = plugin->config.in_r; - in2 = plugin->config.in_g; - in3 = plugin->config.in_b; - in4 = plugin->config.in_a; - out1 = plugin->config.out_r; - out2 = plugin->config.out_g; - out3 = plugin->config.out_b; - out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, 3, 0xff) + { + int in1 = plugin->config.in_r; + int in2 = plugin->config.in_g; + int in3 = plugin->config.in_b; + int in4 = plugin->config.in_a; + int out1 = plugin->config.out_r; + int out2 = plugin->config.out_g; + int out3 = plugin->config.out_b; + int out4 = plugin->config.out_a; + CREATE_GRADIENT(unsigned char, 3) break; + } + case BC_RGBA8888: - in1 = plugin->config.in_r; - in2 = plugin->config.in_g; - in3 = plugin->config.in_b; - in4 = plugin->config.in_a; - out1 = plugin->config.out_r; - out2 = plugin->config.out_g; - out3 = plugin->config.out_b; - out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, 4, 0xff) + { + int in1 = plugin->config.in_r; + int in2 = plugin->config.in_g; + int in3 = plugin->config.in_b; + int in4 = plugin->config.in_a; + int out1 = plugin->config.out_r; + int out2 = plugin->config.out_g; + int out3 = plugin->config.out_b; + int out4 = plugin->config.out_a; + CREATE_GRADIENT(unsigned char, 4) break; + } + + case BC_RGB_FLOAT: + { + float in1 = (float)plugin->config.in_r / 0xff; + float in2 = (float)plugin->config.in_g / 0xff; + float in3 = (float)plugin->config.in_b / 0xff; + float in4 = (float)plugin->config.in_a / 0xff; + float out1 = (float)plugin->config.out_r / 0xff; + float out2 = (float)plugin->config.out_g / 0xff; + float out3 = (float)plugin->config.out_b / 0xff; + float out4 = (float)plugin->config.out_a / 0xff; + CREATE_GRADIENT(float, 3) + break; + } + + case BC_RGBA_FLOAT: + { + float in1 = (float)plugin->config.in_r / 0xff; + float in2 = (float)plugin->config.in_g / 0xff; + float in3 = (float)plugin->config.in_b / 0xff; + float in4 = (float)plugin->config.in_a / 0xff; + float out1 = (float)plugin->config.out_r / 0xff; + float out2 = (float)plugin->config.out_g / 0xff; + float out3 = (float)plugin->config.out_b / 0xff; + float out4 = (float)plugin->config.out_a / 0xff; + CREATE_GRADIENT(float, 4) + break; + } + case BC_RGB161616: - in1 = (plugin->config.in_r << 8) | plugin->config.in_r; - in2 = (plugin->config.in_g << 8) | plugin->config.in_g; - in3 = (plugin->config.in_b << 8) | plugin->config.in_b; - in4 = (plugin->config.in_a << 8) | plugin->config.in_a; - out1 = (plugin->config.out_r << 8) | plugin->config.out_r; - out2 = (plugin->config.out_g << 8) | plugin->config.out_g; - out3 = (plugin->config.out_b << 8) | plugin->config.out_b; - out4 = (plugin->config.out_a << 8) | plugin->config.out_a; - CREATE_GRADIENT(uint16_t, 3, 0xffff) + { + int in1 = (plugin->config.in_r << 8) | plugin->config.in_r; + int in2 = (plugin->config.in_g << 8) | plugin->config.in_g; + int in3 = (plugin->config.in_b << 8) | plugin->config.in_b; + int in4 = (plugin->config.in_a << 8) | plugin->config.in_a; + int out1 = (plugin->config.out_r << 8) | plugin->config.out_r; + int out2 = (plugin->config.out_g << 8) | plugin->config.out_g; + int out3 = (plugin->config.out_b << 8) | plugin->config.out_b; + int out4 = (plugin->config.out_a << 8) | plugin->config.out_a; + CREATE_GRADIENT(uint16_t, 3) break; + } + case BC_RGBA16161616: - in1 = (plugin->config.in_r << 8) | plugin->config.in_r; - in2 = (plugin->config.in_g << 8) | plugin->config.in_g; - in3 = (plugin->config.in_b << 8) | plugin->config.in_b; - in4 = (plugin->config.in_a << 8) | plugin->config.in_a; - out1 = (plugin->config.out_r << 8) | plugin->config.out_r; - out2 = (plugin->config.out_g << 8) | plugin->config.out_g; - out3 = (plugin->config.out_b << 8) | plugin->config.out_b; - out4 = (plugin->config.out_a << 8) | plugin->config.out_a; - CREATE_GRADIENT(uint16_t, 4, 0xffff) + { + int in1 = (plugin->config.in_r << 8) | plugin->config.in_r; + int in2 = (plugin->config.in_g << 8) | plugin->config.in_g; + int in3 = (plugin->config.in_b << 8) | plugin->config.in_b; + int in4 = (plugin->config.in_a << 8) | plugin->config.in_a; + int out1 = (plugin->config.out_r << 8) | plugin->config.out_r; + int out2 = (plugin->config.out_g << 8) | plugin->config.out_g; + int out3 = (plugin->config.out_b << 8) | plugin->config.out_b; + int out4 = (plugin->config.out_a << 8) | plugin->config.out_a; + CREATE_GRADIENT(uint16_t, 4) break; + } + case BC_YUV888: + { + int in1, in2, in3, in4; + int out1, out2, out3, out4; yuv.rgb_to_yuv_8(plugin->config.in_r, plugin->config.in_g, plugin->config.in_b, @@ -780,9 +826,14 @@ void GradientUnit::process_package(LoadPackage *package) out2, out3); out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, 3, 0xff) + CREATE_GRADIENT(unsigned char, 3) break; + } + case BC_YUVA8888: + { + int in1, in2, in3, in4; + int out1, out2, out3, out4; yuv.rgb_to_yuv_8(plugin->config.in_r, plugin->config.in_g, plugin->config.in_b, @@ -797,9 +848,14 @@ void GradientUnit::process_package(LoadPackage *package) out2, out3); out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, 4, 0xff) + CREATE_GRADIENT(unsigned char, 4) break; + } + case BC_YUV161616: + { + int in1, in2, in3, in4; + int out1, out2, out3, out4; yuv.rgb_to_yuv_16( (plugin->config.in_r << 8) | plugin->config.in_r, (plugin->config.in_g << 8) | plugin->config.in_g, @@ -816,9 +872,14 @@ void GradientUnit::process_package(LoadPackage *package) out2, out3); out4 = (plugin->config.out_a << 8) | plugin->config.out_a; - CREATE_GRADIENT(uint16_t, 3, 0xffff) + CREATE_GRADIENT(uint16_t, 3) break; + } + case BC_YUVA16161616: + { + int in1, in2, in3, in4; + int out1, out2, out3, out4; yuv.rgb_to_yuv_16( (plugin->config.in_r << 8) | plugin->config.in_r, (plugin->config.in_g << 8) | plugin->config.in_g, @@ -835,9 +896,15 @@ void GradientUnit::process_package(LoadPackage *package) out2, out3); out4 = (plugin->config.out_a << 8) | plugin->config.out_a; - CREATE_GRADIENT(uint16_t, 4, 0xffff) + CREATE_GRADIENT(uint16_t, 4) break; + } } + + if(r_table) free(r_table); + if(g_table) free(g_table); + if(b_table) free(b_table); + if(a_table) free(a_table); } diff --git a/hvirtual/plugins/histogram/histogram.C b/hvirtual/plugins/histogram/histogram.C index a56289b9..4a8775d3 100644 --- a/hvirtual/plugins/histogram/histogram.C +++ b/hvirtual/plugins/histogram/histogram.C @@ -32,9 +32,19 @@ class HistogramWindow; #define HISTOGRAM_ALPHA 3 #define HISTOGRAM_VALUE 4 -// range -#define HISTOGRAM_RANGE 0x10000 - +// Number of divisions in histogram. +// 65536 + min and max range to speed up the tabulation +#define HISTOGRAM_RANGE 0x13333 +#define FLOAT_RANGE 1.2 +// Minimum value in percentage +#define HISTOGRAM_MIN -10 +#define FLOAT_MIN -0.1 +// Maximum value in percentage +#define HISTOGRAM_MAX 110 +#define FLOAT_MAX 1.1 + +#define PRECISION 0.001 +#define DIGITS 3 #define THRESHOLD_SCALE 1000 class HistogramConfig @@ -49,16 +59,19 @@ public: int64_t prev_frame, int64_t next_frame, int64_t current_frame); +// Used by constructor and reset button void reset(int do_mode); - - int input_min[5]; - int input_mid[5]; - int input_max[5]; - int output_min[5]; - int output_max[5]; + void boundaries(); + +// Range 0 - 1.0 + float input_min[5]; + float input_mid[5]; + float input_max[5]; + float output_min[5]; + float output_max[5]; int automatic; int mode; - int threshold; + float threshold; }; @@ -78,6 +91,7 @@ public: int button_press_event(); int button_release_event(); int cursor_motion_event(); + int input_to_pixel(float input); int operation; enum @@ -134,10 +148,14 @@ public: HistogramWindow *gui, int x, int y, - int *output); + float *output, + int subscript, + int operation); int handle_event(); HistogramMain *plugin; - int *output; + float *output; + int subscript; + int operation; }; class HistogramWindow : public BC_Window @@ -151,12 +169,13 @@ public: void update(int do_input); void update_mode(); void update_canvas(); + void draw_canvas_overlay(); void update_input(); void update_output(); HistogramSlider *input, *output; HistogramAuto *automatic; - HistogramMode *mode_v, *mode_r, *mode_g, *mode_b, *mode_a; + HistogramMode *mode_v, *mode_r, *mode_g, *mode_b /*, *mode_a */; HistogramText *input_min; HistogramText *input_mid; HistogramText *input_max; @@ -165,6 +184,12 @@ public: HistogramText *threshold; BC_SubWindow *canvas; HistogramMain *plugin; + int canvas_w; + int canvas_h; + int title1_x; + int title2_x; + int title3_x; + int title4_x; BC_Pixmap *max_picon, *mid_picon, *min_picon; }; @@ -190,7 +215,7 @@ public: PLUGIN_CLASS_MEMBERS(HistogramConfig, HistogramThread) // Convert input to input curve - float calculate_curve(float input, int mode); + float calculate_transfer(float input, int mode); // Calculate automatic settings void calculate_automatic(VFrame *data); // Calculate histogram @@ -234,6 +259,8 @@ public: LoadClient* new_client(); LoadPackage* new_package(); HistogramMain *plugin; + int total_size; + int operation; enum @@ -276,34 +303,53 @@ void HistogramConfig::reset(int do_mode) { for(int i = 0; i < 5; i++) { - input_min[i] = 0; - input_mid[i] = 0x8000; - input_max[i] = 0xffff; - output_min[i] = 0; - output_max[i] = 0xffff; + input_min[i] = 0.0; + input_mid[i] = .5; + input_max[i] = 1.0; + output_min[i] = 0.0; + output_max[i] = 1.0; } if(do_mode) { mode = HISTOGRAM_VALUE; automatic = 0; - threshold = 10; + threshold = 0.1; + } +} + +void HistogramConfig::boundaries() +{ + for(int i = 0; i < 5; i++) + { + CLAMP(input_min[i], FLOAT_MIN, FLOAT_MAX); + CLAMP(input_mid[i], FLOAT_MIN, FLOAT_MAX); + CLAMP(input_max[i], FLOAT_MIN, FLOAT_MAX); + CLAMP(output_min[i], FLOAT_MIN, FLOAT_MAX); + CLAMP(output_max[i], FLOAT_MIN, FLOAT_MAX); + input_min[i] = Units::quantize(input_min[i], PRECISION); +// Can't quantize or it would screw up automatic calculation. +// input_mid[i] = Units::quantize(input_mid[i], PRECISION); + input_max[i] = Units::quantize(input_max[i], PRECISION); + output_min[i] = Units::quantize(output_min[i], PRECISION); + output_max[i] = Units::quantize(output_max[i], PRECISION); } + CLAMP(threshold, 0, 1); } int HistogramConfig::equivalent(HistogramConfig &that) { for(int i = 0; i < 5; i++) { - if(input_min[i] != that.input_min[i] || - input_mid[i] != that.input_mid[i] || - input_max[i] != that.input_max[i] || - output_min[i] != that.output_min[i] || - output_max[i] != that.output_max[i]) return 0; + if(!EQUIV(input_min[i], that.input_min[i]) || + !EQUIV(input_mid[i], that.input_mid[i]) || + !EQUIV(input_max[i], that.input_max[i]) || + !EQUIV(output_min[i], that.output_min[i]) || + !EQUIV(output_max[i], that.output_max[i])) return 0; } if(automatic != that.automatic || mode != that.mode || - threshold != that.threshold) return 0; + !EQUIV(threshold, that.threshold)) return 0; return 1; } @@ -335,13 +381,13 @@ void HistogramConfig::interpolate(HistogramConfig &prev, for(int i = 0; i < 5; i++) { - input_min[i] = (int)(prev.input_min[i] * prev_scale + next.input_min[i] * next_scale); - input_mid[i] = (int)(prev.input_mid[i] * prev_scale + next.input_mid[i] * next_scale); - input_max[i] = (int)(prev.input_max[i] * prev_scale + next.input_max[i] * next_scale); - output_min[i] = (int)(prev.output_min[i] * prev_scale + next.output_min[i] * next_scale); - output_max[i] = (int)(prev.output_max[i] * prev_scale + next.output_max[i] * next_scale); + input_min[i] = prev.input_min[i] * prev_scale + next.input_min[i] * next_scale; + input_mid[i] = prev.input_mid[i] * prev_scale + next.input_mid[i] * next_scale; + input_max[i] = prev.input_max[i] * prev_scale + next.input_max[i] * next_scale; + output_min[i] = prev.output_min[i] * prev_scale + next.output_min[i] * next_scale; + output_max[i] = prev.output_max[i] * prev_scale + next.output_max[i] * next_scale; } - threshold = (int)(prev.threshold * prev_scale + next.threshold * next_scale); + threshold = prev.threshold * prev_scale + next.threshold * next_scale; automatic = prev.automatic; mode = prev.mode; } @@ -409,12 +455,12 @@ int HistogramWindow::create_objects() y, HISTOGRAM_BLUE, _("Blue"))); - x += 70; - add_subwindow(mode_a = new HistogramMode(plugin, - x, - y, - HISTOGRAM_ALPHA, - _("Alpha"))); +// x += 70; +// add_subwindow(mode_a = new HistogramMode(plugin, +// x, +// y, +// HISTOGRAM_ALPHA, +// _("Alpha"))); x = x1; y += 30; @@ -424,7 +470,9 @@ int HistogramWindow::create_objects() this, x, y, - &plugin->config.input_min[subscript]); + &plugin->config.input_min[subscript], + subscript, + HistogramSlider::DRAG_MIN_INPUT); input_min->create_objects(); x += 90; add_subwindow(new BC_Title(x, y, _("Mid:"))); @@ -433,9 +481,11 @@ int HistogramWindow::create_objects() this, x, y, - &plugin->config.input_mid[subscript]); + &plugin->config.input_mid[subscript], + subscript, + HistogramSlider::DRAG_MID_INPUT); input_mid->create_objects(); - input_mid->update((int64_t)plugin->config.input_mid[subscript]); + input_mid->update(plugin->config.input_mid[subscript]); x += 90; add_subwindow(new BC_Title(x, y, _("Max:"))); x += 40; @@ -443,18 +493,42 @@ int HistogramWindow::create_objects() this, x, y, - &plugin->config.input_max[subscript]); + &plugin->config.input_max[subscript], + subscript, + HistogramSlider::DRAG_MAX_INPUT); input_max->create_objects(); x = x1; y += 30; + canvas_w = get_w() - x - x; + canvas_h = get_h() - y - 170; + title1_x = x; + title2_x = x + (int)(canvas_w * -FLOAT_MIN / FLOAT_RANGE); + title3_x = x + (int)(canvas_w * (1.0 - FLOAT_MIN) / FLOAT_RANGE); + title4_x = x + (int)(canvas_w); add_subwindow(canvas = new BC_SubWindow(x, y, - get_w() - x - x, - get_h() - y - 150, + canvas_w, + canvas_h, 0xffffff)); + draw_canvas_overlay(); + canvas->flash(); - y += canvas->get_h() + 10; + y += canvas->get_h() + 1; + add_subwindow(new BC_Title(title1_x, + y, + "-10%")); + add_subwindow(new BC_Title(title2_x, + y, + "0%")); + add_subwindow(new BC_Title(title3_x - get_text_width(MEDIUMFONT, "100"), + y, + "100%")); + add_subwindow(new BC_Title(title4_x - get_text_width(MEDIUMFONT, "110"), + y, + "110%")); + + y += 20; add_subwindow(input = new HistogramSlider(plugin, this, x, @@ -471,7 +545,9 @@ int HistogramWindow::create_objects() this, x, y, - &plugin->config.output_min[subscript]); + &plugin->config.output_min[subscript], + subscript, + HistogramSlider::DRAG_MIN_OUTPUT); output_min->create_objects(); x += 90; add_subwindow(new BC_Title(x, y, _("Max:"))); @@ -480,7 +556,9 @@ int HistogramWindow::create_objects() this, x, y, - &plugin->config.output_max[subscript]); + &plugin->config.output_max[subscript], + subscript, + HistogramSlider::DRAG_MAX_OUTPUT); output_max->create_objects(); x = x1; @@ -514,7 +592,9 @@ int HistogramWindow::create_objects() this, x, y, - &plugin->config.threshold); + &plugin->config.threshold, + 0, + 0); threshold->create_objects(); show_window(); @@ -527,7 +607,7 @@ WINDOW_CLOSE_EVENT(HistogramWindow) void HistogramWindow::update(int do_input) { automatic->update(plugin->config.automatic); - threshold->update((int64_t)plugin->config.threshold); + threshold->update(plugin->config.threshold); update_mode(); if(do_input) update_input(); @@ -538,17 +618,17 @@ void HistogramWindow::update_input() { int subscript = plugin->config.mode; input->update(); - input_min->update((int64_t)plugin->config.input_min[subscript]); - input_mid->update((int64_t)plugin->config.input_mid[subscript]); - input_max->update((int64_t)plugin->config.input_max[subscript]); + input_min->update(plugin->config.input_min[subscript]); + input_mid->update(plugin->config.input_mid[subscript]); + input_max->update(plugin->config.input_max[subscript]); } void HistogramWindow::update_output() { int subscript = plugin->config.mode; output->update(); - output_min->update((int64_t)plugin->config.output_min[subscript]); - output_max->update((int64_t)plugin->config.output_max[subscript]); + output_min->update(plugin->config.output_min[subscript]); + output_max->update(plugin->config.output_max[subscript]); } void HistogramWindow::update_mode() @@ -557,7 +637,7 @@ void HistogramWindow::update_mode() mode_r->update(plugin->config.mode == HISTOGRAM_RED ? 1 : 0); mode_g->update(plugin->config.mode == HISTOGRAM_GREEN ? 1 : 0); mode_b->update(plugin->config.mode == HISTOGRAM_BLUE ? 1 : 0); - mode_a->update(plugin->config.mode == HISTOGRAM_ALPHA ? 1 : 0); +// mode_a->update(plugin->config.mode == HISTOGRAM_ALPHA ? 1 : 0); input_min->output = &plugin->config.input_min[plugin->config.mode]; input_mid->output = &plugin->config.input_mid[plugin->config.mode]; input_max->output = &plugin->config.input_max[plugin->config.mode]; @@ -565,11 +645,39 @@ void HistogramWindow::update_mode() output_max->output = &plugin->config.output_max[plugin->config.mode]; } +void HistogramWindow::draw_canvas_overlay() +{ + canvas->set_color(0x00ff00); + int y1; + for(int i = 0; i < canvas_w; i++) + { + float input = (float)i / + canvas_w * + FLOAT_RANGE + + FLOAT_MIN; + float output = plugin->calculate_transfer(input, plugin->config.mode); + int y2 = canvas_h - (int)(output * canvas_h); + if(i > 0) + { + canvas->draw_line(i - 1, y1, i, y2); + } + y1 = y2; + } + + canvas->set_color(0xff0000); + canvas->draw_line(title2_x - canvas->get_x(), + 0, + title2_x - canvas->get_x(), + canvas_h); + canvas->draw_line(title3_x - canvas->get_x(), + 0, + title3_x - canvas->get_x(), + canvas_h); +} + void HistogramWindow::update_canvas() { int64_t *accum = plugin->accum[plugin->config.mode]; - int canvas_w = canvas->get_w(); - int canvas_h = canvas->get_h(); int accum_per_canvas_i = HISTOGRAM_RANGE / canvas_w + 1; float accum_per_canvas_f = (float)HISTOGRAM_RANGE / canvas_w; int normalize = 0; @@ -596,7 +704,6 @@ void HistogramWindow::update_canvas() // max = max * canvas_h / normalize; max = (int)(log(max) / log(normalize) * canvas_h); - canvas->set_color(0xffffff); canvas->draw_line(i, 0, i, canvas_h - max); canvas->set_color(0x000000); @@ -609,19 +716,7 @@ void HistogramWindow::update_canvas() canvas->draw_box(0, 0, canvas_w, canvas_h); } - canvas->set_color(0x00ff00); - int y1; - for(int i = 0; i < canvas_w; i++) - { - int y2 = canvas_h - (int)(plugin->calculate_curve((float)i / canvas_w * (HISTOGRAM_RANGE - 1), - plugin->config.mode) * canvas_h / (HISTOGRAM_RANGE - 1)); - if(i > 0) - { - canvas->draw_line(i - 1, y1, i, y2); - } - y1 = y2; - } - + draw_canvas_overlay(); canvas->flash(); } @@ -670,6 +765,11 @@ HistogramSlider::HistogramSlider(HistogramMain *plugin, operation = NONE; } +int HistogramSlider::input_to_pixel(float input) +{ + return (int)((input - FLOAT_MIN) / FLOAT_RANGE * get_w()); +} + int HistogramSlider::button_press_event() { if(is_event_win() && cursor_inside()) @@ -683,7 +783,7 @@ int HistogramSlider::button_press_event() if(is_input) { - int x1 = (int)(plugin->config.input_mid[subscript] * w / 0xffff) - + int x1 = input_to_pixel(plugin->config.input_mid[subscript]) - gui->mid_picon->get_w() / 2; int x2 = x1 + gui->mid_picon->get_w(); if(get_cursor_x() >= x1 && get_cursor_x() < x2 && @@ -697,7 +797,7 @@ int HistogramSlider::button_press_event() { if(is_input) { - int x1 = (int)(plugin->config.input_min[subscript] * w / 0xffff) - + int x1 = input_to_pixel(plugin->config.input_min[subscript]) - gui->mid_picon->get_w() / 2; int x2 = x1 + gui->mid_picon->get_w(); if(get_cursor_x() >= x1 && get_cursor_x() < x2 && @@ -708,7 +808,7 @@ int HistogramSlider::button_press_event() } else { - int x1 = (int)(plugin->config.output_min[subscript] * w / 0xffff) - + int x1 = input_to_pixel(plugin->config.output_min[subscript]) - gui->mid_picon->get_w() / 2; int x2 = x1 + gui->mid_picon->get_w(); if(get_cursor_x() >= x1 && get_cursor_x() < x2 && @@ -723,7 +823,7 @@ int HistogramSlider::button_press_event() { if(is_input) { - int x1 = (int)(plugin->config.input_max[subscript] * w / 0xffff) - + int x1 = input_to_pixel(plugin->config.input_max[subscript]) - gui->mid_picon->get_w() / 2; int x2 = x1 + gui->mid_picon->get_w(); if(get_cursor_x() >= x1 && get_cursor_x() < x2 && @@ -734,7 +834,7 @@ int HistogramSlider::button_press_event() } else { - int x1 = (int)(plugin->config.output_max[subscript] * w / 0xffff) - + int x1 = input_to_pixel(plugin->config.output_max[subscript]) - gui->mid_picon->get_w() / 2; int x2 = x1 + gui->mid_picon->get_w(); if(get_cursor_x() >= x1 && get_cursor_x() < x2 && @@ -764,8 +864,8 @@ int HistogramSlider::cursor_motion_event() //printf("HistogramSlider::cursor_motion_event 1\n"); if(operation != NONE) { - float value = (float)get_cursor_x() * 0xffff / get_w(); - CLAMP(value, 0, 0xffff); + float value = (float)get_cursor_x() / get_w() * FLOAT_RANGE + FLOAT_MIN; + CLAMP(value, FLOAT_MIN, FLOAT_MAX); int subscript = plugin->config.mode; float input_min = plugin->config.input_min[subscript]; float input_max = plugin->config.input_max[subscript]; @@ -776,12 +876,14 @@ int HistogramSlider::cursor_motion_event() { case DRAG_MIN_INPUT: input_min = MIN(input_max, value); - plugin->config.input_min[subscript] = (int)input_min; + plugin->config.input_min[subscript] = input_min; input_mid = input_min + (input_max - input_min) * input_mid_fraction; break; case DRAG_MID_INPUT: CLAMP(value, input_min, input_max); - input_mid = (int)value; +// Quantize value here so automatic calculation doesn't get rounding errors. + value = Units::quantize(value, PRECISION); + input_mid = value; break; case DRAG_MAX_INPUT: input_max = MAX(input_mid, value); @@ -789,11 +891,11 @@ int HistogramSlider::cursor_motion_event() break; case DRAG_MIN_OUTPUT: value = MIN(plugin->config.output_max[subscript], value); - plugin->config.output_min[subscript] = (int)value; + plugin->config.output_min[subscript] = value; break; case DRAG_MAX_OUTPUT: value = MAX(plugin->config.output_min[subscript], value); - plugin->config.output_max[subscript] = (int)value; + plugin->config.output_max[subscript] = value; break; } @@ -801,21 +903,21 @@ int HistogramSlider::cursor_motion_event() operation == DRAG_MID_INPUT || operation == DRAG_MAX_INPUT) { - plugin->config.input_mid[subscript] = (int)input_mid; - plugin->config.input_min[subscript] = (int)input_min; - plugin->config.input_max[subscript] = (int)input_max; + plugin->config.input_mid[subscript] = input_mid; + plugin->config.input_min[subscript] = input_min; + plugin->config.input_max[subscript] = input_max; + plugin->config.boundaries(); gui->update_input(); } else { + plugin->config.boundaries(); gui->update_output(); } gui->unlock_window(); plugin->send_configure_change(); -//printf("HistogramSlider::cursor_motion_event 2\n"); gui->lock_window("HistogramSlider::cursor_motion_event"); -//printf("HistogramSlider::cursor_motion_event 3\n"); return 1; } return 0; @@ -858,7 +960,7 @@ void HistogramSlider::update() if(is_input) { draw_line(i, quarter_h, i, half_h); - color = (int)plugin->calculate_curve(i * 0xffff / w, + color = (int)plugin->calculate_transfer(i * 0xffff / w, subscript); set_color(((r * color / 0xffff) << 16) | ((g * color / 0xffff) << 8) | @@ -870,13 +972,13 @@ void HistogramSlider::update() } - int min; - int max; + float min; + float max; if(is_input) { draw_pixmap(gui->mid_picon, - (int)(plugin->config.input_mid[subscript] * w / 0xffff) - + input_to_pixel(plugin->config.input_mid[subscript]) - gui->mid_picon->get_w() / 2, half_h + 1); min = plugin->config.input_min[subscript]; @@ -889,10 +991,10 @@ void HistogramSlider::update() } draw_pixmap(gui->min_picon, - min * w / 0xffff - gui->min_picon->get_w() / 2, + input_to_pixel(min) - gui->min_picon->get_w() / 2, half_h + 1); draw_pixmap(gui->max_picon, - max * w / 0xffff - gui->max_picon->get_w() / 2, + input_to_pixel(max) - gui->max_picon->get_w() / 2, half_h + 1); // printf("HistogramSlider::update %d %d\n", min, max); @@ -940,6 +1042,8 @@ int HistogramMode::handle_event() { plugin->config.mode = value; plugin->thread->window->update_mode(); + plugin->thread->window->update_input(); + plugin->thread->window->update_output(); plugin->thread->window->input->update(); plugin->thread->window->output->update(); plugin->send_configure_change(); @@ -958,17 +1062,23 @@ HistogramText::HistogramText(HistogramMain *plugin, HistogramWindow *gui, int x, int y, - int *output) + float *output, + int subscript, + int operation) : BC_TumbleTextBox(gui, - (int64_t)*output, - (int64_t)0, - (int64_t)0xff, + (float)*output, + (float)FLOAT_MIN, + (float)FLOAT_MAX, x, y, 60) { this->plugin = plugin; this->output = output; + this->subscript = subscript; + this->operation = operation; + set_precision(DIGITS); + set_increment(PRECISION); } @@ -976,7 +1086,24 @@ int HistogramText::handle_event() { if(output) { - *output = atol(get_text()); + float *input_min = &plugin->config.input_min[subscript]; + float *input_max = &plugin->config.input_max[subscript]; + float *input_mid = &plugin->config.input_mid[subscript]; + float input_mid_fraction = (*input_mid - *input_min) / + (*input_max - *input_min); + + *output = atof(get_text()); + + if(operation != HistogramSlider::NONE && + operation != HistogramSlider::DRAG_MID_INPUT && + operation != HistogramSlider::DRAG_MIN_OUTPUT && + operation != HistogramSlider::DRAG_MAX_OUTPUT) + { + *input_mid = *input_min + + (*input_max - *input_min) * + input_mid_fraction; + plugin->thread->window->update_input(); + } } plugin->thread->window->input->update(); plugin->thread->window->output->update(); @@ -1104,11 +1231,11 @@ int HistogramMain::load_defaults() config.output_min[i] = defaults->get(string, config.output_min[i]); sprintf(string, "OUTPUT_MAX_%d", i); config.output_max[i] = defaults->get(string, config.output_max[i]); -//printf("HistogramMain::load_defaults %d %f %d\n", config.input_min[i], config.input_mid[i], config.input_max[i]); } config.automatic = defaults->get("AUTOMATIC", config.automatic); config.mode = defaults->get("MODE", config.mode); config.threshold = defaults->get("THRESHOLD", config.threshold); + config.boundaries(); return 0; } @@ -1217,58 +1344,75 @@ void HistogramMain::read_data(KeyFrame *keyframe) } } } + config.boundaries(); } -float HistogramMain::calculate_curve(float input, int subscript) +float HistogramMain::calculate_transfer(float input, int subscript) { float y1, y2, y3, y4; - float min = (float)config.input_min[subscript]; - float max = (float)config.input_max[subscript]; - float mid = (float)config.input_mid[subscript]; - float half = (float)HISTOGRAM_RANGE / 2; - float output, output_perfect; - float control = 1.0 / M_PI; + float input_min = config.input_min[subscript]; + float input_max = config.input_max[subscript]; + float input_mid = config.input_mid[subscript]; + float output_min = config.output_min[subscript]; + float output_max = config.output_max[subscript]; + float output; + float output_perfect; float output_linear; +// Expand input // Below minimum - if(input < min) return 0; + if(input < input_min) return output_min; // Above maximum - if(input >= max) return HISTOGRAM_RANGE - 1; + if(input >= input_max) return output_max; - float slope1 = half / (mid - min); - float slope2 = half / (max - mid); + float slope1 = 0.5 / (input_mid - input_min); + float slope2 = 0.5 / (input_max - input_mid); float min_slope = MIN(slope1, slope2); // value of 45` diagonal with midpoint - output_perfect = half + min_slope * (input - mid); + output_perfect = 0.5 + min_slope * (input - input_mid); // Left hand side - if(input < mid) + if(input < input_mid) { // Fraction of perfect diagonal to use - float mid_fraction = (input - min) / (mid - min); + float mid_fraction = (input - input_min) / (input_mid - input_min); // value of line connecting min to mid - output_linear = mid_fraction * half; + output_linear = mid_fraction * 0.5; // Blend perfect diagonal with linear - output = output_linear * (1.0 - mid_fraction) + output_perfect * mid_fraction; + output = output_linear * + (1.0 - mid_fraction) + + output_perfect * + mid_fraction; } else { // Fraction of perfect diagonal to use - float mid_fraction = (max - input) / (max - mid); + float mid_fraction = (input_max - input) / (input_max - input_mid); // value of line connecting max to mid - output_linear = half + (1.0 - mid_fraction) * half; + output_linear = 0.5 + (1.0 - mid_fraction) * 0.5; // Blend perfect diagonal with linear - output = output_linear * (1.0 - mid_fraction) + output_perfect * mid_fraction; + output = output_linear * + (1.0 - mid_fraction) + + output_perfect * + mid_fraction; } +// Expand value + if(subscript != HISTOGRAM_VALUE) + { + output = calculate_transfer(output, HISTOGRAM_VALUE); + } +// Compress output for value followed by channel + output = output_min + + output * + (output_max - output_min); - -// printf("HistogramMain::calculate_curve 1 %.0f %.0f %.0f %.0f %.0f\n", +// printf("HistogramMain::calculate_transfer 1 %.0f %.0f %.0f %.0f %.0f\n", // output, // input, // min, @@ -1277,6 +1421,7 @@ float HistogramMain::calculate_curve(float input, int subscript) return output; } + void HistogramMain::calculate_histogram(VFrame *data) { @@ -1325,7 +1470,7 @@ void HistogramMain::calculate_automatic(VFrame *data) { calculate_histogram(data); - +// Do each channel for(int i = 0; i < 3; i++) { int64_t *accum = this->accum[i]; @@ -1336,28 +1481,37 @@ void HistogramMain::calculate_automatic(VFrame *data) max = MAX(accum[j], max); } - int threshold = config.threshold * max / THRESHOLD_SCALE; + int threshold = (int)(config.threshold * max); -// Minimums +// Minimum input config.input_min[i] = 0; - for(int j = 0; j < HISTOGRAM_RANGE; j++) + for(int j = (int)(HISTOGRAM_RANGE * (0 - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN)); + j < (int)(HISTOGRAM_RANGE * (1 - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN)); j++) { if(accum[j] > threshold) { - config.input_min[i] = j; + config.input_min[i] = (float)j / + HISTOGRAM_RANGE * + FLOAT_RANGE + + FLOAT_MIN; break; } } // Maximums - config.input_max[i] = 0xffff; - for(int j = HISTOGRAM_RANGE - 1; j >= 0; j--) + config.input_max[i] = 1.0; + for(int j = (int)(HISTOGRAM_RANGE * (1 - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN)) - 1; + j >= (int)(HISTOGRAM_RANGE * (0 - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN)); + j--) { if(accum[j] > threshold) { - config.input_max[i] = j; + config.input_max[i] = (float)j / + HISTOGRAM_RANGE * + FLOAT_RANGE + + FLOAT_MIN; break; } } @@ -1373,7 +1527,6 @@ void HistogramMain::calculate_automatic(VFrame *data) int HistogramMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) { -TRACE("HistogramMain::process_realtime"); int need_reconfigure = load_configuration(); @@ -1389,7 +1542,6 @@ TRACE("HistogramMain::process_realtime"); { output_ptr->copy_from(input_ptr); } -//printf("HistogramMain::process_realtime 1\n"); // Generate tables here. The same table is used by many packages to render // each horizontal stripe. Need to cover the entire output range in each @@ -1411,22 +1563,21 @@ TRACE("HistogramMain::process_realtime"); // Convert 16 bit lookup table to 8 bits - switch(input->get_color_model()) - { - case BC_RGB888: - case BC_RGBA8888: - for(int i = 0; i < 0x100; i++) - { - int subscript = (i << 8) | i; - lookup[0][i] = lookup[0][subscript]; - lookup[1][i] = lookup[1][subscript]; - lookup[2][i] = lookup[2][subscript]; - lookup[3][i] = lookup[3][subscript]; - } - break; - } +// switch(input->get_color_model()) +// { +// case BC_RGB888: +// case BC_RGBA8888: +// for(int i = 0; i < 0x100; i++) +// { +// int subscript = (i << 8) | i; +// lookup[0][i] = lookup[0][subscript]; +// lookup[1][i] = lookup[1][subscript]; +// lookup[2][i] = lookup[2][subscript]; +// lookup[3][i] = lookup[3][subscript]; +// } +// break; +// } } -//printf("HistogramMain::process_realtime 1\n"); @@ -1434,10 +1585,6 @@ TRACE("HistogramMain::process_realtime"); // Apply histogram engine->process_packages(HistogramEngine::APPLY, input); -//printf("HistogramMain::process_realtime 100\n"); - - -UNTRACE return 0; } @@ -1487,12 +1634,21 @@ void HistogramUnit::process_package(LoadPackage *package) { #define HISTOGRAM_TAIL(components) \ +/* v = (r * 76 + g * 150 + b * 29) >> 8; */ \ v = MAX(r, g); \ v = MAX(v, b); \ + r += -HISTOGRAM_MIN * 0xffff / 100; \ + g += -HISTOGRAM_MIN * 0xffff / 100; \ + b += -HISTOGRAM_MIN * 0xffff / 100; \ + v += -HISTOGRAM_MIN * 0xffff / 100; \ + CLAMP(r, 0, HISTOGRAM_RANGE); \ + CLAMP(g, 0, HISTOGRAM_RANGE); \ + CLAMP(b, 0, HISTOGRAM_RANGE); \ + CLAMP(v, 0, HISTOGRAM_RANGE); \ accum_r[r]++; \ accum_g[g]++; \ accum_b[b]++; \ - if(components == 4) accum_a[row[3]]++; \ +/* if(components == 4) accum_a[row[3]]++; */ \ accum_v[v]++; \ row += components; \ } \ @@ -1521,6 +1677,13 @@ void HistogramUnit::process_package(LoadPackage *package) b = (row[2] << 8) | row[2]; HISTOGRAM_TAIL(3) break; + case BC_RGB_FLOAT: + HISTOGRAM_HEAD(float) + r = (int)(row[0] * 0xffff); + g = (int)(row[1] * 0xffff); + b = (int)(row[2] * 0xffff); + HISTOGRAM_TAIL(3) + break; case BC_YUV888: HISTOGRAM_HEAD(unsigned char) y = (row[0] << 8) | row[0]; @@ -1536,6 +1699,13 @@ void HistogramUnit::process_package(LoadPackage *package) b = (row[2] << 8) | row[2]; HISTOGRAM_TAIL(4) break; + case BC_RGBA_FLOAT: + HISTOGRAM_HEAD(float) + r = (int)(row[0] * 0xffff); + g = (int)(row[1] * 0xffff); + b = (int)(row[2] * 0xffff); + HISTOGRAM_TAIL(4) + break; case BC_YUVA8888: HISTOGRAM_HEAD(unsigned char) y = (row[0] << 8) | row[0]; @@ -1592,7 +1762,6 @@ void HistogramUnit::process_package(LoadPackage *package) row[0] = lookup_r[row[0]]; \ row[1] = lookup_g[row[1]]; \ row[2] = lookup_b[row[2]]; \ - if(components == 4) row[3] = lookup_a[row[3]]; \ row += components; \ } \ } \ @@ -1611,14 +1780,12 @@ void HistogramUnit::process_package(LoadPackage *package) y = (row[0] << 8) | row[0]; \ u = (row[1] << 8) | row[1]; \ v = (row[2] << 8) | row[2]; \ - if(components == 4) a = (row[3] << 8) | row[3]; \ } \ else \ { \ y = row[0]; \ u = row[1]; \ v = row[2]; \ - if(components == 4) a = row[3]; \ } \ \ plugin->yuv.yuv_to_rgb_16(r, g, b, y, u, v); \ @@ -1627,7 +1794,6 @@ void HistogramUnit::process_package(LoadPackage *package) r = lookup_r[r]; \ g = lookup_g[g]; \ b = lookup_b[b]; \ - if(components == 4) a = lookup_a[a]; \ \ /* Convert to 16 bit YUV */ \ plugin->yuv.rgb_to_yuv_16(r, g, b, y, u, v); \ @@ -1637,21 +1803,41 @@ void HistogramUnit::process_package(LoadPackage *package) row[0] = y >> 8; \ row[1] = u >> 8; \ row[2] = v >> 8; \ - if(components == 4) row[3] = a >> 8; \ } \ else \ { \ row[0] = y; \ row[1] = u; \ row[2] = v; \ - if(components == 4) row[3] = a; \ } \ row += components; \ } \ } \ } - +#define PROCESS_FLOAT(components) \ +{ \ + for(int i = pkg->start; i < pkg->end; i++) \ + { \ + float *row = (float*)input->get_rows()[i]; \ + for(int j = 0; j < w; j++) \ + { \ + float r = row[0]; \ + float g = row[1]; \ + float b = row[2]; \ + \ + r = plugin->calculate_transfer(r, HISTOGRAM_RED); \ + g = plugin->calculate_transfer(g, HISTOGRAM_GREEN); \ + b = plugin->calculate_transfer(b, HISTOGRAM_BLUE); \ + \ + row[0] = r; \ + row[1] = g; \ + row[2] = b; \ + \ + row += components; \ + } \ + } \ +} VFrame *input = plugin->input; @@ -1668,9 +1854,15 @@ void HistogramUnit::process_package(LoadPackage *package) case BC_RGB888: PROCESS(unsigned char, 3) break; + case BC_RGB_FLOAT: + PROCESS_FLOAT(3); + break; case BC_RGBA8888: PROCESS(unsigned char, 4) break; + case BC_RGBA_FLOAT: + PROCESS_FLOAT(4); + break; case BC_RGB161616: PROCESS(uint16_t, 3) break; @@ -1691,93 +1883,45 @@ void HistogramUnit::process_package(LoadPackage *package) break; } } + else if(server->operation == HistogramEngine::TABULATE) { -// Do conversion in 16 bit YUVA - int min_output_r = plugin->config.output_min[0]; - int min_output_g = plugin->config.output_min[1]; - int min_output_b = plugin->config.output_min[2]; - int min_output_a = plugin->config.output_min[3]; - int min_output_v = plugin->config.output_min[4]; - int max_output_r = plugin->config.output_max[0]; - int max_output_g = plugin->config.output_max[1]; - int max_output_b = plugin->config.output_max[2]; - int max_output_a = plugin->config.output_max[3]; - int max_output_v = plugin->config.output_max[4]; int colormodel = plugin->input->get_color_model(); - - for(int i = pkg->start; i < pkg->end; i++) +// Float uses direct calculation + if(colormodel != BC_RGB_FLOAT && + colormodel != BC_RGBA_FLOAT) { -// Expand input - float r = plugin->calculate_curve((float)i, HISTOGRAM_RED); - float g = plugin->calculate_curve((float)i, HISTOGRAM_GREEN); - float b = plugin->calculate_curve((float)i, HISTOGRAM_BLUE); - float a = plugin->calculate_curve((float)i, HISTOGRAM_ALPHA); - int y, u, v; -// Expand value - r = plugin->calculate_curve((float)r, HISTOGRAM_VALUE); - g = plugin->calculate_curve((float)g, HISTOGRAM_VALUE); - b = plugin->calculate_curve((float)b, HISTOGRAM_VALUE); -// r = i; -// g = i; -// b = i; - -// Shrink output - r = (float)min_output_r + - r * - (max_output_r - min_output_r) / - (HISTOGRAM_RANGE - 1); - g = min_output_g + - g * - (max_output_g - min_output_g) / - (HISTOGRAM_RANGE - 1); - b = min_output_b + - b * - (max_output_b - min_output_b) / - (HISTOGRAM_RANGE - 1); - a = min_output_a + - a * - (max_output_a - min_output_a) / - (HISTOGRAM_RANGE - 1); -// Shrink value -//printf(" 1 %d -> ", r); - r = min_output_v + - r * - (max_output_v - min_output_v) / - (HISTOGRAM_RANGE - 1); -//printf("%d\n", r); - g = min_output_v + - g * - (max_output_v - min_output_v) / - (HISTOGRAM_RANGE - 1); - b = min_output_v + - b * - (max_output_v - min_output_v) / - (HISTOGRAM_RANGE - 1); - a = min_output_v + - a * - (max_output_v - min_output_v) / - (HISTOGRAM_RANGE - 1); - - + for(int i = pkg->start; i < pkg->end; i++) + { +// Fix input for legal integer range + float input = (float)i / server->total_size; +// Expand input + float r = plugin->calculate_transfer(input, HISTOGRAM_RED); + float g = plugin->calculate_transfer(input, HISTOGRAM_GREEN); + float b = plugin->calculate_transfer(input, HISTOGRAM_BLUE); // Convert to desired colormodel - switch(colormodel) - { - case BC_RGB888: - case BC_RGBA8888: - plugin->lookup[0][i] = ((int)r) >> 8; - plugin->lookup[1][i] = ((int)g) >> 8; - plugin->lookup[2][i] = ((int)b) >> 8; - plugin->lookup[3][i] = ((int)a) >> 8; - break; - default: + switch(colormodel) + { + case BC_RGB888: + case BC_RGBA8888: + plugin->lookup[0][i] = (int)(r * 0xff); + plugin->lookup[1][i] = (int)(g * 0xff); + plugin->lookup[2][i] = (int)(b * 0xff); + CLAMP(plugin->lookup[0][i], 0, 0xff); + CLAMP(plugin->lookup[1][i], 0, 0xff); + CLAMP(plugin->lookup[2][i], 0, 0xff); + break; + default: // Can't look up yuv. - plugin->lookup[0][i] = (int)r; - plugin->lookup[1][i] = (int)g; - plugin->lookup[2][i] = (int)b; - plugin->lookup[3][i] = (int)a; - break; + plugin->lookup[0][i] = (int)(r * 0xffff); + plugin->lookup[1][i] = (int)(g * 0xffff); + plugin->lookup[2][i] = (int)(b * 0xffff); + CLAMP(plugin->lookup[0][i], 0, 0xffff); + CLAMP(plugin->lookup[1][i], 0, 0xffff); + CLAMP(plugin->lookup[2][i], 0, 0xffff); + break; + } } } } @@ -1798,23 +1942,32 @@ HistogramEngine::HistogramEngine(HistogramMain *plugin, void HistogramEngine::init_packages() { - int total_size; - switch(operation) { case HISTOGRAM: total_size = data->get_h(); break; case TABULATE: - total_size = HISTOGRAM_RANGE; + { + int colormodel = plugin->input->get_color_model(); +// Tabulation only works for integer so we only do integer ranges + if(colormodel == BC_RGB888 | + colormodel == BC_RGBA8888) + total_size = 0x100; + else + total_size = 0x10000; break; + } case APPLY: total_size = data->get_h(); break; } + + int package_size = (int)((float)total_size / get_total_packages() + 1); int start = 0; + for(int i = 0; i < get_total_packages(); i++) { HistogramPackage *package = (HistogramPackage*)get_package(i); @@ -1832,6 +1985,7 @@ void HistogramEngine::init_packages() for(int i = 0; i < 5; i++) bzero(unit->accum[i], sizeof(int64_t) * HISTOGRAM_RANGE); } + } LoadClient* HistogramEngine::new_client() diff --git a/hvirtual/plugins/holo/holo.C b/hvirtual/plugins/holo/holo.C index d31e38bd..ca7216dd 100644 --- a/hvirtual/plugins/holo/holo.C +++ b/hvirtual/plugins/holo/holo.C @@ -1,25 +1,19 @@ #include "clip.h" #include "colormodels.h" +#include "effecttv.h" #include "filexml.h" -#include "picon_png.h" #include "holo.h" #include "holowindow.h" -#include "effecttv.h" +#include "language.h" +#include "picon_png.h" +#include "plugincolors.h" #include #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - -PluginClient* new_plugin(PluginServer *server) -{ - return new HoloMain(server); -} +REGISTER_PLUGIN(HoloMain) @@ -46,6 +40,7 @@ HoloMain::HoloMain(PluginServer *server) effecttv = 0; bgimage = 0; do_reconfigure = 1; + yuv = new YUV; PLUGIN_CONSTRUCTOR_MACRO } @@ -62,6 +57,7 @@ HoloMain::~HoloMain() if(bgimage) delete bgimage; + delete yuv; } char* HoloMain::plugin_title() { return N_("HolographicTV"); } @@ -117,10 +113,27 @@ void HoloMain::reconfigure() \ for(int j = 0; j < w; j++) \ { \ - for(int k = 0; k < components; k++) \ + for(int k = 0; k < 3; k++) \ + { \ + if(sizeof(type) == 4) \ + { \ + int in_temp = (int)(*input_row * 0xffff); \ + int out_temp = (int)(*output_row * 0xffff); \ + int temp = (in_temp & out_temp) + \ + ((in_temp ^ out_temp) >> 1); \ + *output_row = (type)temp / 0xffff; \ + } \ + else \ + { \ + *output_row = ((uint16_t)*input_row & (uint16_t)*output_row) + \ + (((uint16_t)*input_row ^ (uint16_t)*output_row) >> 1); \ + } \ + output_row++; \ + input_row++; \ + } \ + \ + if(components == 4) \ { \ - *output_row = (*input_row & *output_row) + \ - ((*input_row ^ *output_row) >> 1); \ output_row++; \ input_row++; \ } \ @@ -138,6 +151,12 @@ void HoloMain::add_frames(VFrame *output, VFrame *input) case BC_YUV888: ADD_FRAMES(uint8_t, 3); break; + case BC_RGB_FLOAT: + ADD_FRAMES(float, 3); + break; + case BC_RGBA_FLOAT: + ADD_FRAMES(float, 4); + break; case BC_RGBA8888: case BC_YUVA8888: ADD_FRAMES(uint8_t, 4); @@ -158,6 +177,10 @@ void HoloMain::set_background() /* * grab 4 frames and composite them to get a quality background image */ +/** + * For Cinelerra, we make every frame a holograph and expect the user to + * provide a matte. + **/ total = 0; switch(total) @@ -201,7 +224,6 @@ total = 0; int HoloMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) { -//printf("HoloMain::process_realtime 1\n"); this->input_ptr = input_ptr; this->output_ptr = output_ptr; @@ -210,7 +232,6 @@ int HoloMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) load_configuration(); -//printf("HoloMain::process_realtime 1\n"); if(do_reconfigure) @@ -234,17 +255,13 @@ int HoloMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) reconfigure(); } -//printf("HoloMain::process_realtime 1\n"); set_background(); -//printf("HoloMain::process_realtime 1\n"); holo_server->process_packages(); -//printf("HoloMain::process_realtime 1\n"); total++; if(total >= config.recycle * project_frame_rate) total = 0; -//printf("HoloMain::process_realtime 2\n"); return 0; } @@ -277,7 +294,6 @@ void HoloMain::raise_window() HoloServer::HoloServer(HoloMain *plugin, int total_clients, int total_packages) : LoadServer(total_clients, total_packages) -// : LoadServer(1, 1) { this->plugin = plugin; } @@ -346,25 +362,58 @@ void HoloClient::process_package(LoadPackage *package) input_rows++; - -#define STORE_PIXEL(type, components, dest, src) \ +// Convert discrete channels to a single 24 bit number +#define STORE_PIXEL(type, components, dest, src, is_yuv) \ +if(sizeof(type) == 4) \ +{ \ + int r = (int)(src[0] * 0xff); \ + int g = (int)(src[1] * 0xff); \ + int b = (int)(src[2] * 0xff); \ + CLAMP(r, 0, 0xff); \ + CLAMP(g, 0, 0xff); \ + CLAMP(b, 0, 0xff); \ + dest = (r << 16) | (g << 8) | b; \ +} \ +else \ if(sizeof(type) == 2) \ { \ - dest = (src[0] << 8) | \ - (src[1]) | \ - (src[2]) >> 8; \ + if(is_yuv) \ + { \ + int r = (int)src[0] >> 8; \ + int g = (int)src[1] >> 8; \ + int b = (int)src[2] >> 8; \ + plugin->yuv->yuv_to_rgb_8(r, g, b); \ + dest = (r << 16) | (g << 8) | b; \ + } \ + else \ + { \ + dest = (((uint32_t)src[0] << 8) & 0xff0000) | \ + ((uint32_t)src[1] & 0xff00) | \ + ((uint32_t)src[2]) >> 8; \ + } \ } \ else \ { \ - dest = (src[0] << 16) | \ - (src[1] << 8) | \ - src[2]; \ + if(is_yuv) \ + { \ + int r = (int)src[0]; \ + int g = (int)src[1]; \ + int b = (int)src[2]; \ + plugin->yuv->yuv_to_rgb_8(r, g, b); \ + dest = (r << 16) | (g << 8) | b; \ + } \ + else \ + { \ + dest = ((uint32_t)src[0] << 16) | \ + ((uint32_t)src[1] << 8) | \ + (uint32_t)src[2]; \ + } \ } -#define HOLO_CORE(type, components) \ +#define HOLO_CORE(type, components, is_yuv) \ for(y = 1; y < height - 1; y++) \ { \ type *src = (type*)input_rows[y]; \ @@ -379,7 +428,7 @@ else \ { \ if(*diff) \ { \ - STORE_PIXEL(type, components, s, src); \ + STORE_PIXEL(type, components, s, src, is_yuv); \ \ t = (s & 0xff) + \ ((s & 0xff00) >> 7) + \ @@ -397,7 +446,7 @@ else \ if(r < 20) r = 20; \ if(g < 20) g = 20; \ \ - STORE_PIXEL(type, components, s, bg); \ + STORE_PIXEL(type, components, s, bg, is_yuv); \ \ r += (s & 0xff0000) >> 17; \ g += (s & 0xff00) >> 9; \ @@ -407,17 +456,32 @@ else \ if(g > 255) g = 255; \ if(b > 255) b = 255; \ \ - dest[0] = r; \ - dest[1] = g; \ - dest[2] = b; \ - if(components == 4) dest[3] = src[3]; \ + if(is_yuv) plugin->yuv->rgb_to_yuv_8(r, g, b); \ + if(sizeof(type) == 4) \ + { \ + dest[0] = (type)r / 0xff; \ + dest[1] = (type)g / 0xff; \ + dest[2] = (type)b / 0xff; \ + } \ + else \ + if(sizeof(type) == 2) \ + { \ + dest[0] = (r << 8) | r; \ + dest[1] = (g << 8) | g; \ + dest[2] = (b << 8) | b; \ + } \ + else \ + { \ + dest[0] = r; \ + dest[1] = g; \ + dest[2] = b; \ + } \ } \ else \ { \ dest[0] = bg[0]; \ dest[1] = bg[1]; \ dest[2] = bg[2]; \ - if(components == 4) dest[3] = bg[3]; \ } \ \ diff++; \ @@ -432,7 +496,7 @@ else \ { \ if(*diff) \ { \ - STORE_PIXEL(type, components, s, src); \ + STORE_PIXEL(type, components, s, src, is_yuv); \ \ \ t = (s & 0xff) + ((s & 0xff00) >> 6) + ((s & 0xff0000) >> 16); \ @@ -449,7 +513,7 @@ else \ if(r < 0) r = 0; \ if(g < 0) g = 0; \ \ - STORE_PIXEL(type, components, s, bg); \ + STORE_PIXEL(type, components, s, bg, is_yuv); \ \ r += ((s & 0xff0000) >> 17) + 10; \ g += ((s & 0xff00) >> 9) + 10; \ @@ -459,17 +523,32 @@ else \ if(g > 255) g = 255; \ if(b > 255) b = 255; \ \ - dest[0] = r; \ - dest[1] = g; \ - dest[2] = b; \ - if(components == 4) dest[3] = src[3]; \ + if(is_yuv) plugin->yuv->rgb_to_yuv_8(r, g, b); \ + if(sizeof(type) == 4) \ + { \ + dest[0] = (type)r / 0xff; \ + dest[1] = (type)g / 0xff; \ + dest[2] = (type)b / 0xff; \ + } \ + else \ + if(sizeof(type) == 2) \ + { \ + dest[0] = (r << 8) | r; \ + dest[1] = (g << 8) | g; \ + dest[2] = (b << 8) | b; \ + } \ + else \ + { \ + dest[0] = r; \ + dest[1] = g; \ + dest[2] = b; \ + } \ } \ else \ { \ dest[0] = bg[0]; \ dest[1] = bg[1]; \ dest[2] = bg[2]; \ - if(components == 4) dest[3] = bg[3]; \ } \ \ diff++; \ @@ -486,20 +565,34 @@ else \ switch(plugin->input_ptr->get_color_model()) { case BC_RGB888: + HOLO_CORE(uint8_t, 3, 0); + break; + case BC_RGB_FLOAT: + HOLO_CORE(float, 3, 0); + break; case BC_YUV888: - HOLO_CORE(uint8_t, 3); + HOLO_CORE(uint8_t, 3, 1); + break; + case BC_RGBA_FLOAT: + HOLO_CORE(float, 4, 0); break; case BC_RGBA8888: + HOLO_CORE(uint8_t, 4, 0); + break; case BC_YUVA8888: - HOLO_CORE(uint8_t, 4); + HOLO_CORE(uint8_t, 4, 1); break; case BC_RGB161616: + HOLO_CORE(uint16_t, 3, 0); + break; case BC_YUV161616: - HOLO_CORE(uint16_t, 3); + HOLO_CORE(uint16_t, 3, 1); break; case BC_RGBA16161616: + HOLO_CORE(uint16_t, 4, 0); + break; case BC_YUVA16161616: - HOLO_CORE(uint16_t, 4); + HOLO_CORE(uint16_t, 4, 1); break; } diff --git a/hvirtual/plugins/holo/holo.h b/hvirtual/plugins/holo/holo.h new file mode 100644 index 00000000..742dc1ae --- /dev/null +++ b/hvirtual/plugins/holo/holo.h @@ -0,0 +1,110 @@ +#ifndef HOLO_H +#define HOLO_H + +class HoloMain; +class HoloEngine; + +#include "defaults.h" +#include "effecttv.h" +#include "holowindow.h" +#include "loadbalance.h" +#include "mutex.h" +#include "plugincolors.inc" +#include "pluginvclient.h" + +#include + + +class HoloConfig +{ +public: + HoloConfig(); + + + int threshold; + double recycle; // Number of seconds between recycles +}; + +class HoloPackage : public LoadPackage +{ +public: + HoloPackage(); + + int row1, row2; +}; + +class HoloServer : public LoadServer +{ +public: + HoloServer(HoloMain *plugin, int total_clients, int total_packages); + + LoadClient* new_client(); + LoadPackage* new_package(); + void init_packages(); + HoloMain *plugin; +}; + +class HoloClient : public LoadClient +{ +public: + HoloClient(HoloServer *server); + + void process_package(LoadPackage *package); + + HoloMain *plugin; + int phase; +}; + + +class HoloMain : public PluginVClient +{ +public: + HoloMain(PluginServer *server); + ~HoloMain(); + +// required for all realtime plugins + int process_realtime(VFrame *input_ptr, VFrame *output_ptr); + int is_realtime(); + char* plugin_title(); + int show_gui(); + void raise_window(); + int set_string(); + void load_configuration(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + + int load_defaults(); + int save_defaults(); + VFrame* new_picon(); + void reconfigure(); + + + void add_frames(VFrame *output, VFrame *input); + void set_background(); + +// a thread for the GUI + HoloThread *thread; + HoloServer *holo_server; + HoloConfig config; + + Defaults *defaults; + VFrame *input_ptr, *output_ptr; + int do_reconfigure; + EffectTV *effecttv; + + unsigned int noisepattern[256]; + VFrame *bgimage, *tmp; + YUV *yuv; + int total; +}; + + + + + + + + + + +#endif diff --git a/hvirtual/plugins/holo/holowindow.C b/hvirtual/plugins/holo/holowindow.C index 30e7be3e..425d50af 100644 --- a/hvirtual/plugins/holo/holowindow.C +++ b/hvirtual/plugins/holo/holowindow.C @@ -1,10 +1,7 @@ #include "bcdisplayinfo.h" +#include "language.h" #include "holowindow.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) PLUGIN_THREAD_OBJECT(HoloMain, HoloThread, HoloWindow) @@ -44,13 +41,7 @@ int HoloWindow::create_objects() return 0; } -int HoloWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} - +WINDOW_CLOSE_EVENT(HoloWindow) diff --git a/hvirtual/plugins/holo/holowindow.h b/hvirtual/plugins/holo/holowindow.h index 59466e5e..9d2f11b5 100644 --- a/hvirtual/plugins/holo/holowindow.h +++ b/hvirtual/plugins/holo/holowindow.h @@ -7,8 +7,9 @@ class HoloThread; class HoloWindow; #include "filexml.h" -#include "mutex.h" #include "holo.h" +#include "mutex.h" +#include "pluginclient.h" PLUGIN_THREAD_HEADER(HoloMain, HoloThread, HoloWindow) diff --git a/hvirtual/plugins/huesaturation/huesaturation.C b/hvirtual/plugins/huesaturation/huesaturation.C index 8c129b81..17730710 100644 --- a/hvirtual/plugins/huesaturation/huesaturation.C +++ b/hvirtual/plugins/huesaturation/huesaturation.C @@ -3,6 +3,7 @@ #include "defaults.h" #include "filexml.h" #include "guicast.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "../colors/plugincolors.h" @@ -12,10 +13,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) class HueEffect; @@ -300,11 +297,11 @@ void HueWindow::create_objects() } -int HueWindow::close_event() -{ - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(HueWindow) + + + + @@ -368,8 +365,8 @@ HueUnit::HueUnit(HueEffect *plugin, HueEngine *server) #define HUESATURATION(type, max, components, use_yuv) \ { \ float h_offset = plugin->config.hue; \ - float s_offset = ((float)plugin->config.saturation + -MINSATURATION) / MAXSATURATION; \ - float v_offset = ((float)plugin->config.value + -MINVALUE) / MAXVALUE; \ + float s_offset = ((float)plugin->config.saturation - MINSATURATION) / MAXSATURATION; \ + float v_offset = ((float)plugin->config.value - MINVALUE) / MAXVALUE; \ for(int i = pkg->row1; i < pkg->row2; i++) \ { \ type* in_row = (type*)plugin->input->get_rows()[i]; \ @@ -384,9 +381,9 @@ HueUnit::HueUnit(HueEffect *plugin, HueEngine *server) \ if(use_yuv) \ { \ - y = in_row[0]; \ - u = in_row[1]; \ - v = in_row[2]; \ + y = (int)in_row[0]; \ + u = (int)in_row[1]; \ + v = (int)in_row[2]; \ if(max == 0xffff) \ yuv.yuv_to_rgb_16(r_i, g_i, b_i, y, u, v); \ else \ @@ -412,11 +409,14 @@ HueUnit::HueUnit(HueEffect *plugin, HueEngine *server) va *= v_offset; \ \ if(h >= 360) h -= 360; \ - if(s > 1) s = 1; \ - if(va > 1) va = 1; \ if(h < 0) h += 360; \ - if(s < 0) s = 0; \ - if(va < 0) va = 0; \ + if(sizeof(type) < 4) \ + { \ + if(s > 1) s = 1; \ + if(va > 1) va = 1; \ + if(s < 0) s = 0; \ + if(va < 0) va = 0; \ + } \ \ if(use_yuv) \ { \ @@ -428,17 +428,23 @@ HueUnit::HueUnit(HueEffect *plugin, HueEngine *server) else \ { \ HSV::hsv_to_rgb(r, g, b, h, s, va); \ - r *= max; \ - g *= max; \ - b *= max; \ - out_row[0] = (int)CLIP(r, 0, max); \ - out_row[1] = (int)CLIP(g, 0, max); \ - out_row[2] = (int)CLIP(b, 0, max); \ + if(sizeof(type) < 4) \ + { \ + r *= max; \ + g *= max; \ + b *= max; \ + out_row[0] = (type)CLIP(r, 0, max); \ + out_row[1] = (type)CLIP(g, 0, max); \ + out_row[2] = (type)CLIP(b, 0, max); \ + } \ + else \ + { \ + out_row[0] = (type)r; \ + out_row[1] = (type)g; \ + out_row[2] = (type)b; \ + } \ } \ \ - \ - if(components == 4) \ - out_row[3] = in_row[3]; \ in_row += components; \ out_row += components; \ } \ @@ -457,6 +463,10 @@ void HueUnit::process_package(LoadPackage *package) HUESATURATION(unsigned char, 0xff, 3, 0) break; + case BC_RGB_FLOAT: + HUESATURATION(float, 1, 3, 0) + break; + case BC_YUV888: HUESATURATION(unsigned char, 0xff, 3, 1) break; @@ -469,6 +479,10 @@ void HueUnit::process_package(LoadPackage *package) HUESATURATION(uint16_t, 0xffff, 3, 1) break; + case BC_RGBA_FLOAT: + HUESATURATION(float, 1, 4, 0) + break; + case BC_RGBA8888: HUESATURATION(unsigned char, 0xff, 4, 0) break; diff --git a/hvirtual/plugins/invertvideo/invert.C b/hvirtual/plugins/invertvideo/invert.C index b380fbfc..8b7ab5f4 100644 --- a/hvirtual/plugins/invertvideo/invert.C +++ b/hvirtual/plugins/invertvideo/invert.C @@ -3,6 +3,7 @@ #include "defaults.h" #include "filexml.h" #include "guicast.h" +#include "language.h" #include "picon_png.h" #include "../colors/plugincolors.h" #include "pluginvclient.h" @@ -11,10 +12,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) class InvertVideoEffect; @@ -179,12 +176,7 @@ void InvertVideoWindow::create_objects() flush(); } -int InvertVideoWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(InvertVideoWindow) @@ -319,10 +311,16 @@ int InvertVideoEffect::process_realtime(VFrame *input, VFrame *output) switch(input->get_color_model()) { + case BC_RGB_FLOAT: + INVERT_MACRO(float, 3, 1.0) + break; case BC_RGB888: case BC_YUV888: INVERT_MACRO(unsigned char, 3, 0xff) break; + case BC_RGBA_FLOAT: + INVERT_MACRO(float, 4, 1.0) + break; case BC_RGBA8888: case BC_YUVA8888: INVERT_MACRO(unsigned char, 4, 0xff) diff --git a/hvirtual/plugins/invertvideo/invertwindow.C b/hvirtual/plugins/invertvideo/invertwindow.C index c4b2241d..f35bd617 100644 --- a/hvirtual/plugins/invertvideo/invertwindow.C +++ b/hvirtual/plugins/invertvideo/invertwindow.C @@ -1,31 +1,5 @@ #include "invertwindow.h" - -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - - -InvertThread::InvertThread(InvertMain *client) - : Thread() -{ - this->client = client; - synchronous = 1; // make thread wait for join - gui_started.lock(); -} - -InvertThread::~InvertThread() -{ -} - -void InvertThread::run() -{ - window = new InvertWindow(client); - window->create_objects(); - gui_started.unlock(); - window->run_window(); - delete window; -} +#include "language.h" @@ -49,11 +23,7 @@ int InvertWindow::create_objects() add_tool(invert = new InvertToggle(client, &(client->invert), x, y)); } -int InvertWindow::close_event() -{ - hide_window(); - client->send_hide_gui(); -} +WINDOW_CLOSE_EVENT(InvertWindow) InvertToggle::InvertToggle(InvertMain *client, int *output, int x, int y) : BC_CheckBox(x, y, 16, 16, *output) diff --git a/hvirtual/plugins/irissquare/irissquare.C b/hvirtual/plugins/irissquare/irissquare.C index c5f62ec4..0b97e0dc 100644 --- a/hvirtual/plugins/irissquare/irissquare.C +++ b/hvirtual/plugins/irissquare/irissquare.C @@ -2,6 +2,7 @@ #include "defaults.h" #include "edl.inc" #include "filexml.h" +#include "language.h" #include "overlayframe.h" #include "picon_png.h" #include "vframe.h" @@ -11,11 +12,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - REGISTER_PLUGIN(IrisSquareMain) @@ -314,10 +310,16 @@ int IrisSquareMain::process_realtime(VFrame *incoming, VFrame *outgoing) switch(incoming->get_color_model()) { + case BC_RGB_FLOAT: + IRISSQUARE(float, 3); + break; case BC_RGB888: case BC_YUV888: IRISSQUARE(unsigned char, 3) break; + case BC_RGBA_FLOAT: + IRISSQUARE(float, 4); + break; case BC_RGBA8888: case BC_YUVA8888: IRISSQUARE(unsigned char, 4) diff --git a/hvirtual/plugins/ivtc/ivtc.C b/hvirtual/plugins/ivtc/ivtc.C index ff21bfb4..8f313b15 100644 --- a/hvirtual/plugins/ivtc/ivtc.C +++ b/hvirtual/plugins/ivtc/ivtc.C @@ -336,191 +336,6 @@ int IVTCMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) -#define DEINTERLACE_AVG_MACRO(type, components) \ -{ \ - int w = input->get_w(); \ - int h = input->get_h(); \ - type **in_rows = (type**)input->get_rows(); \ - type **out_rows = (type**)output->get_rows(); \ - int max_h = h - 1; \ - \ - for(int i = 0; i < max_h; i += 2) \ - { \ - int in_number1 = dominance ? i - 1 : i + 0; \ - int in_number2 = dominance ? i + 1 : i + 2; \ - int out_number1 = dominance ? i - 1 : i; \ - int out_number2 = dominance ? i : i + 1; \ - in_number1 = MAX(in_number1, 0); \ - in_number2 = MIN(in_number2, max_h); \ - out_number1 = MAX(out_number1, 0); \ - out_number2 = MIN(out_number2, max_h); \ - \ - type *input_row1 = in_rows[in_number1]; \ - type *input_row2 = in_rows[in_number2]; \ - type *input_row3 = in_rows[out_number2]; \ - type *output_row1 = out_rows[out_number1]; \ - type *output_row2 = out_rows[out_number2]; \ - int64_t accum_r, accum_b, accum_g, accum_a; \ - \ -/* Assume the dominant rows are never compared */ \ -/* memcpy(output_row1, input_row1, w * components * sizeof(type)); */\ - for(int j = 0; j < w; j++) \ - { \ - accum_r = (*input_row1++) + (*input_row2++); \ - accum_g = (*input_row1++) + (*input_row2++); \ - accum_b = (*input_row1++) + (*input_row2++); \ - if(components == 4) \ - accum_a = (*input_row1++) + (*input_row2++); \ - accum_r >>= 1; \ - accum_g >>= 1; \ - accum_b >>= 1; \ - accum_a >>= 1; \ - \ - *output_row2++ = accum_r; \ - *output_row2++ = accum_g; \ - *output_row2++ = accum_b; \ - if(components == 4) \ - { \ - *output_row2++ = accum_a; \ - } \ - } \ - } \ -} - - -void IVTCMain::deinterlace_avg(VFrame *output, - VFrame *input, - int dominance) -{ - switch(input->get_color_model()) - { - case BC_RGB888: - case BC_YUV888: - DEINTERLACE_AVG_MACRO(unsigned char, 3); - break; - case BC_RGBA8888: - case BC_YUVA8888: - DEINTERLACE_AVG_MACRO(unsigned char, 4); - break; - case BC_RGB161616: - case BC_YUV161616: - DEINTERLACE_AVG_MACRO(uint16_t, 3); - break; - case BC_RGBA16161616: - case BC_YUVA16161616: - DEINTERLACE_AVG_MACRO(uint16_t, 4); - break; - } -} - - -#define COMPARE(type, components, is_yuv) \ -{ \ - int w = current_avg->get_w(); \ - int h = current_avg->get_h(); \ - type **in_rows = (type**)current_avg->get_rows(); \ - type **curr_rows = (type**)current_orig->get_rows(); \ - type **prev_rows = (type**)previous->get_rows(); \ -/* Components to skip for YUV */ \ - int skip = components - 1; \ - \ - for(int i = 0; i < h; i++) \ - { \ - type *in_row = in_rows[i]; \ - type *out_row; \ - \ - switch(field) \ - { \ - case 0: \ -/* Compare with previous even field */ \ - if(!(i % 2)) \ - out_row = prev_rows[i]; \ - else \ -/* Compare with current odd field */ \ -/* Assume curr_rows is the averaged in_rows with odd dominance and skip. */ \ - out_row = 0; \ - break; \ - case 1: \ -/* Compare with current even field */ \ -/* Assume curr_rows is the averaged in_rows with odd dominance and skip. */ \ - if(!(i % 2)) \ - out_row = 0; \ - else \ -/* Compare with previous odd field */ \ - out_row = prev_rows[i]; \ - break; \ - case 2: \ -/* Compare with current both fields */ \ - out_row = curr_rows[i]; \ - break; \ - } \ - \ - if(out_row) \ - { \ - if(is_yuv) \ - { \ -/* Compare the row luminance */ \ - for(int j = 0; j < w; j++) \ - { \ - int difference = labs(*in_row - *out_row); \ - result += difference; \ - in_row += skip; \ - out_row += skip; \ - } \ - } \ - else \ - { \ -/* Compare all channels */ \ - for(int j = 0; j < w; j++) \ - { \ - result += labs(in_row[0] - out_row[0]); \ - result += labs(in_row[1] - out_row[1]); \ - result += labs(in_row[2] - out_row[2]); \ - in_row += components; \ - out_row += components; \ - } \ - } \ - } \ - } \ -} - -int64_t IVTCMain::compare(VFrame *current_avg, - VFrame *current_orig, - VFrame *previous, - int field) -{ - int64_t result = 0; - - switch(current_avg->get_color_model()) - { - case BC_RGB888: - COMPARE(unsigned char, 3, 0); - break; - case BC_YUV888: - COMPARE(unsigned char, 3, 1); - break; - case BC_RGBA8888: - COMPARE(unsigned char, 4, 0); - break; - case BC_YUVA8888: - COMPARE(unsigned char, 4, 1); - break; - case BC_RGB161616: - COMPARE(uint16_t, 3, 0); - break; - case BC_YUV161616: - COMPARE(uint16_t, 3, 1); - break; - case BC_RGBA16161616: - COMPARE(uint16_t, 4, 0); - break; - case BC_YUVA16161616: - COMPARE(uint16_t, 4, 1); - break; - } - return result; -} - void IVTCMain::update_gui() { if(thread) @@ -551,18 +366,33 @@ void IVTCMain::update_gui() // labs returns different values on x86_64 causing our accumulators to explode -#ifdef __x86_64__ - #define ABS local_abs + +#ifdef __x86_64__ + static int local_abs(int value) { return (value < 0 ? -value : value); } +static float local_abs(float value) +{ + return (value < 0 ? -value : value); +} + #else -#define ABS labs +static int local_abs(int value) +{ + return abs(value); +} + +static float local_abs(float value) +{ + return fabsf(value); +} + #endif @@ -584,7 +414,7 @@ IVTCUnit::IVTCUnit(IVTCEngine *server, IVTCMain *plugin) this->plugin = plugin; } -#define IVTC_MACRO(type, components, is_yuv) \ +#define IVTC_MACRO(type, temp_type, components, is_yuv) \ { \ type **curr_rows = (type**)plugin->input->get_rows(); \ type **prev_rows = (type**)plugin->temp_frame[0]->get_rows(); \ @@ -605,12 +435,12 @@ IVTCUnit::IVTCUnit(IVTCEngine *server, IVTCMain *plugin) type *current_row = curr_rows[i]; \ type *prev_row = prev_rows[i]; \ \ - int64_t current_difference = 0; \ - int64_t prev_difference = 0; \ + temp_type current_difference = 0; \ + temp_type prev_difference = 0; \ for(int j = 0; j < w; j++) \ { \ /* Get pixel average */ \ - uint32_t average = ((uint32_t)*input_row1 + *input_row2) >> 1; \ + temp_type average = ((temp_type)*input_row1 + *input_row2) / 2; \ /* Compare row to current */ \ current_difference += ABS(average - *current_row); \ /* Compare row to previous */ \ @@ -619,10 +449,10 @@ IVTCUnit::IVTCUnit(IVTCEngine *server, IVTCMain *plugin) /* Do RGB channels */ \ if(!is_yuv) \ { \ - average = ((uint32_t)input_row1[1] + input_row2[1]) >> 1; \ + average = ((temp_type)input_row1[1] + input_row2[1]) / 2; \ current_difference += ABS(average - current_row[1]); \ prev_difference += ABS(average - prev_row[1]); \ - average = ((uint32_t)input_row1[2] + input_row2[2]) >> 1; \ + average = ((temp_type)input_row1[2] + input_row2[2]) / 2; \ current_difference += ABS(average - current_row[2]); \ prev_difference += ABS(average - prev_row[2]); \ } \ @@ -635,15 +465,31 @@ IVTCUnit::IVTCUnit(IVTCEngine *server, IVTCMain *plugin) } \ \ /* Store row differences in even or odd variables */ \ - if(i % 2) \ + if(sizeof(type) == 4) \ { \ - odd_vs_current += current_difference; \ - odd_vs_prev += prev_difference; \ + if(i % 2) \ + { \ + odd_vs_current += (int64_t)(current_difference * 0xffff); \ + odd_vs_prev += (int64_t)(prev_difference); \ + } \ + else \ + { \ + even_vs_current += (int64_t)(current_difference); \ + even_vs_prev += (int64_t)(prev_difference); \ + } \ } \ else \ { \ - even_vs_current += current_difference; \ - even_vs_prev += prev_difference; \ + if(i % 2) \ + { \ + odd_vs_current += (int64_t)current_difference; \ + odd_vs_prev += (int64_t)prev_difference; \ + } \ + else \ + { \ + even_vs_current += (int64_t)current_difference; \ + even_vs_prev += (int64_t)prev_difference; \ + } \ } \ } \ } @@ -664,29 +510,35 @@ void IVTCUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + IVTC_MACRO(float, float, 3, 0); + break; case BC_RGB888: - IVTC_MACRO(unsigned char, 3, 0); + IVTC_MACRO(unsigned char, int, 3, 0); break; case BC_YUV888: - IVTC_MACRO(unsigned char, 3, 1); + IVTC_MACRO(unsigned char, int, 3, 1); + break; + case BC_RGBA_FLOAT: + IVTC_MACRO(float, float, 4, 0); break; case BC_RGBA8888: - IVTC_MACRO(unsigned char, 4, 0); + IVTC_MACRO(unsigned char, int, 4, 0); break; case BC_YUVA8888: - IVTC_MACRO(unsigned char, 4, 1); + IVTC_MACRO(unsigned char, int, 4, 1); break; case BC_RGB161616: - IVTC_MACRO(uint16_t, 3, 0); + IVTC_MACRO(uint16_t, int, 3, 0); break; case BC_YUV161616: - IVTC_MACRO(uint16_t, 3, 1); + IVTC_MACRO(uint16_t, int, 3, 1); break; case BC_RGBA16161616: - IVTC_MACRO(uint16_t, 4, 0); + IVTC_MACRO(uint16_t, int, 4, 0); break; case BC_YUVA16161616: - IVTC_MACRO(uint16_t, 4, 1); + IVTC_MACRO(uint16_t, int, 4, 1); break; } diff --git a/hvirtual/plugins/linearblur/linearblur.C b/hvirtual/plugins/linearblur/linearblur.C index a9378283..34ed7799 100644 --- a/hvirtual/plugins/linearblur/linearblur.C +++ b/hvirtual/plugins/linearblur/linearblur.C @@ -7,15 +7,12 @@ #include "defaults.h" #include "filexml.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) class LinearBlurMain; @@ -118,7 +115,7 @@ public: int **scale_x_table; int table_entries; int need_reconfigure; - int *accum; + unsigned char *accum; }; class LinearBlurPackage : public LoadPackage @@ -282,12 +279,7 @@ int LinearBlurWindow::create_objects() return 0; } -int LinearBlurWindow::close_event() -{ -// Set result to 1 to indicate a plugin side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(LinearBlurWindow) @@ -413,9 +405,10 @@ int LinearBlurMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) if(!engine) engine = new LinearBlurEngine(this, get_project_smp() + 1, get_project_smp() + 1); - if(!accum) accum = new int[input_ptr->get_w() * + if(!accum) accum = new unsigned char[input_ptr->get_w() * input_ptr->get_h() * - cmodel_components(input_ptr->get_color_model())]; + cmodel_components(input_ptr->get_color_model()) * + MAX(sizeof(int), sizeof(float))]; this->input = input_ptr; this->output = output_ptr; @@ -500,10 +493,11 @@ int LinearBlurMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) need_reconfigure = 0; } - bzero(accum, input_ptr->get_w() * - input_ptr->get_h() * - cmodel_components(input_ptr->get_color_model()) * - sizeof(int)); + bzero(accum, + input_ptr->get_w() * + input_ptr->get_h() * + cmodel_components(input_ptr->get_color_model()) * + MAX(sizeof(int), sizeof(float))); engine->process_packages(); return 0; } @@ -632,12 +626,12 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, } -#define BLEND_LAYER(COMPONENTS, TYPE, MAX, DO_YUV) \ +#define BLEND_LAYER(COMPONENTS, TYPE, TEMP, MAX, DO_YUV) \ { \ const int chroma_offset = (DO_YUV ? ((MAX + 1) / 2) : 0); \ for(int j = pkg->y1; j < pkg->y2; j++) \ { \ - int *out_row = plugin->accum + COMPONENTS * w * j; \ + TEMP *out_row = (TEMP*)plugin->accum + COMPONENTS * w * j; \ int in_y = y_table[j]; \ \ /* Blend image */ \ @@ -659,8 +653,8 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, } \ else \ { \ - *out_row++ += (int)in_row[in_offset + 1]; \ - *out_row++ += (int)in_row[in_offset + 2]; \ + *out_row++ += in_row[in_offset + 1]; \ + *out_row++ += in_row[in_offset + 2]; \ } \ if(COMPONENTS == 4) \ *out_row++ += in_row[in_offset + 3]; \ @@ -700,14 +694,14 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, { \ for(int j = pkg->y1; j < pkg->y2; j++) \ { \ - int *in_row = plugin->accum + COMPONENTS * w * j; \ + TEMP *in_row = (TEMP*)plugin->accum + COMPONENTS * w * j; \ TYPE *in_backup = (TYPE*)plugin->input->get_rows()[j]; \ TYPE *out_row = (TYPE*)plugin->output->get_rows()[j]; \ for(int k = 0; k < w; k++) \ { \ if(do_r) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -720,7 +714,7 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, { \ if(do_g) \ { \ - *out_row++ = ((*in_row++ * fraction) >> 16); \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -731,7 +725,7 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, \ if(do_b) \ { \ - *out_row++ = ((*in_row++ * fraction) >> 16); \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -744,7 +738,7 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, { \ if(do_g) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -755,7 +749,7 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, \ if(do_b) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -769,7 +763,7 @@ LinearBlurUnit::LinearBlurUnit(LinearBlurEngine *server, { \ if(do_a) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -801,29 +795,35 @@ void LinearBlurUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + BLEND_LAYER(3, float, float, 1, 0) + break; case BC_RGB888: - BLEND_LAYER(3, uint8_t, 0xff, 0) + BLEND_LAYER(3, uint8_t, int, 0xff, 0) + break; + case BC_RGBA_FLOAT: + BLEND_LAYER(4, float, float, 1, 0) break; case BC_RGBA8888: - BLEND_LAYER(4, uint8_t, 0xff, 0) + BLEND_LAYER(4, uint8_t, int, 0xff, 0) break; case BC_RGB161616: - BLEND_LAYER(3, uint16_t, 0xffff, 0) + BLEND_LAYER(3, uint16_t, int, 0xffff, 0) break; case BC_RGBA16161616: - BLEND_LAYER(4, uint16_t, 0xffff, 0) + BLEND_LAYER(4, uint16_t, int, 0xffff, 0) break; case BC_YUV888: - BLEND_LAYER(3, uint8_t, 0xff, 1) + BLEND_LAYER(3, uint8_t, int, 0xff, 1) break; case BC_YUVA8888: - BLEND_LAYER(4, uint8_t, 0xff, 1) + BLEND_LAYER(4, uint8_t, int, 0xff, 1) break; case BC_YUV161616: - BLEND_LAYER(3, uint16_t, 0xffff, 1) + BLEND_LAYER(3, uint16_t, int, 0xffff, 1) break; case BC_YUVA16161616: - BLEND_LAYER(4, uint16_t, 0xffff, 1) + BLEND_LAYER(4, uint16_t, int, 0xffff, 1) break; } } diff --git a/hvirtual/plugins/oilpainting/oil.C b/hvirtual/plugins/oilpainting/oil.C index 6c0f7d32..a4aca248 100644 --- a/hvirtual/plugins/oilpainting/oil.C +++ b/hvirtual/plugins/oilpainting/oil.C @@ -4,6 +4,7 @@ #include "filexml.h" #include "guicast.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" @@ -13,10 +14,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -271,11 +268,7 @@ void OilWindow::create_objects() flush(); } -int OilWindow::close_event() -{ - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(OilWindow) @@ -459,25 +452,34 @@ OilUnit::OilUnit(OilEffect *plugin, OilServer *server) ((p)[2] * 29)) >> 8) -#define OIL_MACRO(type, max, components) \ +#define OIL_MACRO(type, hist_size, components) \ { \ type *src, *dest; \ - type Val[components]; \ - type Cnt[components], Cnt2; \ - type Hist[components][max + 1], Hist2[max + 1]; \ + type val[components]; \ + int count[components], count2; \ + int *hist[components]; \ + int *hist2; \ type **src_rows = (type**)plugin->input->get_rows(); \ \ + for(int i = 0; i < components; i++) \ + hist[i] = new int[hist_size + 1]; \ + hist2 = new int[hist_size + 1]; \ + \ +printf("1\n"); \ for(int y1 = pkg->row1; y1 < pkg->row2; y1++) \ { \ dest = (type*)plugin->output->get_rows()[y1]; \ \ +printf("2 %d\n", y1); \ if(!plugin->config.use_intensity) \ { \ for(int x1 = 0; x1 < w; x1++) \ { \ - bzero(Cnt, sizeof(Cnt)); \ - bzero(Val, sizeof(Val)); \ - bzero(Hist, sizeof(Hist)); \ + bzero(count, sizeof(count)); \ + bzero(val, sizeof(val)); \ + bzero(hist[0], sizeof(int) * (hist_size + 1)); \ + bzero(hist[1], sizeof(int) * (hist_size + 1)); \ + bzero(hist[2], sizeof(int) * (hist_size + 1)); \ \ int x3 = CLIP((x1 - n), 0, w - 1); \ int y3 = CLIP((y1 - n), 0, h - 1); \ @@ -490,48 +492,87 @@ OilUnit::OilUnit(OilEffect *plugin, OilServer *server) for(int x2 = x3; x2 < x4; x2++) \ { \ int c; \ - if((c = ++Hist[0][src[x2 * components + 0]]) > Cnt[0]) \ + int subscript; \ + type value; \ + \ + value = src[x2 * components + 0]; \ + if(sizeof(type) == 4) \ + { \ + subscript = (int)(value * hist_size); \ + CLAMP(subscript, 0, hist_size); \ + } \ + else \ + subscript = (int)value; \ + \ + if((c = ++hist[0][subscript]) > count[0]) \ + { \ + val[0] = value; \ + count[0] = c; \ + } \ + \ + value = src[x2 * components + 1]; \ + if(sizeof(type) == 4) \ { \ - Val[0] = src[x2 * components + 0]; \ - Cnt[0] = c; \ + subscript = (int)(value * hist_size); \ + CLAMP(subscript, 0, hist_size); \ } \ + else \ + subscript = (int)value; \ \ - if((c = ++Hist[1][src[x2 * components + 1]]) > Cnt[1]) \ + if((c = ++hist[1][subscript]) > count[1]) \ { \ - Val[1] = src[x2 * components + 1]; \ - Cnt[1] = c; \ + val[1] = value; \ + count[1] = c; \ } \ \ - if((c = ++Hist[2][src[x2 * components + 2]]) > Cnt[2]) \ + value = src[x2 * components + 2]; \ + if(sizeof(type) == 4) \ { \ - Val[2] = src[x2 * components + 2]; \ - Cnt[2] = c; \ + subscript = (int)(value * hist_size); \ + CLAMP(subscript, 0, hist_size); \ + } \ + else \ + subscript = (int)value; \ + \ + if((c = ++hist[2][subscript]) > count[2]) \ + { \ + val[2] = value; \ + count[2] = c; \ } \ \ if(components == 4) \ { \ - if((c = ++Hist[3][src[x2 * components + 3]]) > Cnt[3]) \ + value = src[x2 * components + 3]; \ + if(sizeof(type) == 4) \ + { \ + subscript = (int)(value * hist_size); \ + CLAMP(subscript, 0, hist_size); \ + } \ + else \ + subscript = (int)value; \ + \ + if((c = ++hist[3][subscript]) > count[3]) \ { \ - Val[3] = src[x2 * components + 3]; \ - Cnt[3] = c; \ + val[3] = value; \ + count[3] = c; \ } \ } \ } \ } \ \ - dest[x1 * components + 0] = Val[0]; \ - dest[x1 * components + 1] = Val[1]; \ - dest[x1 * components + 2] = Val[2]; \ - if(components == 4) dest[x1 * components + 3] = Val[3]; \ + dest[x1 * components + 0] = val[0]; \ + dest[x1 * components + 1] = val[1]; \ + dest[x1 * components + 2] = val[2]; \ + if(components == 4) dest[x1 * components + 3] = val[3]; \ } \ } \ else \ { \ for(int x1 = 0; x1 < w; x1++) \ { \ - Cnt2 = 0; \ - bzero(Val, sizeof(Val)); \ - bzero(Hist2, sizeof(Hist2)); \ + count2 = 0; \ + bzero(val, sizeof(val)); \ + bzero(hist2, sizeof(int) * (hist_size + 1)); \ \ int x3 = CLIP((x1 - n), 0, w - 1); \ int y3 = CLIP((y1 - n), 0, h - 1); \ @@ -544,24 +585,29 @@ OilUnit::OilUnit(OilEffect *plugin, OilServer *server) for(int x2 = x3; x2 < x4; x2++) \ { \ int c; \ - if((c = ++Hist2[INTENSITY(src + x2 * components)]) > Cnt2) \ + if((c = ++hist2[INTENSITY(src + x2 * components)]) > count2) \ { \ - Val[0] = src[x2 * components + 0]; \ - Val[1] = src[x2 * components + 1]; \ - Val[2] = src[x2 * components + 2]; \ - if(components == 3) Val[3] = src[x2 * components + 3]; \ - Cnt2 = c; \ + val[0] = src[x2 * components + 0]; \ + val[1] = src[x2 * components + 1]; \ + val[2] = src[x2 * components + 2]; \ + if(components == 3) val[3] = src[x2 * components + 3]; \ + count2 = c; \ } \ } \ } \ \ - dest[x1 * components + 0] = Val[0]; \ - dest[x1 * components + 1] = Val[1]; \ - dest[x1 * components + 2] = Val[2]; \ - if(components == 3) dest[x1 * components + 3] = Val[3]; \ + dest[x1 * components + 0] = val[0]; \ + dest[x1 * components + 1] = val[1]; \ + dest[x1 * components + 2] = val[2]; \ + if(components == 3) dest[x1 * components + 3] = val[3]; \ } \ } \ } \ + \ + for(int i = 0; i < components; i++) \ + delete [] hist[i]; \ + delete [] hist2; \ +printf("10\n"); \ } @@ -576,6 +622,9 @@ void OilUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + OIL_MACRO(float, 0xffff, 3) + break; case BC_RGB888: case BC_YUV888: OIL_MACRO(unsigned char, 0xff, 3) @@ -584,6 +633,9 @@ void OilUnit::process_package(LoadPackage *package) case BC_YUV161616: OIL_MACRO(uint16_t, 0xffff, 3) break; + case BC_RGBA_FLOAT: + OIL_MACRO(float, 0xffff, 4) + break; case BC_RGBA8888: case BC_YUVA8888: OIL_MACRO(unsigned char, 0xff, 4) diff --git a/hvirtual/plugins/perspective/perspective.C b/hvirtual/plugins/perspective/perspective.C index 1f726aa6..2ad0b993 100644 --- a/hvirtual/plugins/perspective/perspective.C +++ b/hvirtual/plugins/perspective/perspective.C @@ -959,9 +959,15 @@ int PerspectiveMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) switch(input_ptr->get_color_model()) { + case BC_RGB_FLOAT: + RESAMPLE(float, 3, 0) + break; case BC_RGB888: RESAMPLE(unsigned char, 3, 0) break; + case BC_RGBA_FLOAT: + RESAMPLE(float, 4, 0) + break; case BC_RGBA8888: RESAMPLE(unsigned char, 4, 0) break; @@ -1413,9 +1419,11 @@ void PerspectiveUnit::process_package(LoadPackage *package) //printf("PerspectiveUnit::process_package 1 %d %d %d %d %f %f\n", tx1, ty1, tx2, ty2, out_x4, out_y4); -#define TRANSFORM(components, type, chroma_offset, max) \ +#define TRANSFORM(components, type, temp_type, chroma_offset, max) \ { \ type **in_rows = (type**)plugin->input->get_rows(); \ + float round_factor = 0.0; \ + if(sizeof(type) < 4) round_factor = 0.5; \ for(int y = ty1; y < ty2; y++) \ { \ type *out_row = (type*)plugin->output->get_rows()[y]; \ @@ -1517,35 +1525,37 @@ void PerspectiveUnit::process_package(LoadPackage *package) type *row2_ptr = in_rows[row2]; \ type *row3_ptr = in_rows[row3]; \ type *row4_ptr = in_rows[row4]; \ - int r, g, b, a; \ + temp_type r, g, b, a; \ \ - r = (int)(transform_cubic(dy, \ + r = (temp_type)(transform_cubic(dy, \ CUBIC_ROW(row1_ptr, 0x0), \ CUBIC_ROW(row2_ptr, 0x0), \ CUBIC_ROW(row3_ptr, 0x0), \ - CUBIC_ROW(row4_ptr, 0x0)) + \ - 0.5); \ + CUBIC_ROW(row4_ptr, 0x0)) + \ + round_factor); \ \ row1_ptr++; \ row2_ptr++; \ row3_ptr++; \ row4_ptr++; \ - g = ROUND(transform_cubic(dy, \ + g = (temp_type)(transform_cubic(dy, \ CUBIC_ROW(row1_ptr, chroma_offset), \ CUBIC_ROW(row2_ptr, chroma_offset), \ CUBIC_ROW(row3_ptr, chroma_offset), \ - CUBIC_ROW(row4_ptr, chroma_offset))); \ + CUBIC_ROW(row4_ptr, chroma_offset)) + \ + round_factor); \ g += chroma_offset; \ \ row1_ptr++; \ row2_ptr++; \ row3_ptr++; \ row4_ptr++; \ - b = ROUND(transform_cubic(dy, \ + b = (temp_type)(transform_cubic(dy, \ CUBIC_ROW(row1_ptr, chroma_offset), \ CUBIC_ROW(row2_ptr, chroma_offset), \ CUBIC_ROW(row3_ptr, chroma_offset), \ - CUBIC_ROW(row4_ptr, chroma_offset))); \ + CUBIC_ROW(row4_ptr, chroma_offset)) + \ + round_factor); \ b += chroma_offset; \ \ if(components == 4) \ @@ -1554,18 +1564,28 @@ void PerspectiveUnit::process_package(LoadPackage *package) row2_ptr++; \ row3_ptr++; \ row4_ptr++; \ - a = (int)(transform_cubic(dy, \ + a = (temp_type)(transform_cubic(dy, \ CUBIC_ROW(row1_ptr, 0x0), \ CUBIC_ROW(row2_ptr, 0x0), \ CUBIC_ROW(row3_ptr, 0x0), \ CUBIC_ROW(row4_ptr, 0x0)) + \ - 0.5); \ + round_factor); \ } \ \ - *out_row++ = CLIP(r, 0, max); \ - *out_row++ = CLIP(g, 0, max); \ - *out_row++ = CLIP(b, 0, max); \ - if(components == 4) *out_row++ = CLIP(a, 0, max); \ + if(sizeof(type) < 4) \ + { \ + *out_row++ = CLIP(r, 0, max); \ + *out_row++ = CLIP(g, 0, max); \ + *out_row++ = CLIP(b, 0, max); \ + if(components == 4) *out_row++ = CLIP(a, 0, max); \ + } \ + else \ + { \ + *out_row++ = r; \ + *out_row++ = g; \ + *out_row++ = b; \ + if(components == 4) *out_row++ = a; \ + } \ } \ else \ /* Fill with chroma */ \ @@ -1594,29 +1614,35 @@ void PerspectiveUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + TRANSFORM(3, float, float, 0x0, 1) + break; case BC_RGB888: - TRANSFORM(3, unsigned char, 0x0, 0xff) + TRANSFORM(3, unsigned char, int, 0x0, 0xff) + break; + case BC_RGBA_FLOAT: + TRANSFORM(4, float, float, 0x0, 1) break; case BC_RGBA8888: - TRANSFORM(4, unsigned char, 0x0, 0xff) + TRANSFORM(4, unsigned char, int, 0x0, 0xff) break; case BC_YUV888: - TRANSFORM(3, unsigned char, 0x80, 0xff) + TRANSFORM(3, unsigned char, int, 0x80, 0xff) break; case BC_YUVA8888: - TRANSFORM(4, unsigned char, 0x80, 0xff) + TRANSFORM(4, unsigned char, int, 0x80, 0xff) break; case BC_RGB161616: - TRANSFORM(3, uint16_t, 0x0, 0xffff) + TRANSFORM(3, uint16_t, int, 0x0, 0xffff) break; case BC_RGBA16161616: - TRANSFORM(4, uint16_t, 0x0, 0xffff) + TRANSFORM(4, uint16_t, int, 0x0, 0xffff) break; case BC_YUV161616: - TRANSFORM(3, uint16_t, 0x8000, 0xffff) + TRANSFORM(3, uint16_t, int, 0x8000, 0xffff) break; case BC_YUVA16161616: - TRANSFORM(4, uint16_t, 0x8000, 0xffff) + TRANSFORM(4, uint16_t, int, 0x8000, 0xffff) break; } @@ -1684,9 +1710,15 @@ void PerspectiveUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + PERSPECTIVE(float, 3) + break; case BC_RGB888: PERSPECTIVE(unsigned char, 3) break; + case BC_RGBA_FLOAT: + PERSPECTIVE(float, 4) + break; case BC_RGBA8888: PERSPECTIVE(unsigned char, 4) break; diff --git a/hvirtual/plugins/pitch/pitch.C b/hvirtual/plugins/pitch/pitch.C index 986b0b32..65f77687 100644 --- a/hvirtual/plugins/pitch/pitch.C +++ b/hvirtual/plugins/pitch/pitch.C @@ -160,8 +160,8 @@ PitchFFT::PitchFFT(PitchEffect *plugin) int PitchFFT::signal_process() { int min_freq = - 1 + (int)(20.0 / ((double)plugin->PluginAClient::project_sample_rate / window_size * 2) + 0.5); -//printf("PitchFFT::signal_process %d\n", min_freq); + 1 + (int)(20.0 / ((double)plugin->PluginAClient::project_sample_rate / + window_size * 2) + 0.5); if(plugin->config.scale < 1) { for(int i = min_freq; i < window_size / 2; i++) diff --git a/hvirtual/plugins/polar/polar.C b/hvirtual/plugins/polar/polar.C index be1d92d4..1c24b554 100644 --- a/hvirtual/plugins/polar/polar.C +++ b/hvirtual/plugins/polar/polar.C @@ -4,6 +4,7 @@ #include "filexml.h" #include "guicast.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" @@ -14,10 +15,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) #define SQR(x) ((x) * (x)) #define WITHIN(a, b, c) ((((a) <= (b)) && ((b) <= (c))) ? 1 : 0) @@ -211,11 +208,7 @@ void PolarWindow::create_objects() flush(); } -int PolarWindow::close_event() -{ - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(PolarWindow) PLUGIN_THREAD_OBJECT(PolarEffect, PolarThread, PolarWindow) @@ -776,6 +769,12 @@ void PolarUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + POLAR_MACRO(float, 1, 3, 0x0) + break; + case BC_RGBA_FLOAT: + POLAR_MACRO(float, 1, 4, 0x0) + break; case BC_RGB888: POLAR_MACRO(unsigned char, 0xff, 3, 0x0) break; diff --git a/hvirtual/plugins/radialblur/radialblur.C b/hvirtual/plugins/radialblur/radialblur.C index a42b6128..f9793c96 100644 --- a/hvirtual/plugins/radialblur/radialblur.C +++ b/hvirtual/plugins/radialblur/radialblur.C @@ -7,17 +7,13 @@ #include "defaults.h" #include "filexml.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - class RadialBlurMain; class RadialBlurEngine; @@ -285,13 +281,7 @@ int RadialBlurWindow::create_objects() return 0; } -int RadialBlurWindow::close_event() -{ -// Set result to 1 to indicate a plugin side close - set_done(1); - return 1; -} - +WINDOW_CLOSE_EVENT(RadialBlurWindow) @@ -534,7 +524,7 @@ RadialBlurUnit::RadialBlurUnit(RadialBlurEngine *server, } -#define BLEND_LAYER(COMPONENTS, TYPE, MAX, DO_YUV) \ +#define BLEND_LAYER(COMPONENTS, TYPE, TEMP_TYPE, MAX, DO_YUV) \ { \ int chroma_offset = (DO_YUV ? ((MAX + 1) / 2) : 0); \ TYPE **in_rows = (TYPE**)plugin->input->get_rows(); \ @@ -553,10 +543,10 @@ RadialBlurUnit::RadialBlurUnit(RadialBlurEngine *server, for(int j = 0, out_x = -center_x; j < w; j++, out_x++) \ { \ double offset = 0; \ - int accum_r = 0; \ - int accum_g = 0; \ - int accum_b = 0; \ - int accum_a = 0; \ + TEMP_TYPE accum_r = 0; \ + TEMP_TYPE accum_g = 0; \ + TEMP_TYPE accum_b = 0; \ + TEMP_TYPE accum_a = 0; \ \ /* Output coordinate to polar */ \ double magnitude = sqrt(y_square + out_x * out_x); \ @@ -607,7 +597,7 @@ RadialBlurUnit::RadialBlurUnit(RadialBlurEngine *server, /* Accumulation to output */ \ if(do_r) \ { \ - *out_row++ = (accum_r * fraction) >> 16; \ + *out_row++ = (accum_r * fraction) / 0x10000; \ in_row++; \ } \ else \ @@ -618,9 +608,9 @@ RadialBlurUnit::RadialBlurUnit(RadialBlurEngine *server, if(do_g) \ { \ if(DO_YUV) \ - *out_row++ = ((accum_g * fraction) >> 16); \ + *out_row++ = ((accum_g * fraction) / 0x10000); \ else \ - *out_row++ = (accum_g * fraction) >> 16; \ + *out_row++ = (accum_g * fraction) / 0x10000; \ in_row++; \ } \ else \ @@ -631,9 +621,9 @@ RadialBlurUnit::RadialBlurUnit(RadialBlurEngine *server, if(do_b) \ { \ if(DO_YUV) \ - *out_row++ = ((accum_b * fraction) >> 16); \ + *out_row++ = (accum_b * fraction) / 0x10000; \ else \ - *out_row++ = (accum_b * fraction) >> 16; \ + *out_row++ = (accum_b * fraction) / 0x10000; \ in_row++; \ } \ else \ @@ -645,7 +635,7 @@ RadialBlurUnit::RadialBlurUnit(RadialBlurEngine *server, { \ if(do_a) \ { \ - *out_row++ = (accum_a * fraction) >> 16; \ + *out_row++ = (accum_a * fraction) / 0x10000; \ in_row++; \ } \ else \ @@ -673,28 +663,34 @@ void RadialBlurUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { case BC_RGB888: - BLEND_LAYER(3, uint8_t, 0xff, 0) + BLEND_LAYER(3, uint8_t, int, 0xff, 0) break; case BC_RGBA8888: - BLEND_LAYER(4, uint8_t, 0xff, 0) + BLEND_LAYER(4, uint8_t, int, 0xff, 0) + break; + case BC_RGB_FLOAT: + BLEND_LAYER(3, float, float, 1, 0) + break; + case BC_RGBA_FLOAT: + BLEND_LAYER(4, float, float, 1, 0) break; case BC_RGB161616: - BLEND_LAYER(3, uint16_t, 0xffff, 0) + BLEND_LAYER(3, uint16_t, int, 0xffff, 0) break; case BC_RGBA16161616: - BLEND_LAYER(4, uint16_t, 0xffff, 0) + BLEND_LAYER(4, uint16_t, int, 0xffff, 0) break; case BC_YUV888: - BLEND_LAYER(3, uint8_t, 0xff, 1) + BLEND_LAYER(3, uint8_t, int, 0xff, 1) break; case BC_YUVA8888: - BLEND_LAYER(4, uint8_t, 0xff, 1) + BLEND_LAYER(4, uint8_t, int, 0xff, 1) break; case BC_YUV161616: - BLEND_LAYER(3, uint16_t, 0xffff, 1) + BLEND_LAYER(3, uint16_t, int, 0xffff, 1) break; case BC_YUVA16161616: - BLEND_LAYER(4, uint16_t, 0xffff, 1) + BLEND_LAYER(4, uint16_t, int, 0xffff, 1) break; } } diff --git a/hvirtual/plugins/reframe/reframe.C b/hvirtual/plugins/reframe/reframe.C index 495a8c80..dd83ae2f 100644 --- a/hvirtual/plugins/reframe/reframe.C +++ b/hvirtual/plugins/reframe/reframe.C @@ -1,15 +1,11 @@ #include "bcdisplayinfo.h" #include "defaults.h" +#include "language.h" #include "mainprogress.h" #include "picon_png.h" #include "reframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -183,12 +179,6 @@ void ReFrameWindow::create_objects() flush(); } -int ReFrameWindow::close_event() -{ - set_done(1); - return 1; -} - - +WINDOW_CLOSE_EVENT(ReFrameWindow) diff --git a/hvirtual/plugins/rgb601/rgb601.C b/hvirtual/plugins/rgb601/rgb601.C index 4b6bf042..23fb3a50 100644 --- a/hvirtual/plugins/rgb601/rgb601.C +++ b/hvirtual/plugins/rgb601/rgb601.C @@ -1,6 +1,7 @@ #include "clip.h" #include "colormodels.h" #include "filexml.h" +#include "language.h" #include "picon_png.h" #include "rgb601.h" #include "rgb601window.h" @@ -8,10 +9,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) REGISTER_PLUGIN(RGB601Main) @@ -174,20 +171,37 @@ void RGB601Main::create_table(VFrame *input_ptr) /* Just do Y */ \ for(int j = 0; j < w; j++) \ { \ - out_row[j * components] = table[in_row[j * components]]; \ + out_row[j * components] = table[(int)in_row[j * components]]; \ out_row[j * components + 1] = in_row[j * components + 1]; \ out_row[j * components + 2] = in_row[j * components + 2]; \ - if(components == 4) out_row[j * components + 3] = in_row[j * components + 3]; \ } \ } \ else \ + if(sizeof(type) == 4) \ { \ - for(int j = 0; j < bytes; j++) \ + for(int j = 0; j < w; j++) \ + { \ + if(table == forward_table) \ + { \ + out_row[j * components] = (type)(in_row[j * components] * 0.8588 + 0.0627); \ + out_row[j * components + 1] = (type)(in_row[j * components + 1] * 0.8588 + 0.0627); \ + out_row[j * components + 2] = (type)(in_row[j * components + 2] * 0.8588 + 0.0627); \ + } \ + else \ + { \ + out_row[j * components] = (type)(in_row[j * components] * 1.1644 - 0.0627); \ + out_row[j * components + 1] = (type)(in_row[j * components + 1] * 1.1644 - 0.0627); \ + out_row[j * components + 2] = (type)(in_row[j * components + 2] * 1.1644 - 0.0627); \ + } \ + } \ + } \ + else \ + { \ + for(int j = 0; j < w; j++) \ { \ - out_row[j * components] = in_row[j * components]; \ - out_row[j * components + 1] = table[in_row[j * components + 1]]; \ - out_row[j * components + 2] = table[in_row[j * components + 2]]; \ - if(components == 4) out_row[j * components + 3] = table[in_row[j * components + 3]]; \ + out_row[j * components] = table[(int)in_row[j * components]]; \ + out_row[j * components + 1] = table[(int)in_row[j * components + 1]]; \ + out_row[j * components + 2] = table[(int)in_row[j * components + 2]]; \ } \ } \ } \ @@ -219,6 +233,12 @@ void RGB601Main::process(int *table, VFrame *input_ptr, VFrame *output_ptr) case BC_RGBA8888: PROCESS(forward_table, unsigned char, 4, 0); break; + case BC_RGB_FLOAT: + PROCESS(forward_table, float, 3, 0); + break; + case BC_RGBA_FLOAT: + PROCESS(forward_table, float, 4, 0); + break; case BC_RGB161616: PROCESS(forward_table, u_int16_t, 3, 0); break; @@ -248,6 +268,12 @@ void RGB601Main::process(int *table, VFrame *input_ptr, VFrame *output_ptr) case BC_RGBA8888: PROCESS(reverse_table, unsigned char, 4, 0); break; + case BC_RGB_FLOAT: + PROCESS(reverse_table, float, 3, 0); + break; + case BC_RGBA_FLOAT: + PROCESS(reverse_table, float, 4, 0); + break; case BC_RGB161616: PROCESS(reverse_table, u_int16_t, 3, 0); break; @@ -265,6 +291,7 @@ int RGB601Main::process_realtime(VFrame *input_ptr, VFrame *output_ptr) load_configuration(); create_table(input_ptr); + if(config.direction == 1) process(forward_table, input_ptr, output_ptr); else diff --git a/hvirtual/plugins/rgb601/rgb601window.C b/hvirtual/plugins/rgb601/rgb601window.C index 832706d3..1b861c0a 100644 --- a/hvirtual/plugins/rgb601/rgb601window.C +++ b/hvirtual/plugins/rgb601/rgb601window.C @@ -1,12 +1,8 @@ #include "bcdisplayinfo.h" +#include "language.h" #include "rgb601window.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -55,12 +51,7 @@ void RGB601Window::update() reverse->update(client->config.direction == 2); } -int RGB601Window::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(RGB601Window) RGB601Direction::RGB601Direction(RGB601Window *window, int x, int y, int *output, int true_value, char *text) : BC_CheckBox(x, y, *output == true_value, text) diff --git a/hvirtual/plugins/rotate/rotate.C b/hvirtual/plugins/rotate/rotate.C index 44669b68..77491a5a 100644 --- a/hvirtual/plugins/rotate/rotate.C +++ b/hvirtual/plugins/rotate/rotate.C @@ -383,12 +383,7 @@ int RotateWindow::create_objects() return 0; } -int RotateWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(RotateWindow) int RotateWindow::update() { diff --git a/hvirtual/plugins/sharpen/sharpen.C b/hvirtual/plugins/sharpen/sharpen.C index 6162134c..eb5aff06 100644 --- a/hvirtual/plugins/sharpen/sharpen.C +++ b/hvirtual/plugins/sharpen/sharpen.C @@ -1,6 +1,8 @@ #include "clip.h" #include "colormodels.h" +#include "condition.h" #include "filexml.h" +#include "language.h" #include "picon_png.h" #include "sharpen.h" #include "sharpenwindow.h" @@ -8,11 +10,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - REGISTER_PLUGIN(SharpenMain) @@ -300,29 +297,32 @@ void SharpenMain::read_data(KeyFrame *keyframe) SharpenEngine::SharpenEngine(SharpenMain *plugin) - : Thread() + : Thread(1, 0, 0) { this->plugin = plugin; + input_lock = new Condition(0,"SharpenEngine::input_lock"); + output_lock = new Condition(0, "SharpenEngine::output_lock"); last_frame = 0; for(int i = 0; i < 4; i++) { - neg_rows[i] = new int[plugin->input->get_w() * 4]; + neg_rows[i] = new unsigned char[plugin->input->get_w() * + 4 * + MAX(sizeof(float), sizeof(int))]; } - input_lock.lock(); - output_lock.lock(); - set_synchronous(1); } SharpenEngine::~SharpenEngine() { last_frame = 1; - input_lock.unlock(); + input_lock->unlock(); Thread::join(); for(int i = 0; i < 4; i++) { delete [] neg_rows[i]; } + delete input_lock; + delete output_lock; } int SharpenEngine::start_process_frame(VFrame *output, VFrame *input, int field) @@ -330,19 +330,37 @@ int SharpenEngine::start_process_frame(VFrame *output, VFrame *input, int field) this->output = output; this->input = input; this->field = field; - input_lock.unlock(); + +// Get coefficient for floating point + sharpness_coef = 100 - plugin->config.sharpness; + if(plugin->config.horizontal) sharpness_coef /= 2; + if(sharpness_coef < 1) sharpness_coef = 1; + sharpness_coef = 800.0 / sharpness_coef; + + input_lock->unlock(); return 0; } int SharpenEngine::wait_process_frame() { - output_lock.lock(); + output_lock->lock("SharpenEngine::wait_process_frame"); return 0; } -#define FILTER(components, vmax, wordsize) \ +float SharpenEngine::calculate_pos(float value) +{ + return sharpness_coef * value; +} + +float SharpenEngine::calculate_neg(float value) +{ + return (calculate_pos(value) - (value * 8)) / 8; +} + +#define FILTER(components, vmax) \ { \ int *pos_lut = plugin->pos_lut; \ + const int wordsize = sizeof(*src); \ \ /* Skip first pixel in row */ \ memcpy(dst, src, components * wordsize); \ @@ -402,9 +420,6 @@ int SharpenEngine::wait_process_frame() else \ dst[2] = pixel; \ \ - if(components == 4) \ - dst[3] = src[3]; \ - \ src += components; \ dst += components; \ \ @@ -419,7 +434,6 @@ int SharpenEngine::wait_process_frame() } void SharpenEngine::filter(int components, - int wordsize, int vmax, int w, u_int16_t *src, @@ -428,11 +442,10 @@ void SharpenEngine::filter(int components, int *neg1, int *neg2) { - FILTER(components, vmax, wordsize); + FILTER(components, vmax); } void SharpenEngine::filter(int components, - int wordsize, int vmax, int w, unsigned char *src, @@ -441,7 +454,74 @@ void SharpenEngine::filter(int components, int *neg1, int *neg2) { - FILTER(components, vmax, wordsize); + FILTER(components, vmax); +} + +void SharpenEngine::filter(int components, + int vmax, + int w, + float *src, + float *dst, + float *neg0, + float *neg1, + float *neg2) +{ + const int wordsize = sizeof(float); +// First pixel in row + memcpy(dst, src, components * wordsize); + dst += components; + src += components; + + w -= 2; + while(w > 0) + { + float pixel; + pixel = calculate_pos(src[0]) - + neg0[-components] - + neg0[0] - + neg0[components] - + neg1[-components] - + neg1[components] - + neg2[-components] - + neg2[0] - + neg2[components]; + pixel /= 8; + dst[0] = pixel; + + pixel = calculate_pos(src[1]) - + neg0[-components + 1] - + neg0[1] - + neg0[components + 1] - + neg1[-components + 1] - + neg1[components + 1] - + neg2[-components + 1] - + neg2[1] - + neg2[components + 1]; + pixel /= 8; + dst[1] = pixel; + + pixel = calculate_pos(src[2]) - + neg0[-components + 2] - + neg0[2] - + neg0[components + 2] - + neg1[-components + 2] - + neg1[components + 2] - + neg2[-components + 2] - + neg2[2] - + neg2[components + 2]; + pixel /= 8; + dst[2] = pixel; + + src += components; + dst += components; + neg0 += components; + neg1 += components; + neg2 += components; + w--; + } + +/* Last pixel */ + memcpy(dst, src, components * wordsize); } @@ -450,9 +530,10 @@ void SharpenEngine::filter(int components, -#define SHARPEN(components, wordsize, wordtype, vmax) \ +#define SHARPEN(components, type, temp_type, vmax) \ { \ int count, row; \ + int wordsize = sizeof(type); \ unsigned char **input_rows, **output_rows; \ int w = plugin->input->get_w(); \ int h = plugin->input->get_h(); \ @@ -466,8 +547,21 @@ void SharpenEngine::filter(int components, \ for(int j = 0; j < w; j++) \ { \ + temp_type *neg = (temp_type*)neg_rows[0]; \ + type *src = (type*)src_rows[0]; \ for(int k = 0; k < components; k++) \ - neg_rows[0][j * components + k] = plugin->neg_lut[((wordtype*)src_rows[0])[j * components + k]]; \ + { \ + if(wordsize == 4) \ + { \ + neg[j * components + k] = \ + (temp_type)calculate_neg(src[j * components + k]); \ + } \ + else \ + { \ + neg[j * components + k] = \ + (temp_type)plugin->neg_lut[(int)src[j * components + k]]; \ + } \ + } \ } \ \ row = 1; \ @@ -480,10 +574,24 @@ void SharpenEngine::filter(int components, if(count >= 3) count--; \ /* Arm next row */ \ src_rows[row] = input_rows[i + plugin->row_step]; \ +/* Calculate neg rows */ \ + type *src = (type*)src_rows[row]; \ + temp_type *neg = (temp_type*)neg_rows[row]; \ for(int k = 0; k < w; k++) \ { \ for(int j = 0; j < components; j++) \ - neg_rows[row][k * components + j] = plugin->neg_lut[((wordtype*)src_rows[row])[k * components + j]]; \ + { \ + if(wordsize == 4) \ + { \ + neg[k * components + j] = \ + (temp_type)calculate_neg(src[k * components + j]); \ + } \ + else \ + { \ + neg[k * components + j] = \ + plugin->neg_lut[(int)src[k * components + j]]; \ + } \ + } \ } \ \ count++; \ @@ -500,24 +608,22 @@ void SharpenEngine::filter(int components, /* Do the filter */ \ if(plugin->config.horizontal) \ filter(components, \ - wordsize, \ vmax, \ w, \ - (wordtype*)src_rows[(row + 2) & 3], \ - (wordtype*)dst_row, \ - neg_rows[(row + 2) & 3] + components, \ - neg_rows[(row + 2) & 3] + components, \ - neg_rows[(row + 2) & 3] + components); \ + (type*)src_rows[(row + 2) & 3], \ + (type*)dst_row, \ + (temp_type*)neg_rows[(row + 2) & 3] + components, \ + (temp_type*)neg_rows[(row + 2) & 3] + components, \ + (temp_type*)neg_rows[(row + 2) & 3] + components); \ else \ filter(components, \ - wordsize, \ vmax, \ w, \ - (wordtype*)src_rows[(row + 2) & 3], \ - (wordtype*)dst_row, \ - neg_rows[(row + 1) & 3] + components, \ - neg_rows[(row + 2) & 3] + components, \ - neg_rows[(row + 3) & 3] + components); \ + (type*)src_rows[(row + 2) & 3], \ + (type*)dst_row, \ + (temp_type*)neg_rows[(row + 1) & 3] + components, \ + (temp_type*)neg_rows[(row + 2) & 3] + components, \ + (temp_type*)neg_rows[(row + 3) & 3] + components); \ } \ else \ if(count == 2) \ @@ -530,63 +636,52 @@ void SharpenEngine::filter(int components, } \ } -void SharpenEngine::sharpen_888() -{ - SHARPEN(3, 1, unsigned char, 0xff); -} - -void SharpenEngine::sharpen_8888() -{ - SHARPEN(4, 1, unsigned char, 0xff); -} - -void SharpenEngine::sharpen_161616() -{ - SHARPEN(3, 2, u_int16_t, 0xffff); -} - -void SharpenEngine::sharpen_16161616() -{ - SHARPEN(4, 2, u_int16_t, 0xffff); -} void SharpenEngine::run() { while(1) { - input_lock.lock(); + input_lock->lock("SharpenEngine::run"); if(last_frame) { - output_lock.unlock(); + output_lock->unlock(); return; } switch(input->get_color_model()) { + case BC_RGB_FLOAT: + SHARPEN(3, float, float, 1); + break; + case BC_RGB888: case BC_YUV888: - sharpen_888(); + SHARPEN(3, unsigned char, int, 0xff); break; + case BC_RGBA_FLOAT: + SHARPEN(4, float, float, 1); + break; + case BC_RGBA8888: case BC_YUVA8888: - sharpen_8888(); + SHARPEN(4, unsigned char, int, 0xff); break; case BC_RGB161616: case BC_YUV161616: - sharpen_161616(); + SHARPEN(3, u_int16_t, int, 0xffff); break; case BC_RGBA16161616: case BC_YUVA16161616: - sharpen_16161616(); + SHARPEN(4, u_int16_t, int, 0xffff); break; } - output_lock.unlock(); + output_lock->unlock(); } } diff --git a/hvirtual/plugins/sharpen/sharpen.h b/hvirtual/plugins/sharpen/sharpen.h new file mode 100644 index 00000000..5519c3e2 --- /dev/null +++ b/hvirtual/plugins/sharpen/sharpen.h @@ -0,0 +1,160 @@ +#ifndef SHARPEN_H +#define SHARPEN_H + +// the simplest plugin possible +// Sharpen leaves the last line too bright + +class SharpenMain; +#define MAXSHARPNESS 100 + +#include "condition.inc" +#include "defaults.h" +#include "pluginvclient.h" +#include "sharpenwindow.h" + +#include + +class SharpenEngine; + +class SharpenConfig +{ +public: + SharpenConfig(); + + void copy_from(SharpenConfig &that); + int equivalent(SharpenConfig &that); + void interpolate(SharpenConfig &prev, + SharpenConfig &next, + long prev_frame, + long next_frame, + long current_frame); + + + + int horizontal; + int interlace; + int luminance; + float sharpness; +}; + +class SharpenMain : public PluginVClient +{ +public: + SharpenMain(PluginServer *server); + ~SharpenMain(); + +// required for all realtime plugins + int process_realtime(VFrame *input_ptr, VFrame *output_ptr); + int is_realtime(); + char* plugin_title(); + int show_gui(); + void raise_window(); + int set_string(); + void update_gui(); + int load_configuration(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + int load_defaults(); + int save_defaults(); + VFrame* new_picon(); + +// parameters needed for sharpness + int row_step; + +// a thread for the GUI + SharpenThread *thread; + int pos_lut[0x10000], neg_lut[0x10000]; + SharpenConfig config; + VFrame *output, *input; + +private: + int get_luts(int *pos_lut, int *neg_lut, int color_model); + Defaults *defaults; + SharpenEngine **engine; + int total_engines; +}; + + +class SharpenEngine : public Thread +{ +public: + SharpenEngine(SharpenMain *plugin); + ~SharpenEngine(); + + int start_process_frame(VFrame *output, VFrame *input, int field); + int wait_process_frame(); + void run(); + + void filter(int components, + int vmax, + int w, + unsigned char *src, + unsigned char *dst, + int *neg0, + int *neg1, + int *neg2); + void filter(int components, + int vmax, + int w, + u_int16_t *src, + u_int16_t *dst, + int *neg0, + int *neg1, + int *neg2); + void filter(int components, + int vmax, + int w, + float *src, + float *dst, + float *neg0, + float *neg1, + float *neg2); + + + void filter_888(int w, + unsigned char *src, + unsigned char *dst, + int *neg0, + int *neg1, + int *neg2); + void filter_8888(int w, + unsigned char *src, + unsigned char *dst, + int *neg0, + int *neg1, + int *neg2); + void filter_161616(int w, + u_int16_t *src, + u_int16_t *dst, + int *neg0, + int *neg1, + int *neg2); + void filter_16161616(int w, + u_int16_t *src, + u_int16_t *dst, + int *neg0, + int *neg1, + int *neg2); + + int filter(int w, + unsigned char *src, + unsigned char *dst, + int *neg0, + int *neg1, + int *neg2); + + float calculate_pos(float value); + float calculate_neg(float value); + + + SharpenMain *plugin; + int field; + VFrame *output, *input; + int last_frame; + Condition *input_lock, *output_lock; + unsigned char *src_rows[4], *dst_row; + unsigned char *neg_rows[4]; + float sharpness_coef; +}; + +#endif diff --git a/hvirtual/plugins/shiftinterlace/shiftinterlace.C b/hvirtual/plugins/shiftinterlace/shiftinterlace.C index 2947383c..e5b7e773 100644 --- a/hvirtual/plugins/shiftinterlace/shiftinterlace.C +++ b/hvirtual/plugins/shiftinterlace/shiftinterlace.C @@ -411,9 +411,15 @@ void ShiftInterlaceMain::shift_row(VFrame *input_frame, case BC_RGB888: SHIFT_ROW_MACRO(3, unsigned char, 0x0) break; + case BC_RGB_FLOAT: + SHIFT_ROW_MACRO(3, float, 0x0) + break; case BC_YUV888: SHIFT_ROW_MACRO(3, unsigned char, 0x80) break; + case BC_RGBA_FLOAT: + SHIFT_ROW_MACRO(4, float, 0x0) + break; case BC_RGBA8888: SHIFT_ROW_MACRO(4, unsigned char, 0x0) break; diff --git a/hvirtual/plugins/slide/slide.C b/hvirtual/plugins/slide/slide.C index 5a878641..038129f7 100644 --- a/hvirtual/plugins/slide/slide.C +++ b/hvirtual/plugins/slide/slide.C @@ -347,6 +347,12 @@ int SlideMain::process_realtime(VFrame *incoming, VFrame *outgoing) switch(incoming->get_color_model()) { + case BC_RGB_FLOAT: + SLIDE(float, 3) + break; + case BC_RGBA_FLOAT: + SLIDE(float, 4) + break; case BC_RGB888: case BC_YUV888: SLIDE(unsigned char, 3) diff --git a/hvirtual/plugins/swapchannels/swapchannels.C b/hvirtual/plugins/swapchannels/swapchannels.C index fc66ec30..e7d7967d 100644 --- a/hvirtual/plugins/swapchannels/swapchannels.C +++ b/hvirtual/plugins/swapchannels/swapchannels.C @@ -2,6 +2,7 @@ #include "clip.h" #include "defaults.h" #include "filexml.h" +#include "language.h" #include "picon_png.h" #include "swapchannels.h" #include "vframe.h" @@ -11,11 +12,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -109,12 +105,9 @@ void SwapWindow::create_objects() flush(); } -int SwapWindow::close_event() -{ -// Set result to 1 to indicate a client side close - set_done(1); - return 1; -} +WINDOW_CLOSE_EVENT(SwapWindow) + + @@ -397,6 +390,12 @@ int SwapMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) switch(input_ptr->get_color_model()) { + case BC_RGB_FLOAT: + SWAP_CHANNELS(float, 1, 3); + break; + case BC_RGBA_FLOAT: + SWAP_CHANNELS(float, 1, 4); + break; case BC_RGB888: case BC_YUV888: SWAP_CHANNELS(unsigned char, 0xff, 3); diff --git a/hvirtual/plugins/timeavg/timeavg.C b/hvirtual/plugins/timeavg/timeavg.C index 2f961352..5958bb54 100644 --- a/hvirtual/plugins/timeavg/timeavg.C +++ b/hvirtual/plugins/timeavg/timeavg.C @@ -2,16 +2,12 @@ #include "defaults.h" #include "filexml.h" #include "keyframe.h" +#include "language.h" #include "picon_png.h" #include "timeavg.h" #include "timeavgwindow.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - @@ -30,8 +26,34 @@ REGISTER_PLUGIN(TimeAvgMain) TimeAvgConfig::TimeAvgConfig() { frames = 1; + accumulate = 0; + paranoid = 0; +} + +void TimeAvgConfig::copy_from(TimeAvgConfig *src) +{ + this->frames = src->frames; + this->accumulate = src->accumulate; + this->paranoid = src->paranoid; } +int TimeAvgConfig::equivalent(TimeAvgConfig *src) +{ + return frames == src->frames && + accumulate == src->accumulate && + paranoid == src->paranoid; +} + + + + + + + + + + + TimeAvgMain::TimeAvgMain(PluginServer *server) @@ -41,11 +63,13 @@ TimeAvgMain::TimeAvgMain(PluginServer *server) accumulation = 0; history = 0; history_size = 0; + history_start = -0x7fffffff; + history_frame = 0; + history_valid = 0; } TimeAvgMain::~TimeAvgMain() { -//printf("TimeAvgMain::~TimeAvgMain 1\n"); PLUGIN_DESTRUCTOR_MACRO if(accumulation) delete [] accumulation; @@ -55,6 +79,8 @@ TimeAvgMain::~TimeAvgMain() delete history[i]; delete [] history; } + if(history_frame) delete [] history_frame; + if(history_valid) delete [] history_valid; } char* TimeAvgMain::plugin_title() { return N_("Time Average"); } @@ -71,152 +97,480 @@ RAISE_WINDOW_MACRO(TimeAvgMain); -int TimeAvgMain::process_realtime(VFrame *input, VFrame *output) +int TimeAvgMain::process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate) { - int h = input->get_h(); - int w = input->get_w(); - int color_model = input->get_color_model(); + int h = frame->get_h(); + int w = frame->get_w(); + int color_model = frame->get_color_model(); load_configuration(); +// Allocate accumulation if(!accumulation) { - accumulation = new int[w * h * cmodel_components(color_model)]; - bzero(accumulation, sizeof(int) * w * h * cmodel_components(color_model)); + accumulation = new unsigned char[w * + h * + cmodel_components(color_model) * + MAX(sizeof(float), sizeof(int))]; + clear_accum(w, h, color_model); } +// Reallocate history if(history) { if(config.frames != history_size) { VFrame **history2; + int64_t *history_frame2; + int *history_valid2; history2 = new VFrame*[config.frames]; + history_frame2 = new int64_t[config.frames]; + history_valid2 = new int[config.frames]; // Copy existing frames over int i, j; for(i = 0, j = 0; i < config.frames && j < history_size; i++, j++) + { history2[i] = history[j]; + history_frame2[i] = history_frame[i]; + history_valid2[i] = history_valid[i]; + } -// Delete extra previous frames +// Delete extra previous frames and subtract from accumulation for( ; j < history_size; j++) + { + subtract_accum(history[j]); delete history[j]; + } delete [] history; + delete [] history_frame; + delete [] history_valid; + // Create new frames for( ; i < config.frames; i++) + { history2[i] = new VFrame(0, w, h, color_model); + history_frame2[i] = -0x7fffffff; + history_valid2[i] = 0; + } history = history2; - history_size = config.frames; + history_frame = history_frame2; + history_valid = history_valid2; -for(i = 0; i < config.frames; i++) - bzero(history[i]->get_data(), history[i]->get_data_size()); - -bzero(accumulation, sizeof(int) * w * h * cmodel_components(color_model)); + history_size = config.frames; } } else +// Allocate history { history = new VFrame*[config.frames]; for(int i = 0; i < config.frames; i++) history[i] = new VFrame(0, w, h, color_model); history_size = config.frames; + history_frame = new int64_t[config.frames]; + bzero(history_frame, sizeof(int64_t) * config.frames); + history_valid = new int[config.frames]; + bzero(history_valid, sizeof(int) * config.frames); + } + + + + + + +// Create new history frames based on current frame + int64_t *new_history_frames = new int64_t[history_size]; + for(int i = 0; i < history_size; i++) + { + new_history_frames[history_size - i - 1] = start_position - i; + } + +// Subtract old history frames which are not in the new vector + int no_change = 1; + for(int i = 0; i < history_size; i++) + { +// Old frame is valid + if(history_valid[i]) + { + int got_it = 0; + for(int j = 0; j < history_size; j++) + { +// Old frame is equal to a new frame + if(history_frame[i] == new_history_frames[j]) + { + got_it = 1; + break; + } + } + +// Didn't find old frame in new frames + if(!got_it) + { + subtract_accum(history[i]); + history_valid[i] = 0; + no_change = 0; + } + } + } + +// If all frames are still valid, assume tweek occurred upstream and reload. + if(config.paranoid && no_change) + { + for(int i = 0; i < history_size; i++) + { + history_valid[i] = 0; + } + clear_accum(w, h, color_model); + } + + +// Add new history frames which are not in the old vector + for(int i = 0; i < history_size; i++) + { +// Find new frame in old vector + int got_it = 0; + for(int j = 0; j < history_size; j++) + { + if(history_valid[j] && history_frame[j] == new_history_frames[i]) + { + got_it = 1; + break; + } + } + +// Didn't find new frame in old vector + if(!got_it) + { +// Get first unused entry + for(int j = 0; j < history_size; j++) + { + if(!history_valid[j]) + { +// Load new frame into it + history_frame[j] = new_history_frames[i]; + history_valid[j] = 1; + read_frame(history[j], + 0, + history_frame[j], + frame_rate); + add_accum(history[j]); + break; + } + } + } } + delete [] new_history_frames; -// Cycle history - VFrame *temp = history[0]; - for(int i = 0; i < history_size - 1; i++) - history[i] = history[i + 1]; - history[history_size - 1] = temp; +// Transfer accumulation to output with division if average is desired. + transfer_accum(frame); + + + + return 0; +} -// Subtract oldest history. Add input. Divide by total frames. -#define AVERAGE_MACRO(type, components, max) \ + + + + + + + + +// Reset accumulation +#define CLEAR_ACCUM(type, components, chroma) \ { \ - for(int i = 0; i < h; i++) \ + type *row = (type*)accumulation; \ + if(chroma) \ { \ - int *accum_row = accumulation + i * w * components; \ - type *out_row = (type*)output->get_rows()[i]; \ - type *in_row = (type*)input->get_rows()[i]; \ - type *subtract_row = (type*)history[history_size - 1]->get_rows()[i]; \ - \ - for(int j = 0; j < w * components; j++) \ + for(int i = 0; i < w * h; i++) \ { \ - accum_row[j] -= subtract_row[j]; \ - accum_row[j] += in_row[j]; \ - subtract_row[j] = in_row[j]; \ - out_row[j] = accum_row[j] / history_size; \ + *row++ = 0x0; \ + *row++ = chroma; \ + *row++ = chroma; \ + if(components == 4) *row++ = 0x0; \ } \ } \ + else \ + { \ + bzero(row, w * h * sizeof(type) * components); \ + } \ } +void TimeAvgMain::clear_accum(int w, int h, int color_model) +{ + switch(color_model) + { + case BC_RGB888: + CLEAR_ACCUM(int, 3, 0x0) + break; + case BC_RGB_FLOAT: + CLEAR_ACCUM(float, 3, 0x0) + break; + case BC_RGBA8888: + CLEAR_ACCUM(int, 4, 0x0) + break; + case BC_RGBA_FLOAT: + CLEAR_ACCUM(float, 4, 0x0) + break; + case BC_YUV888: + CLEAR_ACCUM(int, 3, 0x80) + break; + case BC_YUVA8888: + CLEAR_ACCUM(int, 4, 0x80) + break; + case BC_YUV161616: + CLEAR_ACCUM(int, 3, 0x8000) + break; + case BC_YUVA16161616: + CLEAR_ACCUM(int, 4, 0x8000) + break; + } +} +#define SUBTRACT_ACCUM(type, accum_type, components, chroma) \ +{ \ + for(int i = 0; i < h; i++) \ + { \ + accum_type *accum_row = (accum_type*)accumulation + \ + i * w * components; \ + type *frame_row = (type*)frame->get_rows()[i]; \ + for(int j = 0; j < w; j++) \ + { \ + *accum_row++ -= *frame_row++; \ + *accum_row++ -= (accum_type)*frame_row++ - chroma; \ + *accum_row++ -= (accum_type)*frame_row++ - chroma; \ + if(components == 4) *accum_row++ -= *frame_row++; \ + } \ + } \ +} +void TimeAvgMain::subtract_accum(VFrame *frame) +{ + int w = frame->get_w(); + int h = frame->get_h(); - switch(input->get_color_model()) + switch(frame->get_color_model()) { case BC_RGB888: + SUBTRACT_ACCUM(unsigned char, int, 3, 0x0) + break; + case BC_RGB_FLOAT: + SUBTRACT_ACCUM(float, float, 3, 0x0) + break; + case BC_RGBA8888: + SUBTRACT_ACCUM(unsigned char, int, 4, 0x0) + break; + case BC_RGBA_FLOAT: + SUBTRACT_ACCUM(float, float, 4, 0x0) + break; case BC_YUV888: - AVERAGE_MACRO(unsigned char, 3, 0xff); + SUBTRACT_ACCUM(unsigned char, int, 3, 0x80) break; + case BC_YUVA8888: + SUBTRACT_ACCUM(unsigned char, int, 4, 0x80) + break; + case BC_YUV161616: + SUBTRACT_ACCUM(uint16_t, int, 3, 0x8000) + break; + case BC_YUVA16161616: + SUBTRACT_ACCUM(uint16_t, int, 4, 0x8000) + break; + } +} + + +#define ADD_ACCUM(type, accum_type, components, chroma) \ +{ \ + for(int i = 0; i < h; i++) \ + { \ + accum_type *accum_row = (accum_type*)accumulation + \ + i * w * components; \ + type *frame_row = (type*)frame->get_rows()[i]; \ + for(int j = 0; j < w; j++) \ + { \ + *accum_row++ += *frame_row++; \ + *accum_row++ += (accum_type)*frame_row++ - chroma; \ + *accum_row++ += (accum_type)*frame_row++ - chroma; \ + if(components == 4) *accum_row++ += *frame_row++; \ + } \ + } \ +} + +void TimeAvgMain::add_accum(VFrame *frame) +{ + int w = frame->get_w(); + int h = frame->get_h(); + + switch(frame->get_color_model()) + { + case BC_RGB888: + ADD_ACCUM(unsigned char, int, 3, 0x0) + break; + case BC_RGB_FLOAT: + ADD_ACCUM(float, float, 3, 0x0) + break; case BC_RGBA8888: + ADD_ACCUM(unsigned char, int, 4, 0x0) + break; + case BC_RGBA_FLOAT: + ADD_ACCUM(float, float, 4, 0x0) + break; + case BC_YUV888: + ADD_ACCUM(unsigned char, int, 3, 0x80) + break; case BC_YUVA8888: - AVERAGE_MACRO(unsigned char, 4, 0xff); + ADD_ACCUM(unsigned char, int, 4, 0x80) break; - - case BC_RGB161616: case BC_YUV161616: - AVERAGE_MACRO(uint16_t, 3, 0xffff); + ADD_ACCUM(uint16_t, int, 3, 0x8000) break; - - case BC_RGBA16161616: case BC_YUVA16161616: - AVERAGE_MACRO(uint16_t, 4, 0xffff); + ADD_ACCUM(uint16_t, int, 4, 0x8000) break; } +} -//printf("TimeAvgMain::process_realtime 2\n"); - return 0; +#define TRANSFER_ACCUM(type, accum_type, components, chroma, max) \ +{ \ + if(!config.accumulate) \ + { \ + accum_type denominator = history_size; \ + for(int i = 0; i < h; i++) \ + { \ + accum_type *accum_row = (accum_type*)accumulation + \ + i * w * components; \ + type *frame_row = (type*)frame->get_rows()[i]; \ + for(int j = 0; j < w; j++) \ + { \ + *frame_row++ = *accum_row++ / denominator; \ + *frame_row++ = (*accum_row++ - chroma) / denominator + chroma; \ + *frame_row++ = (*accum_row++ - chroma) / denominator + chroma; \ + if(components == 4) *frame_row++ = *accum_row++ / denominator; \ + } \ + } \ + } \ + else \ + { \ + for(int i = 0; i < h; i++) \ + { \ + accum_type *accum_row = (accum_type*)accumulation + \ + i * w * components; \ + type *frame_row = (type*)frame->get_rows()[i]; \ + for(int j = 0; j < w; j++) \ + { \ + if(sizeof(type) < 4) \ + { \ + accum_type r = *accum_row++; \ + accum_type g = *accum_row++ + chroma; \ + accum_type b = *accum_row++ + chroma; \ + *frame_row++ = CLIP(r, 0, max); \ + *frame_row++ = CLIP(g, 0, max); \ + *frame_row++ = CLIP(b, 0, max); \ + if(components == 4) \ + { \ + accum_type a = *accum_row++; \ + *frame_row++ = CLIP(a, 0, max); \ + } \ + } \ + else \ + { \ + *frame_row++ = *accum_row++; \ + *frame_row++ = *accum_row++ + chroma; \ + *frame_row++ = *accum_row++ + chroma; \ + if(components == 4) \ + { \ + *frame_row++ = *accum_row++; \ + } \ + } \ + } \ + } \ + } \ } +void TimeAvgMain::transfer_accum(VFrame *frame) +{ + int w = frame->get_w(); + int h = frame->get_h(); + + switch(frame->get_color_model()) + { + case BC_RGB888: + TRANSFER_ACCUM(unsigned char, int, 3, 0x0, 0xff) + break; + case BC_RGB_FLOAT: + TRANSFER_ACCUM(float, float, 3, 0x0, 1) + break; + case BC_RGBA8888: + TRANSFER_ACCUM(unsigned char, int, 4, 0x0, 0xff) + break; + case BC_RGBA_FLOAT: + TRANSFER_ACCUM(float, float, 4, 0x0, 1) + break; + case BC_YUV888: + TRANSFER_ACCUM(unsigned char, int, 3, 0x80, 0xff) + break; + case BC_YUVA8888: + TRANSFER_ACCUM(unsigned char, int, 4, 0x80, 0xff) + break; + case BC_YUV161616: + TRANSFER_ACCUM(uint16_t, int, 3, 0x8000, 0xffff) + break; + case BC_YUVA16161616: + TRANSFER_ACCUM(uint16_t, int, 4, 0x8000, 0xffff) + break; + } +} + int TimeAvgMain::load_defaults() { char directory[BCTEXTLEN], string[BCTEXTLEN]; // set the default directory - sprintf(directory, "%sbrightness.rc", BCASTDIR); + sprintf(directory, "%stimeavg.rc", BCASTDIR); // load the defaults defaults = new Defaults(directory); defaults->load(); config.frames = defaults->get("FRAMES", config.frames); + config.accumulate = defaults->get("ACCUMULATE", config.accumulate); + config.paranoid = defaults->get("PARANOID", config.paranoid); return 0; } int TimeAvgMain::save_defaults() { defaults->update("FRAMES", config.frames); + defaults->update("ACCUMULATE", config.accumulate); + defaults->update("PARANOID", config.paranoid); defaults->save(); return 0; } -void TimeAvgMain::load_configuration() +int TimeAvgMain::load_configuration() { KeyFrame *prev_keyframe; -//printf("BlurMain::load_configuration 1\n"); + TimeAvgConfig old_config; + old_config.copy_from(&config); prev_keyframe = get_prev_keyframe(get_source_position()); read_data(prev_keyframe); + return !old_config.equivalent(&config); } void TimeAvgMain::save_data(KeyFrame *keyframe) @@ -227,6 +581,8 @@ void TimeAvgMain::save_data(KeyFrame *keyframe) output.set_shared_string(keyframe->data, MESSAGESIZE); output.tag.set_title("TIME_AVERAGE"); output.tag.set_property("FRAMES", config.frames); + output.tag.set_property("ACCUMULATE", config.accumulate); + output.tag.set_property("PARANOID", config.paranoid); output.append_tag(); output.terminate_string(); } @@ -244,6 +600,8 @@ void TimeAvgMain::read_data(KeyFrame *keyframe) if(input.tag.title_is("TIME_AVERAGE")) { config.frames = input.tag.get_property("FRAMES", config.frames); + config.accumulate = input.tag.get_property("ACCUMULATE", config.accumulate); + config.paranoid = input.tag.get_property("PARANOID", config.paranoid); } } } @@ -253,9 +611,24 @@ void TimeAvgMain::update_gui() { if(thread) { - load_configuration(); - thread->window->lock_window(); - thread->window->total_frames->update(config.frames); - thread->window->unlock_window(); + if(load_configuration()) + { + thread->window->lock_window("TimeAvgMain::update_gui"); + thread->window->total_frames->update(config.frames); + thread->window->accum->update(config.accumulate); + thread->window->avg->update(!config.accumulate); + thread->window->paranoid->update(config.paranoid); + thread->window->unlock_window(); + } } } + + + + + + + + + + diff --git a/hvirtual/plugins/timeavg/timeavg.h b/hvirtual/plugins/timeavg/timeavg.h new file mode 100644 index 00000000..59710d80 --- /dev/null +++ b/hvirtual/plugins/timeavg/timeavg.h @@ -0,0 +1,69 @@ +#ifndef TIMEAVG_H +#define TIMEAVG_H + +class TimeAvgMain; + +#include "defaults.inc" +#include "pluginvclient.h" +#include "timeavgwindow.h" +#include "vframe.inc" + +class TimeAvgConfig +{ +public: + TimeAvgConfig(); + void copy_from(TimeAvgConfig *src); + int equivalent(TimeAvgConfig *src); + + int frames; + int accumulate; + int paranoid; +}; + + +class TimeAvgMain : public PluginVClient +{ +public: + TimeAvgMain(PluginServer *server); + ~TimeAvgMain(); + +// required for all realtime plugins + int process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate); + int is_realtime(); + char* plugin_title(); + VFrame* new_picon(); + int show_gui(); + int load_configuration(); + int set_string(); + int load_defaults(); + int save_defaults(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + void raise_window(); + void update_gui(); + void clear_accum(int w, int h, int color_model); + void subtract_accum(VFrame *frame); + void add_accum(VFrame *frame); + void transfer_accum(VFrame *frame); + + + VFrame **history; +// Frame of history in requested samplerate + int64_t *history_frame; + int *history_valid; + unsigned char *accumulation; + +// a thread for the GUI + TimeAvgThread *thread; + TimeAvgConfig config; + int history_size; +// Starting frame of history in requested framerate + int64_t history_start; + + Defaults *defaults; +}; + + +#endif diff --git a/hvirtual/plugins/timeavg/timeavgwindow.C b/hvirtual/plugins/timeavg/timeavgwindow.C index 1b574190..c63d9e76 100644 --- a/hvirtual/plugins/timeavg/timeavgwindow.C +++ b/hvirtual/plugins/timeavg/timeavgwindow.C @@ -1,12 +1,7 @@ #include "bcdisplayinfo.h" +#include "language.h" #include "timeavgwindow.h" - -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - PLUGIN_THREAD_OBJECT(TimeAvgMain, TimeAvgThread, TimeAvgWindow) @@ -18,9 +13,9 @@ TimeAvgWindow::TimeAvgWindow(TimeAvgMain *client, int x, int y) x, y, 210, - 80, + 150, 200, - 80, + 150, 0, 0, 1) @@ -38,6 +33,12 @@ int TimeAvgWindow::create_objects() add_tool(new BC_Title(x, y, _("Frames to average"))); y += 20; add_tool(total_frames = new TimeAvgSlider(client, x, y)); + y += 30; + add_tool(accum = new TimeAvgAccum(client, this, x, y)); + y += 30; + add_tool(avg = new TimeAvgAvg(client, this, x, y)); + y += 30; + add_tool(paranoid = new TimeAvgParanoid(client, x, y)); show_window(); flush(); return 0; @@ -68,3 +69,75 @@ int TimeAvgSlider::handle_event() client->send_configure_change(); return 1; } + + + + + +TimeAvgAccum::TimeAvgAccum(TimeAvgMain *client, TimeAvgWindow *gui, int x, int y) + : BC_Radial(x, + y, + client->config.accumulate, + "Accumulate") +{ + this->client = client; + this->gui = gui; +} +int TimeAvgAccum::handle_event() +{ + int result = get_value(); + client->config.accumulate = result; + gui->avg->update(0); + client->send_configure_change(); + return 1; +} + + + + + +TimeAvgAvg::TimeAvgAvg(TimeAvgMain *client, TimeAvgWindow *gui, int x, int y) + : BC_Radial(x, + y, + !client->config.accumulate, + "Average") +{ + this->client = client; + this->gui = gui; +} +int TimeAvgAvg::handle_event() +{ + int result = get_value(); + client->config.accumulate = !result; + gui->accum->update(0); + client->send_configure_change(); + return 1; +} + + + + + +TimeAvgParanoid::TimeAvgParanoid(TimeAvgMain *client, int x, int y) + : BC_CheckBox(x, + y, + client->config.paranoid, + "Reprocess frame again") +{ + this->client = client; +} +int TimeAvgParanoid::handle_event() +{ + int result = get_value(); + client->config.paranoid = result; + client->send_configure_change(); + return 1; +} + + + + + + + + diff --git a/hvirtual/plugins/timeavg/timeavgwindow.h b/hvirtual/plugins/timeavg/timeavgwindow.h new file mode 100644 index 00000000..f66160c6 --- /dev/null +++ b/hvirtual/plugins/timeavg/timeavgwindow.h @@ -0,0 +1,71 @@ +#ifndef TIMEAVGWINDOW_H +#define TIMEAVGWINDOW_H + + +class TimeAvgThread; +class TimeAvgWindow; +class TimeAvgAccum; +class TimeAvgAvg; +class TimeAvgParanoid; + +#include "guicast.h" +#include "mutex.h" +#include "timeavg.h" + +PLUGIN_THREAD_HEADER(TimeAvgMain, TimeAvgThread, TimeAvgWindow) + +class TimeAvgSlider; + +class TimeAvgWindow : public BC_Window +{ +public: + TimeAvgWindow(TimeAvgMain *client, int x, int y); + ~TimeAvgWindow(); + + int create_objects(); + int close_event(); + + TimeAvgMain *client; + TimeAvgSlider *total_frames; + TimeAvgAccum *accum; + TimeAvgAvg *avg; + TimeAvgParanoid *paranoid; +}; + +class TimeAvgSlider : public BC_ISlider +{ +public: + TimeAvgSlider(TimeAvgMain *client, int x, int y); + ~TimeAvgSlider(); + int handle_event(); + + TimeAvgMain *client; +}; + +class TimeAvgAccum : public BC_Radial +{ +public: + TimeAvgAccum(TimeAvgMain *client, TimeAvgWindow *gui, int x, int y); + int handle_event(); + TimeAvgMain *client; + TimeAvgWindow *gui; +}; + +class TimeAvgAvg : public BC_Radial +{ +public: + TimeAvgAvg(TimeAvgMain *client, TimeAvgWindow *gui, int x, int y); + int handle_event(); + TimeAvgMain *client; + TimeAvgWindow *gui; +}; + +class TimeAvgParanoid : public BC_CheckBox +{ +public: + TimeAvgParanoid(TimeAvgMain *client, int x, int y); + int handle_event(); + TimeAvgMain *client; +}; + +#endif diff --git a/hvirtual/plugins/titler/title.C b/hvirtual/plugins/titler/title.C index 58d53940..498df0de 100644 --- a/hvirtual/plugins/titler/title.C +++ b/hvirtual/plugins/titler/title.C @@ -581,6 +581,15 @@ void TitleTranslateUnit::process_package(LoadPackage *package) TRANSLATE(unsigned char, 0xff, 3, r_in, g_in, b_in); break; } + case BC_RGB_FLOAT: + { + float r, g, b; + r = (float)r_in / 0xff; + g = (float)g_in / 0xff; + b = (float)b_in / 0xff; + TRANSLATE(float, 0xff, 3, r, g, b); + break; + } case BC_YUV888: { unsigned char y, u, v; @@ -610,6 +619,15 @@ void TitleTranslateUnit::process_package(LoadPackage *package) TRANSLATE(uint16_t, 0xffff, 3, y, u, v); break; } + case BC_RGBA_FLOAT: + { + float r, g, b; + r = (float)r_in / 0xff; + g = (float)g_in / 0xff; + b = (float)b_in / 0xff; + TRANSLATE(float, 0xff, 4, r, g, b); + break; + } case BC_RGBA8888: { TRANSLATE(unsigned char, 0xff, 4, r_in, g_in, b_in); diff --git a/hvirtual/plugins/videoscope/videoscope.C b/hvirtual/plugins/videoscope/videoscope.C index 7818c2ec..8b672469 100644 --- a/hvirtual/plugins/videoscope/videoscope.C +++ b/hvirtual/plugins/videoscope/videoscope.C @@ -3,6 +3,7 @@ #include "defaults.h" #include "filexml.h" #include "guicast.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "../colors/plugincolors.h" @@ -15,12 +16,12 @@ #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) +#define FLOAT_MIN -0.1 +#define FLOAT_MAX 1.1 +#define WAVEFORM_DIVISIONS 12 +#define VECTORSCOPE_DIVISIONS 12 class VideoScopeEffect; @@ -233,8 +234,16 @@ void VideoScopeWindow::create_objects() { calculate_sizes(get_w(), get_h()); - add_subwindow(waveform = new VideoScopeWaveform(plugin, wave_x, wave_y, wave_w, wave_h)); - add_subwindow(vectorscope = new VideoScopeVectorscope(plugin, vector_x, vector_y, vector_w, vector_h)); + add_subwindow(waveform = new VideoScopeWaveform(plugin, + wave_x, + wave_y, + wave_w, + wave_h)); + add_subwindow(vectorscope = new VideoScopeVectorscope(plugin, + vector_x, + vector_y, + vector_w, + vector_h)); allocate_bitmaps(); draw_overlays(); @@ -277,33 +286,50 @@ void VideoScopeWindow::draw_overlays() set_color(GREEN); set_font(SMALLFONT); - for(int i = 0; i <= 10; i++) +// Waveform overlay + for(int i = 0; i <= WAVEFORM_DIVISIONS; i++) { - int y = wave_h * i / 10; - int text_y = y + wave_y + 10; + int y = wave_h * i / WAVEFORM_DIVISIONS; + int text_y = y + wave_y + get_text_ascent(SMALLFONT) / 2; int x = wave_x - 20; char string[BCTEXTLEN]; - sprintf(string, "%d", 100 - i * 10); + sprintf(string, "%d", + (int)((FLOAT_MAX - + i * (FLOAT_MAX - FLOAT_MIN) / WAVEFORM_DIVISIONS) * 100)); draw_text(x, text_y, string); - - if(i > 0) waveform->draw_line(0, y, wave_w, y); + + waveform->draw_line(0, + CLAMP(y, 0, waveform->get_h() - 1), + wave_w, + CLAMP(y, 0, waveform->get_h() - 1)); +//waveform->draw_rectangle(0, 0, wave_w, wave_h); } -#define DIVISIONS 5 + + +// Vectorscope overlay int radius = MIN(vector_w / 2, vector_h / 2); - for(int i = 0; i <= DIVISIONS; i++) + for(int i = 1; i <= VECTORSCOPE_DIVISIONS - 1; i += 2) { - int x = vector_w / 2 - radius * i / DIVISIONS; - int y = vector_h / 2 - radius * i / DIVISIONS; - int text_y = y + 20; - int w = radius * i / DIVISIONS * 2; - int h = radius * i / DIVISIONS * 2; + int x = vector_w / 2 - radius * i / VECTORSCOPE_DIVISIONS; + int y = vector_h / 2 - radius * i / VECTORSCOPE_DIVISIONS; + int text_x = vector_x - 20; + int text_y = y + vector_y + get_text_ascent(SMALLFONT) / 2; + int w = radius * i / VECTORSCOPE_DIVISIONS * 2; + int h = radius * i / VECTORSCOPE_DIVISIONS * 2; char string[BCTEXTLEN]; - sprintf(string, "%d", i * 100 / DIVISIONS); - draw_text(vector_x - 20, text_y, string); - if(i > 0) vectorscope->draw_circle(x, y, w, h); + sprintf(string, "%d", + (int)((FLOAT_MIN + + (FLOAT_MAX - FLOAT_MIN) / VECTORSCOPE_DIVISIONS * i) * 100)); + draw_text(text_x, text_y, string); + vectorscope->draw_circle(x, y, w, h); +//vectorscope->draw_rectangle(0, 0, vector_w, vector_h); } +// vectorscope->draw_circle(vector_w / 2 - radius, +// vector_h / 2 - radius, +// radius * 2, +// radius * 2); set_font(MEDIUMFONT); waveform->flash(); @@ -475,7 +501,13 @@ VideoScopeUnit::VideoScopeUnit(VideoScopeEffect *plugin, ((p)[2] * 29)) >> 8) -static void draw_point(unsigned char **rows, int color_model, int x, int y, int r, int g, int b) +static void draw_point(unsigned char **rows, + int color_model, + int x, + int y, + int r, + int g, + int b) { switch(color_model) { @@ -505,7 +537,7 @@ static void draw_point(unsigned char **rows, int color_model, int x, int y, int -#define VIDEOSCOPE(type, max, components, use_yuv) \ +#define VIDEOSCOPE(type, temp_type, max, components, use_yuv) \ { \ for(int i = pkg->row1; i < pkg->row2; i++) \ { \ @@ -519,16 +551,26 @@ static void draw_point(unsigned char **rows, int color_model, int x, int y, int if(use_yuv) intensity = (float)*in_pixel / max; \ \ float h, s, v; \ - int r, g, b; \ + temp_type r, g, b; \ if(use_yuv) \ { \ - if(max == 0xffff) \ + if(sizeof(type) == 2) \ { \ - yuv.yuv_to_rgb_16(r, g, b, in_pixel[0], in_pixel[1], in_pixel[2]); \ + yuv.yuv_to_rgb_16(r, \ + g, \ + b, \ + in_pixel[0], \ + in_pixel[1], \ + in_pixel[2]); \ } \ else \ { \ - yuv.yuv_to_rgb_8(r, g, b, in_pixel[0], in_pixel[1], in_pixel[2]); \ + yuv.yuv_to_rgb_8(r, \ + g, \ + b, \ + in_pixel[0], \ + in_pixel[1], \ + in_pixel[2]); \ } \ } \ else \ @@ -545,35 +587,54 @@ static void draw_point(unsigned char **rows, int color_model, int x, int y, int s, \ v); \ \ - if(max == 0xffff) \ - { \ - r >>= 8; \ - g >>= 8; \ - b >>= 8; \ - } \ - \ /* Calculate waveform */ \ if(!use_yuv) intensity = v; \ - intensity = intensity * \ + intensity = (intensity - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN) * \ waveform_h; \ int y = waveform_h - (int)intensity; \ int x = j * waveform_w / w; \ if(x >= 0 && x < waveform_w && y >= 0 && y < waveform_h) \ - draw_point(waveform_rows, waveform_cmodel, x, y, 0xff, 0xff, 0xff); \ + draw_point(waveform_rows, \ + waveform_cmodel, \ + x, \ + y, \ + 0xff, \ + 0xff, \ + 0xff); \ \ /* Calculate vectorscope */ \ float adjacent = cos(h / 360 * 2 * M_PI); \ float opposite = sin(h / 360 * 2 * M_PI); \ x = (int)(vector_w / 2 + \ - adjacent * s * radius); \ + adjacent * (s - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN) * radius); \ \ y = (int)(vector_h / 2 - \ - opposite * s * radius); \ + opposite * (s - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN) * radius); \ \ \ CLAMP(x, 0, vector_w - 1); \ CLAMP(y, 0, vector_h - 1); \ - draw_point(vector_rows, vector_cmodel, x, y, r, g, b); \ + if(sizeof(type) == 2) \ + { \ + r /= 256; \ + g /= 256; \ + b /= 256; \ + } \ + else \ + if(sizeof(type) == 4) \ + { \ + r = CLIP(r, 0, 1) * 0xff; \ + g = CLIP(g, 0, 1) * 0xff; \ + b = CLIP(b, 0, 1) * 0xff; \ + } \ + \ + draw_point(vector_rows, \ + vector_cmodel, \ + x, \ + y, \ + (int)r, \ + (int)g, \ + (int)b); \ \ } \ } \ @@ -585,8 +646,8 @@ void VideoScopeUnit::process_package(LoadPackage *package) VideoScopePackage *pkg = (VideoScopePackage*)package; int w = plugin->input->get_w(); int h = plugin->input->get_h(); - int waveform_h = window->waveform_bitmap->get_h(); - int waveform_w = window->waveform_bitmap->get_w(); + int waveform_h = window->wave_h; + int waveform_w = window->wave_w; int waveform_cmodel = window->waveform_bitmap->get_color_model(); unsigned char **waveform_rows = window->waveform_bitmap->get_row_pointers(); int vector_h = window->vector_bitmap->get_h(); @@ -598,35 +659,43 @@ void VideoScopeUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { case BC_RGB888: - VIDEOSCOPE(unsigned char, 0xff, 3, 0) + VIDEOSCOPE(unsigned char, int, 0xff, 3, 0) + break; + + case BC_RGB_FLOAT: + VIDEOSCOPE(float, float, 1, 3, 0) break; case BC_YUV888: - VIDEOSCOPE(unsigned char, 0xff, 3, 1) + VIDEOSCOPE(unsigned char, int, 0xff, 3, 1) break; case BC_RGB161616: - VIDEOSCOPE(uint16_t, 0xffff, 3, 0) + VIDEOSCOPE(uint16_t, int, 0xffff, 3, 0) break; case BC_YUV161616: - VIDEOSCOPE(uint16_t, 0xffff, 3, 1) + VIDEOSCOPE(uint16_t, int, 0xffff, 3, 1) break; case BC_RGBA8888: - VIDEOSCOPE(unsigned char, 0xff, 4, 0) + VIDEOSCOPE(unsigned char, int, 0xff, 4, 0) + break; + + case BC_RGBA_FLOAT: + VIDEOSCOPE(float, float, 1, 4, 0) break; case BC_YUVA8888: - VIDEOSCOPE(unsigned char, 0xff, 4, 1) + VIDEOSCOPE(unsigned char, int, 0xff, 4, 1) break; case BC_RGBA16161616: - VIDEOSCOPE(uint16_t, 0xffff, 4, 0) + VIDEOSCOPE(uint16_t, int, 0xffff, 4, 0) break; case BC_YUVA16161616: - VIDEOSCOPE(uint16_t, 0xffff, 4, 1) + VIDEOSCOPE(uint16_t, int, 0xffff, 4, 1) break; } } diff --git a/hvirtual/plugins/wave/wave.C b/hvirtual/plugins/wave/wave.C index 8b99deac..58e59ed9 100644 --- a/hvirtual/plugins/wave/wave.C +++ b/hvirtual/plugins/wave/wave.C @@ -4,6 +4,7 @@ #include "filexml.h" #include "guicast.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" @@ -13,10 +14,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) @@ -798,6 +795,9 @@ void WaveUnit::process_package(LoadPackage *package) case BC_RGB888: WAVE(unsigned char, 3, 0x0); break; + case BC_RGB_FLOAT: + WAVE(float, 3, 0x0); + break; case BC_YUV888: WAVE(unsigned char, 3, 0x80); break; @@ -807,6 +807,9 @@ void WaveUnit::process_package(LoadPackage *package) case BC_YUV161616: WAVE(uint16_t, 3, 0x8000); break; + case BC_RGBA_FLOAT: + WAVE(unsigned char, 4, 0x0); + break; case BC_RGBA8888: WAVE(unsigned char, 4, 0x0); break; diff --git a/hvirtual/plugins/whirl/whirl.C b/hvirtual/plugins/whirl/whirl.C index d7a9a654..a8cfe2aa 100644 --- a/hvirtual/plugins/whirl/whirl.C +++ b/hvirtual/plugins/whirl/whirl.C @@ -4,16 +4,12 @@ #include "filexml.h" #include "guicast.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - #include @@ -794,10 +790,16 @@ void WhirlUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { + case BC_RGB_FLOAT: + WHIRL_MACRO(float, 1, 3); + break; case BC_RGB888: case BC_YUV888: WHIRL_MACRO(unsigned char, 0xff, 3); break; + case BC_RGBA_FLOAT: + WHIRL_MACRO(float, 1, 4); + break; case BC_RGBA8888: case BC_YUVA8888: WHIRL_MACRO(unsigned char, 0xff, 4); diff --git a/hvirtual/plugins/wipe/wipe.C b/hvirtual/plugins/wipe/wipe.C index 187e514c..2ff054c0 100644 --- a/hvirtual/plugins/wipe/wipe.C +++ b/hvirtual/plugins/wipe/wipe.C @@ -259,10 +259,16 @@ int WipeMain::process_realtime(VFrame *incoming, VFrame *outgoing) switch(incoming->get_color_model()) { + case BC_RGB_FLOAT: + WIPE(float, 3) + break; case BC_RGB888: case BC_YUV888: WIPE(unsigned char, 3) break; + case BC_RGBA_FLOAT: + WIPE(float, 4) + break; case BC_RGBA8888: case BC_YUVA8888: WIPE(unsigned char, 4) diff --git a/hvirtual/plugins/yuv/yuv.C b/hvirtual/plugins/yuv/yuv.C index 6f0c88ab..359b5d37 100644 --- a/hvirtual/plugins/yuv/yuv.C +++ b/hvirtual/plugins/yuv/yuv.C @@ -3,6 +3,7 @@ #include "defaults.h" #include "filexml.h" #include "guicast.h" +#include "language.h" #include "picon_png.h" #include "../colors/plugincolors.h" #include "pluginvclient.h" @@ -11,11 +12,6 @@ #include #include -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - class YUVEffect; @@ -288,52 +284,72 @@ void YUVEffect::read_data(KeyFrame *keyframe) static YUV yuv_static; -#define YUV_MACRO(type, max, components, use_yuv) \ +#define YUV_MACRO(type, temp_type, max, components, use_yuv) \ { \ for(int i = 0; i < input->get_h(); i++) \ { \ type *in_row = (type*)input->get_rows()[i]; \ type *out_row = (type*)output->get_rows()[i]; \ + const float round = (sizeof(type) == 4) ? 0.0 : 0.5; \ \ for(int j = 0; j < w; j++) \ { \ if(use_yuv) \ { \ - int y = (int)((float)in_row[0] * y_scale + 0.5); \ - int u = (int)((float)(in_row[1] - (max / 2 + 1)) * u_scale + 0.5) + (max / 2 + 1); \ - int v = (int)((float)(in_row[2] - (max / 2 + 1)) * v_scale + 0.5) + (max / 2 + 1); \ + int y = (int)((float)in_row[0] * y_scale + round); \ + int u = (int)((float)(in_row[1] - (max / 2 + 1)) * u_scale + round) + (max / 2 + 1); \ + int v = (int)((float)(in_row[2] - (max / 2 + 1)) * v_scale + round) + (max / 2 + 1); \ out_row[0] = CLIP(y, 0, max); \ out_row[1] = CLIP(u, 0, max); \ out_row[2] = CLIP(v, 0, max); \ } \ else \ { \ - int y, u, v, r, g, b; \ - if(max == 0xff) \ - yuv_static.rgb_to_yuv_8(in_row[0], in_row[1], in_row[2], y, u, v); \ + temp_type y, u, v, r, g, b; \ + if(sizeof(type) == 4) \ + { \ + yuv_static.rgb_to_yuv_f(in_row[0], in_row[1], in_row[2], y, u, v); \ + } \ else \ + if(sizeof(type) == 2) \ + { \ yuv_static.rgb_to_yuv_16(in_row[0], in_row[1], in_row[2], y, u, v); \ + } \ + else \ + { \ + yuv_static.rgb_to_yuv_8(in_row[0], in_row[1], in_row[2], y, u, v); \ + } \ \ - y = (int)((float)y * y_scale + 0.5); \ - u = (int)((float)(u - (max / 2 + 1)) * u_scale + 0.5) + (max / 2 + 1); \ - v = (int)((float)(v - (max / 2 + 1)) * v_scale + 0.5) + (max / 2 + 1); \ + if(sizeof(type) < 4) \ + { \ + CLAMP(y, 0, max); \ + CLAMP(u, 0, max); \ + CLAMP(v, 0, max); \ \ - CLAMP(y, 0, max); \ - CLAMP(u, 0, max); \ - CLAMP(v, 0, max); \ + y = temp_type((float)y * y_scale + round); \ + u = temp_type((float)(u - (max / 2 + 1)) * u_scale + round) + (max / 2 + 1); \ + v = temp_type((float)(v - (max / 2 + 1)) * v_scale + round) + (max / 2 + 1); \ + } \ + else \ + { \ + y = temp_type((float)y * y_scale + round); \ + u = temp_type((float)u * u_scale + round); \ + v = temp_type((float)v * v_scale + round); \ + } \ \ - if(max == 0xff) \ - yuv_static.yuv_to_rgb_8(r, g, b, y, u, v); \ + if(sizeof(type) == 4) \ + yuv_static.yuv_to_rgb_f(r, g, b, y, u, v); \ else \ + if(sizeof(type) == 2) \ yuv_static.yuv_to_rgb_16(r, g, b, y, u, v); \ + else \ + yuv_static.yuv_to_rgb_8(r, g, b, y, u, v); \ \ out_row[0] = r; \ out_row[1] = g; \ out_row[2] = b; \ } \ \ - if(components == 4) \ - out_row[3] = in_row[3]; \ in_row += components; \ out_row += components; \ } \ @@ -362,36 +378,44 @@ int YUVEffect::process_realtime(VFrame *input, VFrame *output) switch(input->get_color_model()) { + case BC_RGB_FLOAT: + YUV_MACRO(float, float, 1, 3, 0) + break; + case BC_RGB888: - YUV_MACRO(unsigned char, 0xff, 3, 0) + YUV_MACRO(unsigned char, int, 0xff, 3, 0) break; case BC_YUV888: - YUV_MACRO(unsigned char, 0xff, 3, 1) + YUV_MACRO(unsigned char, int, 0xff, 3, 1) break; case BC_RGB161616: - YUV_MACRO(uint16_t, 0xffff, 3, 0) + YUV_MACRO(uint16_t, int, 0xffff, 3, 0) break; case BC_YUV161616: - YUV_MACRO(uint16_t, 0xffff, 3, 1) + YUV_MACRO(uint16_t, int, 0xffff, 3, 1) + break; + + case BC_RGBA_FLOAT: + YUV_MACRO(float, float, 1, 4, 0) break; case BC_RGBA8888: - YUV_MACRO(unsigned char, 0xff, 4, 0) + YUV_MACRO(unsigned char, int, 0xff, 4, 0) break; case BC_YUVA8888: - YUV_MACRO(unsigned char, 0xff, 4, 1) + YUV_MACRO(unsigned char, int, 0xff, 4, 1) break; case BC_RGBA16161616: - YUV_MACRO(uint16_t, 0xffff, 4, 0) + YUV_MACRO(uint16_t, int, 0xffff, 4, 0) break; case BC_YUVA16161616: - YUV_MACRO(uint16_t, 0xffff, 4, 1) + YUV_MACRO(uint16_t, int, 0xffff, 4, 1) break; } diff --git a/hvirtual/plugins/zoomblur/zoomblur.C b/hvirtual/plugins/zoomblur/zoomblur.C index 8d9e00e6..afbad161 100644 --- a/hvirtual/plugins/zoomblur/zoomblur.C +++ b/hvirtual/plugins/zoomblur/zoomblur.C @@ -7,15 +7,12 @@ #include "defaults.h" #include "filexml.h" #include "keyframe.h" +#include "language.h" #include "loadbalance.h" #include "picon_png.h" #include "pluginvclient.h" #include "vframe.h" -#include -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) class ZoomBlurMain; @@ -119,7 +116,7 @@ public: int **scale_x_table; int table_entries; int need_reconfigure; - int *accum; + unsigned char *accum; }; class ZoomBlurPackage : public LoadPackage @@ -421,9 +418,10 @@ int ZoomBlurMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) if(!engine) engine = new ZoomBlurEngine(this, get_project_smp() + 1, get_project_smp() + 1); - if(!accum) accum = new int[input_ptr->get_w() * + if(!accum) accum = new unsigned char[input_ptr->get_w() * input_ptr->get_h() * - cmodel_components(input_ptr->get_color_model())]; + cmodel_components(input_ptr->get_color_model()) * + MAX(sizeof(int), sizeof(float))]; this->input = input_ptr; this->output = output_ptr; @@ -531,7 +529,7 @@ int ZoomBlurMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr) bzero(accum, input_ptr->get_w() * input_ptr->get_h() * cmodel_components(input_ptr->get_color_model()) * - sizeof(int)); + MAX(sizeof(int), sizeof(float))); engine->process_packages(); return 0; } @@ -665,12 +663,12 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, } -#define BLEND_LAYER(COMPONENTS, TYPE, MAX, DO_YUV) \ +#define BLEND_LAYER(COMPONENTS, TYPE, TEMP_TYPE, MAX, DO_YUV) \ { \ const int chroma_offset = (DO_YUV ? ((MAX + 1) / 2) : 0); \ for(int j = pkg->y1; j < pkg->y2; j++) \ { \ - int *out_row = plugin->accum + COMPONENTS * w * j; \ + TEMP_TYPE *out_row = (TEMP_TYPE*)plugin->accum + COMPONENTS * w * j; \ int in_y = y_table[j]; \ \ /* Blend image */ \ @@ -692,8 +690,8 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, } \ else \ { \ - *out_row++ += (int)in_row[in_offset + 1]; \ - *out_row++ += (int)in_row[in_offset + 2]; \ + *out_row++ += (TEMP_TYPE)in_row[in_offset + 1]; \ + *out_row++ += (TEMP_TYPE)in_row[in_offset + 2]; \ } \ if(COMPONENTS == 4) \ *out_row++ += in_row[in_offset + 3]; \ @@ -733,14 +731,14 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, { \ for(int j = pkg->y1; j < pkg->y2; j++) \ { \ - int *in_row = plugin->accum + COMPONENTS * w * j; \ + TEMP_TYPE *in_row = (TEMP_TYPE*)plugin->accum + COMPONENTS * w * j; \ TYPE *in_backup = (TYPE*)plugin->input->get_rows()[j]; \ TYPE *out_row = (TYPE*)plugin->output->get_rows()[j]; \ for(int k = 0; k < w; k++) \ { \ if(do_r) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -753,7 +751,7 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, { \ if(do_g) \ { \ - *out_row++ = ((*in_row++ * fraction) >> 16); \ + *out_row++ = ((*in_row++ * fraction) / 0x10000); \ in_backup++; \ } \ else \ @@ -764,7 +762,7 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, \ if(do_b) \ { \ - *out_row++ = ((*in_row++ * fraction) >> 16); \ + *out_row++ = ((*in_row++ * fraction) / 0x10000); \ in_backup++; \ } \ else \ @@ -777,7 +775,7 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, { \ if(do_g) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -788,7 +786,7 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, \ if(do_b) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -802,7 +800,7 @@ ZoomBlurUnit::ZoomBlurUnit(ZoomBlurEngine *server, { \ if(do_a) \ { \ - *out_row++ = (*in_row++ * fraction) >> 16; \ + *out_row++ = (*in_row++ * fraction) / 0x10000; \ in_backup++; \ } \ else \ @@ -835,28 +833,34 @@ void ZoomBlurUnit::process_package(LoadPackage *package) switch(plugin->input->get_color_model()) { case BC_RGB888: - BLEND_LAYER(3, uint8_t, 0xff, 0) + BLEND_LAYER(3, uint8_t, int, 0xff, 0) + break; + case BC_RGB_FLOAT: + BLEND_LAYER(3, float, float, 1, 0) + break; + case BC_RGBA_FLOAT: + BLEND_LAYER(4, float, float, 1, 0) break; case BC_RGBA8888: - BLEND_LAYER(4, uint8_t, 0xff, 0) + BLEND_LAYER(4, uint8_t, int, 0xff, 0) break; case BC_RGB161616: - BLEND_LAYER(3, uint16_t, 0xffff, 0) + BLEND_LAYER(3, uint16_t, int, 0xffff, 0) break; case BC_RGBA16161616: - BLEND_LAYER(4, uint16_t, 0xffff, 0) + BLEND_LAYER(4, uint16_t, int, 0xffff, 0) break; case BC_YUV888: - BLEND_LAYER(3, uint8_t, 0xff, 1) + BLEND_LAYER(3, uint8_t, int, 0xff, 1) break; case BC_YUVA8888: - BLEND_LAYER(4, uint8_t, 0xff, 1) + BLEND_LAYER(4, uint8_t, int, 0xff, 1) break; case BC_YUV161616: - BLEND_LAYER(3, uint16_t, 0xffff, 1) + BLEND_LAYER(3, uint16_t, int, 0xffff, 1) break; case BC_YUVA16161616: - BLEND_LAYER(4, uint16_t, 0xffff, 1) + BLEND_LAYER(4, uint16_t, int, 0xffff, 1) break; } } diff --git a/hvirtual/quicktime/cmodel_default.c b/hvirtual/quicktime/cmodel_default.c new file mode 100644 index 00000000..5468abed --- /dev/null +++ b/hvirtual/quicktime/cmodel_default.c @@ -0,0 +1,1958 @@ +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ +#include "cmodel_permutation.h" + + + + + + + + + +// ********************************* YUV101010 -> ***************************** + +#define READ_YUV101010 \ + uint64_t y, u, v; \ + uint32_t input_i = input[0] | \ + (input[1] << 8) | \ + (input[2] << 16) | \ + (input[3] << 24); \ + \ + y = ((input_i & 0xffc00000) >> 16) | 0x3f; \ + u = ((input_i & 0x3ff000) >> 6) | 0x3f; \ + v = ((input_i & 0xffc) << 4) | 0x3f; + + + + + + +static inline void transfer_YUV101010_to_RGB8(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = (unsigned char)(((input[0] & 0xc000) >> 8) + + ((input[1] & 0xe000) >> 10) + + ((input[2] & 0xe000) >> 13)); +} + +static inline void transfer_YUV101010_to_BGR565(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(uint16_t*)(*output) = (b & 0xf800) | + ((g & 0xfc00) >> 5) | + ((r & 0xf800) >> 11); + (*output) += 2; +} + +static inline void transfer_YUV101010_to_RGB565(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(uint16_t*)(*output) = (r & 0xf800) | + ((g & 0xfc00) >> 5) | + ((b & 0xf800) >> 11); + (*output) += 2; +} + +static inline void transfer_YUV101010_to_BGR888(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = b >> 8; + *(*output)++ = g >> 8; + *(*output)++ = r >> 8; +} + +static inline void transfer_YUV101010_to_BGR8888(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = b >> 8; + *(*output)++ = g >> 8; + *(*output)++ = r >> 8; + (*output)++; +} + +static inline void transfer_YUV101010_to_YUV888(unsigned char *(*output), unsigned char *input) +{ + READ_YUV101010 + + *(*output)++ = y >> 8; + *(*output)++ = u >> 8; + *(*output)++ = v >> 8; +} + +static inline void transfer_YUV101010_to_YUVA8888(unsigned char *(*output), unsigned char *input) +{ + READ_YUV101010 + + *(*output)++ = y >> 8; + *(*output)++ = u >> 8; + *(*output)++ = v >> 8; + *(*output)++ = 0xff; +} + +static inline void transfer_YUV101010_to_YUV161616(uint16_t *(*output), unsigned char *input) +{ + READ_YUV101010 + + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; +} + +static inline void transfer_YUV101010_to_YUVA16161616(uint16_t *(*output), unsigned char *input) +{ + READ_YUV101010 + + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; + *(*output)++ = 0xffff; +} + +static inline void transfer_YUV101010_to_RGB888(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = r >> 8; + *(*output)++ = g >> 8; + *(*output)++ = b >> 8; +} + +static inline void transfer_YUV101010_to_RGBA8888(unsigned char *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = r >> 8; + *(*output)++ = g >> 8; + *(*output)++ = b >> 8; + *(*output)++ = 0xff; +} + +static inline void transfer_YUV101010_to_RGB161616(uint16_t *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_YUV101010_to_RGBA16161616(uint16_t *(*output), unsigned char *input) +{ + int r, g, b; + + READ_YUV101010 + + y = (y << 8) | (y >> 8); + + YUV_TO_RGB16(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 0xffff; +} + + + + +static inline void transfer_YUV101010_to_RGB_FLOAT(float *(*output), + unsigned char *input) +{ + float r, g, b; + float y_f; + + READ_YUV101010 + + y_f = (float)y / 0xffff; + + YUV16_TO_RGB_FLOAT(y_f, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_YUV101010_to_RGBA_FLOAT(float *(*output), + unsigned char *input) +{ + float r, g, b; + float y_f; + + READ_YUV101010 + + y_f = (float)y / 0xffff; + + YUV16_TO_RGB_FLOAT(y_f, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 1.0; +} + + + + + + + + + + + + + + + + + + + +// ******************************** VYU888 -> ********************************* + + +static inline void transfer_VYU888_to_RGB8(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + + *(*output) = (unsigned char)((r & 0xc0) + + ((g & 0xe0) >> 2) + + ((b & 0xe0) >> 5)); + (*output)++; +} + +static inline void transfer_VYU888_to_BGR565(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + *(uint16_t*)(*output) = ((b & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((r & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_VYU888_to_RGB565(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + *(uint16_t*)(*output) = ((r & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((b & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_VYU888_to_BGR888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + + (*output)[2] = r; + (*output)[1] = g; + (*output)[0] = b; + (*output) += 3; +} + +static inline void transfer_VYU888_to_BGR8888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + (*output)[2] = r; + (*output)[1] = g; + (*output)[0] = b; + (*output) += 4; +} + + +static inline void transfer_VYU888_to_RGB888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_VYU888_to_RGBA8888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[2]; + v = input[0]; + YUV_TO_RGB(y, u, v, r, g, b); + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = 0xff; + (*output) += 4; +} + + +static inline void transfer_VYU888_to_RGB161616(uint16_t *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = (input[1] << 16) | (input[1] << 8) | input[1]; + u = (input[2] << 8) | input[2]; + v = (input[0] << 8) | input[0]; + YUV_TO_RGB16(y, u, v, r, g, b); + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_VYU888_to_RGBA16161616(uint16_t *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = (input[1] << 16) | (input[1] << 8) | input[1]; + u = (input[2] << 8) | input[2]; + v = (input[0] << 8) | input[0]; + YUV_TO_RGB16(y, u, v, r, g, b); + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = 0xffff; + (*output) += 3; +} + + +static inline void transfer_VYU888_to_RGB_FLOAT(float *(*output), unsigned char *input) +{ + float y; + int u, v; + float r, g, b; + + v = *input++; + y = (float)*input++ / 0xff; + u = *input; + YUV_TO_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_VYU888_to_RGBA_FLOAT(float *(*output), unsigned char *input) +{ + float y; + int u, v; + float r, g, b; + + v = *input++; + y = (float)*input++ / 0xff; + u = *input; + YUV_TO_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 1.0; +} + + +static inline void transfer_VYU888_to_YUV888(unsigned char *(*output), unsigned char *input) +{ + (*output)[0] = input[1]; + (*output)[1] = input[2]; + (*output)[2] = input[0]; + (*output) += 3; +} + +static inline void transfer_VYU888_to_YUVA8888(unsigned char *(*output), unsigned char *input) +{ + (*output)[0] = input[1]; + (*output)[1] = input[2]; + (*output)[2] = input[0]; + (*output)[3] = 0xff; + (*output) += 4; +} + + +static inline void transfer_VYU888_to_YUV161616(uint16_t *(*output), unsigned char *input) +{ + (*output)[0] = ((int)input[1]) << 8; + (*output)[1] = ((int)input[2]) << 8; + (*output)[2] = ((int)input[0]) << 8; + (*output) += 3; +} + +static inline void transfer_VYU888_to_YUVA16161616(uint16_t *(*output), unsigned char *input) +{ + (*output)[0] = ((int)input[1]) << 8; + (*output)[1] = ((int)input[2]) << 8; + (*output)[2] = ((int)input[0]) << 8; + (*output)[3] = 0xff; + (*output) += 4; +} + + + + + + + + + + + + +// ******************************** UYVA8888 -> ********************************* + + +static inline void transfer_UYVA8888_to_RGB8(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + *(*output) = (unsigned char)((r & 0xc0) + + ((g & 0xe0) >> 2) + + ((b & 0xe0) >> 5)); + (*output)++; +} + +static inline void transfer_UYVA8888_to_BGR565(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + *(uint16_t*)(*output) = ((b & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((r & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_UYVA8888_to_RGB565(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + *(uint16_t*)(*output) = ((r & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((b & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_UYVA8888_to_BGR888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + + (*output)[2] = r; + (*output)[1] = g; + (*output)[0] = b; + (*output) += 3; +} + +static inline void transfer_UYVA8888_to_BGR8888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + + (*output)[2] = r; + (*output)[1] = g; + (*output)[0] = b; + (*output) += 4; +} + + +static inline void transfer_UYVA8888_to_RGB888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_UYVA8888_to_RGBA8888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = input[0]; + v = input[2]; + YUV_TO_RGB(y, u, v, r, g, b); + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = input[3]; + (*output) += 4; +} + + +static inline void transfer_UYVA8888_to_RGB161616(uint16_t *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = (input[0] << 8) | input[0]; + v = (input[2] << 8) | input[2]; + YUV_TO_RGB16(y, u, v, r, g, b); + r = r * input[3] / 0xff; + g = g * input[3] / 0xff; + b = b * input[3] / 0xff; + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_UYVA8888_to_RGBA16161616(uint16_t *(*output), unsigned char *input) +{ + int y, u, v; + int r, g, b; + + y = ((int)input[1]) << 16; + u = (input[0] << 8) | input[0]; + v = (input[2] << 8) | input[2]; + YUV_TO_RGB16(y, u, v, r, g, b); + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = input[3] << 8; + (*output) += 4; +} + +static inline void transfer_UYVA8888_to_RGB_FLOAT(float *(*output), unsigned char *input) +{ + float y, a; + int u, v; + float r, g, b; + + u = *input++; + y = (float)*input++ / 0xff; + v = *input++; + a = (float)*input / 0xff; + YUV_TO_FLOAT(y, u, v, r, g, b); + + r = r * a; + g = g * a; + b = b * a; + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_UYVA8888_to_RGBA_FLOAT(float *(*output), unsigned char *input) +{ + float y, a; + int u, v; + float r, g, b; + + u = *input++; + y = (float)*input++ / 0xff; + v = *input++; + a = (float)*input / 0xff; + YUV_TO_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = a; +} + + +static inline void transfer_UYVA8888_to_YUV888(unsigned char *(*output), unsigned char *input) +{ + int a, anti_a; + a = input[3]; + anti_a = 0xff - a; + + (*output)[0] = (a * input[1]) / 0xff; + (*output)[1] = (a * input[0] + anti_a * 0x80) / 0xff; + (*output)[2] = (a * input[2] + anti_a * 0x80) / 0xff; + (*output) += 3; +} + +static inline void transfer_UYVA8888_to_YUVA8888(unsigned char *(*output), unsigned char *input) +{ + (*output)[0] = input[1]; + (*output)[1] = input[0]; + (*output)[2] = input[2]; + (*output)[3] = input[3]; + (*output) += 4; +} + + +static inline void transfer_UYVA8888_to_YUV161616(uint16_t *(*output), unsigned char *input) +{ + int a, anti_a; + a = input[3]; + anti_a = 0xff - a; + + (*output)[0] = a * input[1]; + (*output)[1] = a * input[0] + anti_a * 0x80; + (*output)[2] = a * input[2] + anti_a * 0x80; + (*output) += 3; +} + +static inline void transfer_UYVA8888_to_YUVA16161616(uint16_t *(*output), unsigned char *input) +{ + (*output)[0] = input[1] << 8; + (*output)[1] = input[0] << 8; + (*output)[2] = input[2] << 8; + (*output)[3] = input[3] << 8; + (*output) += 4; +} + + + + + + + + + + +#define TRANSFER_FRAME_DEFAULT(output, \ + input, \ + y_in_offset, \ + u_in_offset, \ + v_in_offset, \ + input_column) \ +{ \ + register int i, j; \ + \ + switch(in_colormodel) \ + { \ + case BC_YUV888: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_YUV101010((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_YUV888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_YUV888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_YUV888_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_YUV422((output), \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_YUV888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_VYU888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_VYU888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_UYVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV888_to_UYVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_YUVA8888: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_VYU888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_VYU888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_UYVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_UYVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_YUV101010((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_YUVA8888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_YUVA8888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_YUVA8888_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA8888_to_YUV422((output), \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_YUV161616: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_RGB8((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_BGR565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_RGB565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_BGR888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_BGR8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_RGB888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_RGBA8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_RGB_FLOAT((float**)(output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_RGBA_FLOAT((float**)(output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_YUV161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_YUV161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_YUV161616_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_YUV422((output), \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_YUV101010((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_YUVA8888((output), \ + (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_VYU888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_VYU888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_UYVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_UYVA8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV161616_to_YUV161616((uint16_t**)(output), \ + (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_YUVA16161616: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_RGB8((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_BGR565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_RGB565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_BGR888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_BGR8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_RGB888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_RGBA8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_RGB_FLOAT((float**)(output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_RGBA_FLOAT((float**)(output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_YUV101010((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_VYU888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_VYU888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_UYVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_UYVA8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_YUVA16161616((uint16_t**)(output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_YUVA16161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_YUVA16161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_YUVA16161616_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_YUVA16161616_to_YUV422((output), \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_YUV101010: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_YUV888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGB161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGBA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_YUV161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV101010_to_YUVA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_VYU888: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_YUV888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB161616: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGB161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGBA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_YUV161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_VYU888_to_YUVA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_UYVA8888: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_YUV888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB161616: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGB161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGBA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_YUV161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_UYVA8888_to_YUVA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_ARGB8888: \ + case BC_ABGR8888: \ + switch(out_colormodel) \ + { \ + case BC_ARGB8888: \ + case BC_ABGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_ARGB8888_to_ARGB8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_RGB888: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGB161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGBA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_ARGB8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_ARGB8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_ABGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_ABGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_YUV888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_YUV161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_YUVA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_YUV101010((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_RGB888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB888_to_YUV422((output), (input), j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_RGB888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_RGB888_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_RGBA8888: \ + switch(out_colormodel) \ + { \ + case BC_TRANSPARENCY: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_TRANSPARENCY((output), (input), &bit_counter); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB8: \ + if(bg_color > 0) \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB8bg((output), (input), bg_r, bg_g, bg_b); \ + TRANSFER_FRAME_TAIL \ + else \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB8((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + if(bg_color > 0) \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_BGR565bg((output), (input), bg_r, bg_g, bg_b); \ + TRANSFER_FRAME_TAIL \ + else \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_BGR565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + if(bg_color > 0) \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB565bg((output), (input), bg_r, bg_g, bg_b); \ + TRANSFER_FRAME_TAIL \ + else \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB565((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + if(bg_color > 0) \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_BGR888bg((output), (input), bg_r, bg_g, bg_b); \ + TRANSFER_FRAME_TAIL \ + else \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_BGR888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + if(bg_color > 0) \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB888bg((output), (input), bg_r, bg_g, bg_b); \ + TRANSFER_FRAME_TAIL \ + else \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGBA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGB_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_RGBA_FLOAT((float**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + if(bg_color > 0) \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_BGR8888bg((output), (input), bg_r, bg_g, bg_b); \ + TRANSFER_FRAME_TAIL \ + else \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_YUV888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_YUVA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_YUV161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_YUVA16161616((uint16_t**)(output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA8888_to_YUV101010((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_RGBA888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA888_to_YUV422((output), (input), j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_RGBA888_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_RGBA888_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_RGB161616: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_RGB8((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_BGR565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_RGB565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_BGR888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_BGR8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_RGB888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_RGBA8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_YUV888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_YUVA8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_RGB161616_to_YUV101010((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_RGB161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_RGB161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_RGB161616_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_RGBA16161616: \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_RGB8((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_BGR565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_RGB565((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_BGR888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_BGR8888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_RGB888((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_RGBA8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV101010: \ + TRANSFER_FRAME_HEAD \ + transfer_RGBA16161616_to_YUV101010((output), (uint16_t*)(input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_RGBA16161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_RGBA16161616_to_YUV420P_YUV422P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV444P: \ + TRANSFER_YUV444P_OUT_HEAD \ + transfer_RGBA16161616_to_YUV444P(output_y, \ + output_u, \ + output_v, \ + (uint16_t*)(input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_BGR8888: \ + switch(out_colormodel) \ + { \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_BGR8888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_BGR8888_to_BGR8888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + \ + case BC_BGR888: \ + switch(out_colormodel) \ + { \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_BGR888_to_RGB888((output), (input)); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ + break; \ + } \ +} + + + + +void cmodel_default(PERMUTATION_ARGS) +{ + if(scale) + { + TRANSFER_FRAME_DEFAULT(&output_row, + input_row + column_table[j] * in_pixelsize, + 0, + 0, + 0, + 0); + } + else + { + TRANSFER_FRAME_DEFAULT(&output_row, + input_row + j * in_pixelsize, + 0, + 0, + 0, + 0); + } +} diff --git a/hvirtual/quicktime/cmodel_permutation.h b/hvirtual/quicktime/cmodel_permutation.h index d5346f9f..059d5efd 100644 --- a/hvirtual/quicktime/cmodel_permutation.h +++ b/hvirtual/quicktime/cmodel_permutation.h @@ -17,37 +17,36 @@ #include "colormodels.h" #include - -#define RGB_TO_YUV(y, u, v, r, g, b) \ -{ \ - y = ((yuv_table->rtoy_tab[r] + yuv_table->gtoy_tab[g] + yuv_table->btoy_tab[b]) >> 16); \ - u = ((yuv_table->rtou_tab[r] + yuv_table->gtou_tab[g] + yuv_table->btou_tab[b]) >> 16); \ - v = ((yuv_table->rtov_tab[r] + yuv_table->gtov_tab[g] + yuv_table->btov_tab[b]) >> 16); \ - RECLIP(y, 0, 0xff); \ - RECLIP(u, 0, 0xff); \ - RECLIP(v, 0, 0xff); \ -} - +// All variables are unsigned // y -> 24 bits u, v, -> 8 bits r, g, b -> 8 bits #define YUV_TO_RGB(y, u, v, r, g, b) \ { \ (r) = ((y + yuv_table->vtor_tab[v]) >> 16); \ (g) = ((y + yuv_table->utog_tab[u] + yuv_table->vtog_tab[v]) >> 16); \ (b) = ((y + yuv_table->utob_tab[u]) >> 16); \ - RECLIP(r, 0, 0xff); \ - RECLIP(g, 0, 0xff); \ - RECLIP(b, 0, 0xff); \ + CLAMP(r, 0, 0xff); \ + CLAMP(g, 0, 0xff); \ + CLAMP(b, 0, 0xff); \ } -// r, g, b -> 16 bits -#define RGB_TO_YUV16(y, u, v, r, g, b) \ +// y -> 0 - 1 float +// u, v, -> 8 bits +// r, g, b -> float +#define YUV_TO_FLOAT(y, u, v, r, g, b) \ { \ - y = ((yuv_table->rtoy_tab16[r] + yuv_table->gtoy_tab16[g] + yuv_table->btoy_tab16[b]) >> 8); \ - u = ((yuv_table->rtou_tab16[r] + yuv_table->gtou_tab16[g] + yuv_table->btou_tab16[b]) >> 8); \ - v = ((yuv_table->rtov_tab16[r] + yuv_table->gtov_tab16[g] + yuv_table->btov_tab16[b]) >> 8); \ - RECLIP(y, 0, 0xffff); \ - RECLIP(u, 0, 0xffff); \ - RECLIP(v, 0, 0xffff); \ + (r) = y + yuv_table->vtor_float_tab[v]; \ + (g) = y + yuv_table->utog_float_tab[u] + yuv_table->vtog_float_tab[v]; \ + (b) = y + yuv_table->utob_float_tab[u]; \ +} + +// y -> 0 - 1 float +// u, v, -> 16 bits +// r, g, b -> float +#define YUV16_TO_RGB_FLOAT(y, u, v, r, g, b) \ +{ \ + (r) = y + yuv_table->v16tor_float_tab[v]; \ + (g) = y + yuv_table->u16tog_float_tab[u] + yuv_table->v16tog_float_tab[v]; \ + (b) = y + yuv_table->u16tob_float_tab[u]; \ } // y -> 24 bits u, v-> 16 bits @@ -56,12 +55,35 @@ (r) = ((y + yuv_table->vtor_tab16[v]) >> 8); \ (g) = ((y + yuv_table->utog_tab16[u] + yuv_table->vtog_tab16[v]) >> 8); \ (b) = ((y + yuv_table->utob_tab16[u]) >> 8); \ - RECLIP(r, 0, 0xffff); \ - RECLIP(g, 0, 0xffff); \ - RECLIP(b, 0, 0xffff); \ + CLAMP(r, 0, 0xffff); \ + CLAMP(g, 0, 0xffff); \ + CLAMP(b, 0, 0xffff); \ } + + +#define RGB_TO_YUV(y, u, v, r, g, b) \ +{ \ + y = ((yuv_table->rtoy_tab[r] + yuv_table->gtoy_tab[g] + yuv_table->btoy_tab[b]) >> 16); \ + u = ((yuv_table->rtou_tab[r] + yuv_table->gtou_tab[g] + yuv_table->btou_tab[b]) >> 16); \ + v = ((yuv_table->rtov_tab[r] + yuv_table->gtov_tab[g] + yuv_table->btov_tab[b]) >> 16); \ + CLAMP(y, 0, 0xff); \ + CLAMP(u, 0, 0xff); \ + CLAMP(v, 0, 0xff); \ +} + +// r, g, b -> 16 bits +#define RGB_TO_YUV16(y, u, v, r, g, b) \ +{ \ + y = ((yuv_table->rtoy_tab16[r] + yuv_table->gtoy_tab16[g] + yuv_table->btoy_tab16[b]) >> 8); \ + u = ((yuv_table->rtou_tab16[r] + yuv_table->gtou_tab16[g] + yuv_table->btou_tab16[b]) >> 8); \ + v = ((yuv_table->rtov_tab16[r] + yuv_table->gtov_tab16[g] + yuv_table->btov_tab16[b]) >> 8); \ + CLAMP(y, 0, 0xffff); \ + CLAMP(u, 0, 0xffff); \ + CLAMP(v, 0, 0xffff); \ +} + #define WRITE_YUV101010(y, u, v) \ { \ uint32_t output_i = ((y & 0xffc0) << 16) | \ @@ -172,27 +194,24 @@ static inline void transfer_RGB888_to_RGB565(unsigned char *(*output), unsigned static inline void transfer_RGB888_to_BGR888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[2]; - (*output)[1] = input[1]; - (*output)[2] = input[0]; - (*output) += 3; + *(*output)++ = input[2]; + *(*output)++ = input[1]; + *(*output)++ = input[0]; } static inline void transfer_RGB888_to_RGB888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[0]; - (*output)[1] = input[1]; - (*output)[2] = input[2]; - (*output) += 3; + *(*output)++ = *input++; + *(*output)++ = *input++; + *(*output)++ = *input; } static inline void transfer_RGB888_to_RGBA8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[0]; - (*output)[1] = input[1]; - (*output)[2] = input[2]; - (*output)[3] = 0xff; - (*output) += 4; + *(*output)++ = *input++; + *(*output)++ = *input++; + *(*output)++ = *input; + *(*output)++ = 0xff; } static inline void transfer_RGB888_to_RGB161616(uint16_t *(*output), unsigned char *input) @@ -212,30 +231,43 @@ static inline void transfer_RGB888_to_RGBA16161616(uint16_t *(*output), unsigned (*output) += 4; } +static inline void transfer_RGB888_to_RGB_FLOAT(float *(*output), unsigned char *input) +{ + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input / 0xff; +} + +static inline void transfer_RGB888_to_RGBA_FLOAT(float *(*output), unsigned char *input) +{ + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input / 0xff; + *(*output)++ = 1.0; +} + static inline void transfer_RGB888_to_ARGB8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = 0xff; - (*output)[1] = input[0]; - (*output)[2] = input[1]; - (*output)[3] = input[2]; - (*output) += 4; + *(*output)++ = 0xff; + *(*output)++ = input[0]; + *(*output)++ = input[1]; + *(*output)++ = input[2]; } static inline void transfer_RGB888_to_ABGR8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = 0xff; - (*output)[1] = input[2]; - (*output)[2] = input[1]; - (*output)[3] = input[0]; - (*output) += 4; + *(*output)++ = 0xff; + *(*output)++ = input[2]; + *(*output)++ = input[1]; + *(*output)++ = input[0]; } static inline void transfer_RGB888_to_BGR8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[2]; - (*output)[1] = input[1]; - (*output)[2] = input[0]; - (*output) += 4; + *(*output)++ = input[2]; + *(*output)++ = input[1]; + *(*output)++ = input[0]; + (*output)++; } static inline void transfer_RGB888_to_YUV888(unsigned char *(*output), unsigned char *input) @@ -244,10 +276,9 @@ static inline void transfer_RGB888_to_YUV888(unsigned char *(*output), unsigned RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output) += 3; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; } @@ -269,10 +300,9 @@ static inline void transfer_RGB888_to_VYU888(unsigned char *(*output), unsigned RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = v; - (*output)[1] = y; - (*output)[2] = u; - (*output) += 3; + *(*output)++ = v; + *(*output)++ = y; + *(*output)++ = u; } static inline void transfer_RGB888_to_UYVA8888(unsigned char *(*output), unsigned char *input) @@ -281,11 +311,10 @@ static inline void transfer_RGB888_to_UYVA8888(unsigned char *(*output), unsigne RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = u; - (*output)[1] = y; - (*output)[2] = v; - (*output)[3] = 0xff; - (*output) += 4; + *(*output)++ = u; + *(*output)++ = y; + *(*output)++ = v; + *(*output)++ = 0xff; } @@ -296,11 +325,10 @@ static inline void transfer_RGB888_to_YUVA8888(unsigned char *(*output), unsigne RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output)[3] = 255; - (*output) += 4; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; + *(*output)++ = 255; } static inline void transfer_RGB888_to_YUV161616(uint16_t *(*output), unsigned char *input) @@ -313,10 +341,9 @@ static inline void transfer_RGB888_to_YUV161616(uint16_t *(*output), unsigned ch RGB_TO_YUV16(y, u, v, r, g, b); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output) += 3; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; } static inline void transfer_RGB888_to_YUVA16161616(uint16_t *(*output), unsigned char *input) @@ -328,11 +355,10 @@ static inline void transfer_RGB888_to_YUVA16161616(uint16_t *(*output), unsigned b = (((int)input[2]) << 8) | input[2]; RGB_TO_YUV16(y, u, v, r, g, b); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output)[3] = 0xffff; - (*output) += 4; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; + *(*output)++ = 0xffff; } static inline void transfer_RGB888_to_YUV420P_YUV422P(unsigned char *output_y, @@ -468,10 +494,9 @@ static inline void transfer_RGBA8888_to_BGR888bg(unsigned char *(*output), unsig r = ((unsigned int)input[0] * a + bg_r * anti_a) / 0xff; g = ((unsigned int)input[1] * a + bg_g * anti_a) / 0xff; b = ((unsigned int)input[2] * a + bg_b * anti_a) / 0xff; - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 3; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; } static inline void transfer_RGBA8888_to_RGB888bg(unsigned char *(*output), unsigned char *input, int bg_r, int bg_g, int bg_b) @@ -482,10 +507,9 @@ static inline void transfer_RGBA8888_to_RGB888bg(unsigned char *(*output), unsig r = ((unsigned int)input[0] * a + bg_r * anti_a) / 0xff; g = ((unsigned int)input[1] * a + bg_g * anti_a) / 0xff; b = ((unsigned int)input[2] * a + bg_b * anti_a) / 0xff; - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; } static inline void transfer_RGBA8888_to_BGR8888bg(unsigned char *(*output), unsigned char *input, int bg_r, int bg_g, int bg_b) @@ -498,10 +522,10 @@ static inline void transfer_RGBA8888_to_BGR8888bg(unsigned char *(*output), unsi g = ((unsigned int)input[1] * a + bg_g * anti_a) / 0xff; b = ((unsigned int)input[2] * a + bg_b * anti_a) / 0xff; - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 4; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; + (*output)++; } @@ -560,10 +584,9 @@ static inline void transfer_RGBA8888_to_BGR888(unsigned char *(*output), unsigne r = ((unsigned int)input[0] * a) / 0xff; g = ((unsigned int)input[1] * a) / 0xff; b = ((unsigned int)input[2] * a) / 0xff; - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 3; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; } static inline void transfer_RGBA8888_to_RGB888(unsigned char *(*output), unsigned char *input) @@ -573,10 +596,9 @@ static inline void transfer_RGBA8888_to_RGB888(unsigned char *(*output), unsigne r = ((unsigned int)input[0] * a) / 0xff; g = ((unsigned int)input[1] * a) / 0xff; b = ((unsigned int)input[2] * a) / 0xff; - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; } static inline void transfer_RGBA8888_to_RGBA8888(unsigned char *(*output), unsigned char *input) @@ -610,6 +632,22 @@ static inline void transfer_RGBA8888_to_RGBA16161616(uint16_t *(*output), unsign (*output) += 4; } +static inline void transfer_RGBA8888_to_RGB_FLOAT(float *(*output), unsigned char *input) +{ + float opacity = (float)input[3]; + *(*output)++ = (float)*input++ * opacity / 0xff / 0xff; + *(*output)++ = (float)*input++ * opacity / 0xff / 0xff; + *(*output)++ = (float)*input * opacity / 0xff / 0xff; +} + +static inline void transfer_RGBA8888_to_RGBA_FLOAT(float *(*output), unsigned char *input) +{ + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input++ / 0xff; + *(*output)++ = (float)*input / 0xff; +} + static inline void transfer_RGBA8888_to_BGR8888(unsigned char *(*output), unsigned char *input) { unsigned int r, g, b, a; @@ -617,10 +655,10 @@ static inline void transfer_RGBA8888_to_BGR8888(unsigned char *(*output), unsign r = ((unsigned int)input[0] * a) / 0xff; g = ((unsigned int)input[1] * a) / 0xff; b = ((unsigned int)input[2] * a) / 0xff; - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 4; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; + (*output)++; } static inline void transfer_RGBA8888_to_YUV888(unsigned char *(*output), unsigned char *input) @@ -634,10 +672,9 @@ static inline void transfer_RGBA8888_to_YUV888(unsigned char *(*output), unsigne RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output) += 3; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; } static inline void transfer_RGBA8888_to_YUVA8888(unsigned char *(*output), unsigned char *input) @@ -646,11 +683,10 @@ static inline void transfer_RGBA8888_to_YUVA8888(unsigned char *(*output), unsig RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output)[3] = input[3]; - (*output) += 4; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; + *(*output)++ = input[3]; } static inline void transfer_RGBA8888_to_YUV161616(uint16_t *(*output), unsigned char *input) @@ -664,10 +700,9 @@ static inline void transfer_RGBA8888_to_YUV161616(uint16_t *(*output), unsigned RGB_TO_YUV16(y, u, v, r, g, b); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output) += 3; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; } static inline void transfer_RGBA8888_to_YUVA16161616(uint16_t *(*output), unsigned char *input) @@ -679,11 +714,10 @@ static inline void transfer_RGBA8888_to_YUVA16161616(uint16_t *(*output), unsign b = (((int)input[2]) << 8) | input[2]; RGB_TO_YUV16(y, u, v, r, g, b); - (*output)[0] = y; - (*output)[1] = u; - (*output)[2] = v; - (*output)[3] = (((int)input[3]) << 8) | input[3]; - (*output) += 4; + *(*output)++ = y; + *(*output)++ = u; + *(*output)++ = v; + *(*output)++ = (((int)input[3]) << 8) | input[3]; } static inline void transfer_RGBA8888_to_YUV101010(unsigned char *(*output), unsigned char *input) @@ -709,10 +743,9 @@ static inline void transfer_RGBA8888_to_VYU888(unsigned char *(*output), unsigne RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = v; - (*output)[1] = y; - (*output)[2] = u; - (*output) += 3; + *(*output)++ = v; + *(*output)++ = y; + *(*output)++ = u; } static inline void transfer_RGBA8888_to_UYVA8888(unsigned char *(*output), unsigned char *input) @@ -721,11 +754,10 @@ static inline void transfer_RGBA8888_to_UYVA8888(unsigned char *(*output), unsig RGB_TO_YUV(y, u, v, input[0], input[1], input[2]); - (*output)[0] = u; - (*output)[1] = y; - (*output)[2] = v; - (*output)[3] = input[3]; - (*output) += 4; + *(*output)++ = u; + *(*output)++ = y; + *(*output)++ = v; + *(*output)++ = input[3]; } static inline void transfer_RGBA888_to_YUV420P_YUV422P(unsigned char *output_y, @@ -1037,29 +1069,30 @@ static inline void transfer_RGBA16161616_to_RGB565(unsigned char *(*output), uin static inline void transfer_RGBA16161616_to_BGR888(unsigned char *(*output), uint16_t *input) { - unsigned int r, g, b, a; - a = (input)[3] >> 8; - r = (unsigned int)(input)[0] * a; - g = (unsigned int)(input)[1] * a; - b = (unsigned int)(input)[2] * a; - - (*output)[0] = (unsigned char)(b >> 16); - (*output)[1] = (unsigned char)(g >> 16); - (*output)[2] = (unsigned char)(r >> 16); + uint32_t r, g, b, a; + a = input[3]; + r = (uint32_t)(input)[0] * a; + g = (uint32_t)(input)[1] * a; + b = (uint32_t)(input)[2] * a; + +// For display only + (*output)[0] = (unsigned char)(b >> 24); + (*output)[1] = (unsigned char)(g >> 24); + (*output)[2] = (unsigned char)(r >> 24); (*output) += 3; } static inline void transfer_RGBA16161616_to_RGB888(unsigned char *(*output), uint16_t *input) { - unsigned int r, g, b, a; - a = (input)[3] >> 8; + uint32_t r, g, b, a; + a = input[3]; r = (unsigned int)(input)[0] * a; g = (unsigned int)(input)[1] * a; b = (unsigned int)(input)[2] * a; - (*output)[0] = (unsigned char)(r >> 16); - (*output)[1] = (unsigned char)(g >> 16); - (*output)[2] = (unsigned char)(b >> 16); + (*output)[0] = (unsigned char)(r / 0xffffff); + (*output)[1] = (unsigned char)(g / 0xffffff); + (*output)[2] = (unsigned char)(b / 0xffffff); (*output) += 3; } @@ -1076,26 +1109,27 @@ static inline void transfer_RGBA16161616_to_RGBA8888(unsigned char *(*output), u static inline void transfer_RGBA16161616_to_BGR8888(unsigned char *(*output), uint16_t *input) { - unsigned int r, g, b, a; - a = (input)[3] >> 8; + uint32_t r, g, b, a; + a = input[3]; r = (input)[0] * a; g = (input)[1] * a; b = (input)[2] * a; - (*output)[0] = (unsigned char)(b >> 16); - (*output)[1] = (unsigned char)(g >> 16); - (*output)[2] = (unsigned char)(r >> 16); +// For display only + (*output)[0] = (unsigned char)(b >> 24); + (*output)[1] = (unsigned char)(g >> 24); + (*output)[2] = (unsigned char)(r >> 24); (*output) += 4; } static inline void transfer_RGBA16161616_to_YUV101010(unsigned char *(*output), uint16_t *input) { - int r, g, b; - int y, u, v; + uint32_t r, g, b, a, y, u, v; - r = (((uint32_t)input[0] * input[3]) >> 16) + 0x1; - g = (((uint32_t)input[1] * input[3]) >> 16) + 0x1; - b = (((uint32_t)input[2] * input[3]) >> 16) + 0x1; + a = input[3]; + r = (uint32_t)input[0] * a / 0xffff; + g = (uint32_t)input[1] * a / 0xffff; + b = (uint32_t)input[2] * a / 0xffff; RGB_TO_YUV16(y, u, v, r, g, b); WRITE_YUV101010(y, u, v); } @@ -1107,12 +1141,11 @@ static inline void transfer_RGBA16161616_to_YUV420P_YUV422P(unsigned char *outpu uint16_t *input, int output_column) { - int y, u, v, r, g, b; - int64_t a; + uint32_t y, u, v, r, g, b, a; a = input[3]; - r = (int64_t)input[0] * a / 0xffffff; - g = (int64_t)input[1] * a / 0xffffff; - b = (int64_t)input[2] * a / 0xffffff; + r = (int32_t)input[0] * a / 0xffffff; + g = (int32_t)input[1] * a / 0xffffff; + b = (int32_t)input[2] * a / 0xffffff; RGB_TO_YUV(y, u, v, r, g, b); @@ -1127,12 +1160,11 @@ static inline void transfer_RGBA16161616_to_YUV444P(unsigned char *output_y, uint16_t *input, int output_column) { - int y, u, v, r, g, b; - int64_t a; + uint32_t y, u, v, r, g, b, a; a = input[3]; - r = (int64_t)input[0] * a / 0xffffff; - g = (int64_t)input[1] * a / 0xffffff; - b = (int64_t)input[2] * a / 0xffffff; + r = (int32_t)input[0] * a / 0xffffff; + g = (int32_t)input[1] * a / 0xffffff; + b = (int32_t)input[2] * a / 0xffffff; RGB_TO_YUV(y, u, v, r, g, b); @@ -1157,28 +1189,34 @@ static inline void transfer_RGBA16161616_to_YUV444P(unsigned char *output_y, + + + + + + +// ********************************** screen capture ***************************** + static inline void transfer_BGR8888_to_RGB888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[2]; - (*output)[1] = input[1]; - (*output)[2] = input[0]; - (*output) += 3; + *(*output)++ = input[2]; + *(*output)++ = input[1]; + *(*output)++ = input[0]; } static inline void transfer_BGR8888_to_BGR8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[0]; - (*output)[1] = input[1]; - (*output)[2] = input[2]; - (*output) += 4; + *(*output)++ = input[0]; + *(*output)++ = input[1]; + *(*output)++ = input[2]; + (*output)++; } static inline void transfer_BGR888_to_RGB888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[2]; - (*output)[1] = input[1]; - (*output)[2] = input[0]; - (*output) += 3; + *(*output)++ = input[2]; + *(*output)++ = input[1]; + *(*output)++ = input[0]; } @@ -1195,7 +1233,7 @@ static inline void transfer_YUV888_to_RGB8(unsigned char *(*output), unsigned ch int y, u, v; int r, g, b; - y = (input[0] << 16); + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); @@ -1211,7 +1249,7 @@ static inline void transfer_YUV888_to_BGR565(unsigned char *(*output), unsigned int y, u, v; int r, g, b; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); @@ -1226,7 +1264,7 @@ static inline void transfer_YUV888_to_RGB565(unsigned char *(*output), unsigned int y, u, v; int r, g, b; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); @@ -1241,15 +1279,14 @@ static inline void transfer_YUV888_to_BGR888(unsigned char *(*output), unsigned int y, u, v; int r, g, b; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 3; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; } static inline void transfer_YUV888_to_BGR8888(unsigned char *(*output), unsigned char *input) @@ -1257,14 +1294,14 @@ static inline void transfer_YUV888_to_BGR8888(unsigned char *(*output), unsigned int y, u, v; int r, g, b; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 4; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; + (*output)++; } static inline void transfer_YUV888_to_RGB888(unsigned char *(*output), unsigned char *input) @@ -1272,15 +1309,14 @@ static inline void transfer_YUV888_to_RGB888(unsigned char *(*output), unsigned int y, u, v; int r, g, b; - y = ((int)input[0]) << 16; - u = input[1]; - v = input[2]; + y = (input[0] << 16) | (input[0] << 8) | input[0]; + u = (int)input[1]; + v = (int)input[2]; YUV_TO_RGB(y, u, v, r, g, b); - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; } static inline void transfer_YUV888_to_RGBA8888(unsigned char *(*output), unsigned char *input) @@ -1288,27 +1324,54 @@ static inline void transfer_YUV888_to_RGBA8888(unsigned char *(*output), unsigne int y, u, v; int r, g, b; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xff; - (*output) += 4; + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 0xff; } -static inline void transfer_YUV888_to_YUVA8888(unsigned char *(*output), unsigned char *input) +static inline void transfer_YUV888_to_RGB_FLOAT(float *(*output), unsigned char *input) { - (*output)[0] = (int)input[0]; - (*output)[1] = input[1]; - (*output)[2] = input[2]; - (*output)[3] = 0xff; - (*output) += 4; + float y = (float)input[0] / 0xff; + int u = input[1]; + int v = input[2]; + float r, g, b; + + YUV_TO_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; } -static inline void transfer_YUV888_to_YUV888(unsigned char *(*output), unsigned char *input) +static inline void transfer_YUV888_to_RGBA_FLOAT(float *(*output), unsigned char *input) +{ + float y = (float)input[0] / 0xff; + int u = input[1]; + int v = input[2]; + float r, g, b; + + YUV_TO_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 1.0; +} + +static inline void transfer_YUV888_to_YUVA8888(unsigned char *(*output), unsigned char *input) +{ + *(*output)++ = (int)input[0]; + *(*output)++ = input[1]; + *(*output)++ = input[2]; + *(*output)++ = 0xff; +} + +static inline void transfer_YUV888_to_YUV888(unsigned char *(*output), unsigned char *input) { (*output)[0] = (int)input[0]; (*output)[1] = input[1]; @@ -1401,7 +1464,7 @@ static inline void transfer_YUVA8888_to_RGB8(unsigned char *(*output), unsigned int r, g, b; a = input[3]; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); @@ -1422,7 +1485,7 @@ static inline void transfer_YUVA8888_to_BGR565(unsigned char *(*output), unsigne int r, g, b; a = input[3]; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); @@ -1443,7 +1506,7 @@ static inline void transfer_YUVA8888_to_RGB565(unsigned char *(*output), unsigne int r, g, b; a = input[3]; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); @@ -1464,7 +1527,7 @@ static inline void transfer_YUVA8888_to_BGR888(unsigned char *(*output), unsigne int r, g, b; a = input[3]; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; @@ -1474,10 +1537,31 @@ static inline void transfer_YUVA8888_to_BGR888(unsigned char *(*output), unsigne g *= a; b *= a; - (*output)[0] = (b >> 8) + 1; - (*output)[1] = (g >> 8) + 1; - (*output)[2] = (r >> 8) + 1; - (*output) += 3; + *(*output)++ = b / 0xff; + *(*output)++ = g / 0xff; + *(*output)++ = r / 0xff; +} + + +static inline void transfer_YUVA8888_to_BGR8888(unsigned char *(*output), unsigned char *input) +{ + int y, u, v, a; + int r, g, b; + + a = input[3]; + y = (input[0] << 16) | (input[0] << 8) | input[0]; + u = input[1]; + v = input[2]; + + YUV_TO_RGB(y, u, v, r, g, b); + + r *= a; + g *= a; + b *= a; + *(*output)++ = b / 0xff; + *(*output)++ = g / 0xff; + *(*output)++ = r / 0xff; + (*output)++; } static inline void transfer_YUVA8888_to_RGB888(unsigned char *(*output), unsigned char *input) @@ -1486,7 +1570,7 @@ static inline void transfer_YUVA8888_to_RGB888(unsigned char *(*output), unsigne int r, g, b; a = input[3]; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; @@ -1496,10 +1580,9 @@ static inline void transfer_YUVA8888_to_RGB888(unsigned char *(*output), unsigne g *= a; b *= a; - (*output)[0] = (r >> 8) + 1; - (*output)[1] = (g >> 8) + 1; - (*output)[2] = (b >> 8) + 1; - (*output) += 3; + *(*output)++ = r / 0xff; + *(*output)++ = g / 0xff; + *(*output)++ = b / 0xff; } static inline void transfer_YUVA8888_to_RGBA8888(unsigned char *(*output), unsigned char *input) @@ -1508,37 +1591,55 @@ static inline void transfer_YUVA8888_to_RGBA8888(unsigned char *(*output), unsig int r, g, b; a = input[3]; - y = ((int)input[0]) << 16; + y = (input[0] << 16) | (input[0] << 8) | input[0]; u = input[1]; v = input[2]; YUV_TO_RGB(y, u, v, r, g, b); - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = a; - (*output) += 4; + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = a; } -static inline void transfer_YUVA8888_to_BGR8888(unsigned char *(*output), unsigned char *input) +static inline void transfer_YUVA8888_to_RGB_FLOAT(float *(*output), unsigned char *input) { - int y, u, v, a; - int r, g, b; + float y, a; + int u, v; + float r, g, b; - a = input[3]; - y = ((int)input[0]) << 16; + a = (float)input[3] / 0xff; + y = (float)input[0] / 0xff; u = input[1]; v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - + YUV_TO_FLOAT(y, u, v, r, g, b); + r *= a; g *= a; b *= a; - (*output)[0] = (b >> 8) + 1; - (*output)[1] = (g >> 8) + 1; - (*output)[2] = (r >> 8) + 1; - (*output) += 4; + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_YUVA8888_to_RGBA_FLOAT(float *(*output), unsigned char *input) +{ + float y = (float)input[0] / 0xff; + int u, v; + float r, g, b, a; + + a = (float)input[3] / 0xff; + u = input[1]; + v = input[2]; + + YUV_TO_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = a; } @@ -1551,29 +1652,26 @@ static inline void transfer_YUVA8888_to_VYU888(unsigned char *(*output), unsigne u = ((uint32_t)input[1] * a + 0x80 * anti_a) / 0xff; v = ((uint32_t)input[2] * a + 0x80 * anti_a) / 0xff; - (*output)[0] = v; - (*output)[1] = y; - (*output)[2] = u; - (*output) += 3; + *(*output)++ = v; + *(*output)++ = y; + *(*output)++ = u; } static inline void transfer_YUVA8888_to_YUVA8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[0]; - (*output)[1] = input[1]; - (*output)[2] = input[2]; - (*output)[3] = input[3]; - (*output) += 4; + *(*output)++ = input[0]; + *(*output)++ = input[1]; + *(*output)++ = input[2]; + *(*output)++ = input[3]; } static inline void transfer_YUVA8888_to_UYVA8888(unsigned char *(*output), unsigned char *input) { - (*output)[0] = input[1]; - (*output)[1] = input[0]; - (*output)[2] = input[2]; - (*output)[3] = input[3]; - (*output) += 4; + *(*output)++ = input[1]; + *(*output)++ = input[0]; + *(*output)++ = input[2]; + *(*output)++ = input[3]; } static inline void transfer_YUVA8888_to_YUV101010(unsigned char *(*output), unsigned char *input) @@ -1643,206 +1741,6 @@ static inline void transfer_YUVA8888_to_YUV422(unsigned char *(*output), - -// ********************************* YUV101010 -> ***************************** - -#define READ_YUV101010 \ - uint64_t y, u, v; \ - uint32_t input_i = input[0] | \ - (input[1] << 8) | \ - (input[2] << 16) | \ - (input[3] << 24); \ - \ - y = (input_i & 0xffc00000) >> 16; \ - u = (input_i & 0x3ff000) >> 6; \ - v = (input_i & 0xffc) << 4; - -static inline void transfer_YUV101010_to_RGB8(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = (unsigned char)(((input[0] & 0xc000) >> 8) + - ((input[1] & 0xe000) >> 10) + - ((input[2] & 0xe000) >> 13)); -} - -static inline void transfer_YUV101010_to_BGR565(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(uint16_t*)(*output) = (b & 0xf800) | - ((g & 0xfc00) >> 5) | - ((r & 0xf800) >> 11); - (*output) += 2; -} - -static inline void transfer_YUV101010_to_RGB565(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(uint16_t*)(*output) = (r & 0xf800) | - ((g & 0xfc00) >> 5) | - ((b & 0xf800) >> 11); - (*output) += 2; -} - -static inline void transfer_YUV101010_to_BGR888(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = b >> 8; - *(*output)++ = g >> 8; - *(*output)++ = r >> 8; -} - -static inline void transfer_YUV101010_to_BGR8888(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = b >> 8; - *(*output)++ = g >> 8; - *(*output)++ = r >> 8; - (*output)++; -} - -static inline void transfer_YUV101010_to_YUV888(unsigned char *(*output), unsigned char *input) -{ - READ_YUV101010 - - *(*output)++ = y >> 8; - *(*output)++ = u >> 8; - *(*output)++ = v >> 8; -} - -static inline void transfer_YUV101010_to_YUVA8888(unsigned char *(*output), unsigned char *input) -{ - READ_YUV101010 - - *(*output)++ = y >> 8; - *(*output)++ = u >> 8; - *(*output)++ = v >> 8; - *(*output)++ = 0xff; -} - -static inline void transfer_YUV101010_to_YUV161616(uint16_t *(*output), unsigned char *input) -{ - READ_YUV101010 - - *(*output)++ = y; - *(*output)++ = u; - *(*output)++ = v; -} - -static inline void transfer_YUV101010_to_YUVA16161616(uint16_t *(*output), unsigned char *input) -{ - READ_YUV101010 - - *(*output)++ = y; - *(*output)++ = u; - *(*output)++ = v; - *(*output)++ = 0xffff; -} - -static inline void transfer_YUV101010_to_RGB888(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = r >> 8; - *(*output)++ = g >> 8; - *(*output)++ = b >> 8; -} - -static inline void transfer_YUV101010_to_RGBA8888(unsigned char *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = r >> 8; - *(*output)++ = g >> 8; - *(*output)++ = b >> 8; - *(*output)++ = 0xff; -} - -static inline void transfer_YUV101010_to_RGB161616(uint16_t *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = r; - *(*output)++ = g; - *(*output)++ = b; -} - -static inline void transfer_YUV101010_to_RGBA16161616(uint16_t *(*output), unsigned char *input) -{ - int r, g, b; - - READ_YUV101010 - - y = (y << 8) | (y >> 8); - - YUV_TO_RGB16(y, u, v, r, g, b); - - *(*output)++ = r; - *(*output)++ = g; - *(*output)++ = b; - *(*output)++ = 0xffff; -} - - - - - - - - - // ******************************** YUV161616 -> ****************************** @@ -1902,10 +1800,9 @@ static inline void transfer_YUV161616_to_BGR888(unsigned char *(*output), uint16 v = input[2]; YUV_TO_RGB16(y, u, v, r, g, b); - (*output)[2] = r >> 8; - (*output)[1] = g >> 8; - (*output)[0] = b >> 8; - (*output) += 3; + *(*output)++ = b >> 8; + *(*output)++ = g >> 8; + *(*output)++ = r >> 8; } static inline void transfer_YUV161616_to_RGB888(unsigned char *(*output), uint16_t *input) @@ -1918,10 +1815,9 @@ static inline void transfer_YUV161616_to_RGB888(unsigned char *(*output), uint16 v = input[2]; YUV_TO_RGB16(y, u, v, r, g, b); - (*output)[0] = r >> 8; - (*output)[1] = g >> 8; - (*output)[2] = b >> 8; - (*output) += 3; + *(*output)++ = r >> 8; + *(*output)++ = g >> 8; + *(*output)++ = b >> 8; } static inline void transfer_YUV161616_to_RGBA8888(unsigned char *(*output), uint16_t *input) @@ -1934,11 +1830,41 @@ static inline void transfer_YUV161616_to_RGBA8888(unsigned char *(*output), uint v = input[2]; YUV_TO_RGB16(y, u, v, r, g, b); - (*output)[0] = r >> 8; - (*output)[1] = g >> 8; - (*output)[2] = b >> 8; - (*output)[3] = 0xff; - (*output) += 4; + *(*output)++ = r >> 8; + *(*output)++ = g >> 8; + *(*output)++ = b >> 8; + *(*output)++ = 0xff; +} + +static inline void transfer_YUV161616_to_RGB_FLOAT(float *(*output), uint16_t *input) +{ + float y = (float)input[0] / 0xffff; + int u, v; + float r, g, b; + + u = input[1]; + v = input[2]; + YUV16_TO_RGB_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_YUV161616_to_RGBA_FLOAT(float *(*output), uint16_t *input) +{ + float y = (float)input[0] / 0xffff; + int u, v; + float r, g, b; + + u = input[1]; + v = input[2]; + YUV16_TO_RGB_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 1.0; } static inline void transfer_YUV161616_to_BGR8888(unsigned char *(*output), uint16_t *input) @@ -1950,10 +1876,10 @@ static inline void transfer_YUV161616_to_BGR8888(unsigned char *(*output), uint1 u = input[1] >> 8; v = input[2] >> 8; YUV_TO_RGB(y, u, v, r, g, b); - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 4; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; + (*output)++; } static inline void transfer_YUV161616_to_YUV161616(uint16_t *(*output), uint16_t *input) @@ -2135,10 +2061,9 @@ static inline void transfer_YUVA16161616_to_BGR888(unsigned char *(*output), uin g *= a; b *= a; - (*output)[0] = b / 0xffff00; - (*output)[1] = g / 0xffff00; - (*output)[2] = r / 0xffff00; - (*output) += 3; + *(*output)++ = b / 0xffff00; + *(*output)++ = g / 0xffff00; + *(*output)++ = r / 0xffff00; } static inline void transfer_YUVA16161616_to_RGB888(unsigned char *(*output), uint16_t *input) @@ -2160,14 +2085,13 @@ static inline void transfer_YUVA16161616_to_RGB888(unsigned char *(*output), uin g /= 0xffff00; b /= 0xffff00; - RECLIP(r, 0, 0xff); - RECLIP(g, 0, 0xff); - RECLIP(b, 0, 0xff); + CLAMP(r, 0, 0xff); + CLAMP(g, 0, 0xff); + CLAMP(b, 0, 0xff); - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; } static inline void transfer_YUVA16161616_to_RGBA8888(unsigned char *(*output), uint16_t *input) @@ -2181,14 +2105,57 @@ static inline void transfer_YUVA16161616_to_RGBA8888(unsigned char *(*output), u YUV_TO_RGB16(y, u, v, r, g, b); - (*output)[0] = (r >> 8); - (*output)[1] = (g >> 8); - (*output)[2] = (b >> 8); - (*output)[3] = input[3]; - (*output) += 4; + *(*output)++ = (r >> 8); + *(*output)++ = (g >> 8); + *(*output)++ = (b >> 8); + *(*output)++ = input[3] >> 8; +} + +static inline void transfer_YUVA16161616_to_RGB_FLOAT(float *(*output), + uint16_t *input) +{ + float y; + int u, v; + float r, g, b, a; + + y = (float)input[0] / 0xffff; + u = input[1]; + v = input[2]; + a = (float)input[3] / 0xffff; + + YUV16_TO_RGB_FLOAT(y, u, v, r, g, b); + + r *= a; + g *= a; + b *= a; + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_YUVA16161616_to_RGBA_FLOAT(float *(*output), + uint16_t *input) +{ + float y; + int u, v; + float r, g, b, a; + + y = (float)input[0] / 0xffff; + u = input[1]; + v = input[2]; + a = (float)input[3] / 0xffff; + + YUV16_TO_RGB_FLOAT(y, u, v, r, g, b); + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = a; } -static inline void transfer_YUVA16161616_to_BGR8888(unsigned char *(*output), uint16_t *input) +static inline void transfer_YUVA16161616_to_BGR8888(unsigned char *(*output), + uint16_t *input) { int y, u, v, a; int64_t r, g, b; @@ -2207,10 +2174,10 @@ static inline void transfer_YUVA16161616_to_BGR8888(unsigned char *(*output), ui g /= 0xffff; r /= 0xffff; - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 4; + *(*output)++ = b; + *(*output)++ = g; + *(*output)++ = r; + (*output)++; } @@ -2223,10 +2190,9 @@ static inline void transfer_YUVA16161616_to_VYU888(unsigned char *(*output), uin u = ((uint32_t)input[1] * a + 0x8000 * anti_a) / 0xffff00; v = ((uint32_t)input[2] * a + 0x8000 * anti_a) / 0xffff00; - (*output)[0] = v; - (*output)[1] = y; - (*output)[2] = u; - (*output) += 3; + *(*output)++ = v; + *(*output)++ = y; + *(*output)++ = u; } @@ -2324,1130 +2290,23 @@ static inline void transfer_YUVA16161616_to_YUV422(unsigned char *(*output), -// ******************************** VYU888 -> ********************************* - - -static inline void transfer_VYU888_to_RGB8(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - - *(*output) = (unsigned char)((r & 0xc0) + - ((g & 0xe0) >> 2) + - ((b & 0xe0) >> 5)); - (*output)++; -} - -static inline void transfer_VYU888_to_BGR565(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - *(uint16_t*)(*output) = ((b & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((r & 0xf8) >> 3); - (*output) += 2; -} - -static inline void transfer_VYU888_to_RGB565(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - *(uint16_t*)(*output) = ((r & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((b & 0xf8) >> 3); - (*output) += 2; -} - -static inline void transfer_VYU888_to_BGR888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 3; -} - -static inline void transfer_VYU888_to_BGR8888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 4; -} - - -static inline void transfer_VYU888_to_RGB888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} - -static inline void transfer_VYU888_to_RGBA8888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2]; - v = input[0]; - YUV_TO_RGB(y, u, v, r, g, b); - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xff; - (*output) += 4; -} - - -static inline void transfer_VYU888_to_RGB161616(uint16_t *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2] << 8; - v = input[0] << 8; - YUV_TO_RGB16(y, u, v, r, g, b); - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} - -static inline void transfer_VYU888_to_RGBA16161616(uint16_t *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[2] << 8; - v = input[0] << 8; - YUV_TO_RGB16(y, u, v, r, g, b); - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xffff; - (*output) += 3; -} - - -static inline void transfer_VYU888_to_YUV888(unsigned char *(*output), unsigned char *input) -{ - (*output)[0] = input[1]; - (*output)[1] = input[2]; - (*output)[2] = input[0]; - (*output) += 3; -} - -static inline void transfer_VYU888_to_YUVA8888(unsigned char *(*output), unsigned char *input) -{ - (*output)[0] = input[1]; - (*output)[1] = input[2]; - (*output)[2] = input[0]; - (*output)[3] = 0xff; - (*output) += 4; -} - - -static inline void transfer_VYU888_to_YUV161616(uint16_t *(*output), unsigned char *input) -{ - (*output)[0] = ((int)input[1]) << 8; - (*output)[1] = ((int)input[2]) << 8; - (*output)[2] = ((int)input[0]) << 8; - (*output) += 3; -} - -static inline void transfer_VYU888_to_YUVA16161616(uint16_t *(*output), unsigned char *input) -{ - (*output)[0] = ((int)input[1]) << 8; - (*output)[1] = ((int)input[2]) << 8; - (*output)[2] = ((int)input[0]) << 8; - (*output)[3] = 0xff; - (*output) += 4; -} - - - - - - - - - - - - - - -// ******************************** UYVA8888 -> ********************************* - - -static inline void transfer_UYVA8888_to_RGB8(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - *(*output) = (unsigned char)((r & 0xc0) + - ((g & 0xe0) >> 2) + - ((b & 0xe0) >> 5)); - (*output)++; -} -static inline void transfer_UYVA8888_to_BGR565(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - *(uint16_t*)(*output) = ((b & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((r & 0xf8) >> 3); - (*output) += 2; -} -static inline void transfer_UYVA8888_to_RGB565(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - *(uint16_t*)(*output) = ((r & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((b & 0xf8) >> 3); - (*output) += 2; -} -static inline void transfer_UYVA8888_to_BGR888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 3; -} -static inline void transfer_UYVA8888_to_BGR8888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - (*output)[2] = r; - (*output)[1] = g; - (*output)[0] = b; - (*output) += 4; -} -static inline void transfer_UYVA8888_to_RGB888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} -static inline void transfer_UYVA8888_to_RGBA8888(unsigned char *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0]; - v = input[2]; - YUV_TO_RGB(y, u, v, r, g, b); - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = input[3]; - (*output) += 4; -} -static inline void transfer_UYVA8888_to_RGB161616(uint16_t *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - - y = ((int)input[1]) << 16; - u = input[0] << 8; - v = input[2] << 8; - YUV_TO_RGB16(y, u, v, r, g, b); - r = r * input[3] / 0xff; - g = g * input[3] / 0xff; - b = b * input[3] / 0xff; - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} -static inline void transfer_UYVA8888_to_RGBA16161616(uint16_t *(*output), unsigned char *input) -{ - int y, u, v; - int r, g, b; - y = ((int)input[1]) << 16; - u = input[0] << 8; - v = input[2] << 8; - YUV_TO_RGB16(y, u, v, r, g, b); - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = input[3] << 8; - (*output) += 4; -} - - -static inline void transfer_UYVA8888_to_YUV888(unsigned char *(*output), unsigned char *input) -{ - int a, anti_a; - a = input[3]; - anti_a = 0xff - a; - - (*output)[0] = (a * input[1]) / 0xff; - (*output)[1] = (a * input[0] + anti_a * 0x80) / 0xff; - (*output)[2] = (a * input[2] + anti_a * 0x80) / 0xff; - (*output) += 3; -} - -static inline void transfer_UYVA8888_to_YUVA8888(unsigned char *(*output), unsigned char *input) -{ - (*output)[0] = input[1]; - (*output)[1] = input[0]; - (*output)[2] = input[2]; - (*output)[3] = input[3]; - (*output) += 4; -} - - -static inline void transfer_UYVA8888_to_YUV161616(uint16_t *(*output), unsigned char *input) -{ - int a, anti_a; - a = input[3]; - anti_a = 0xff - a; - - (*output)[0] = a * input[1]; - (*output)[1] = a * input[0] + anti_a * 0x80; - (*output)[2] = a * input[2] + anti_a * 0x80; - (*output) += 3; -} - -static inline void transfer_UYVA8888_to_YUVA16161616(uint16_t *(*output), unsigned char *input) -{ - (*output)[0] = input[1] << 8; - (*output)[1] = input[0] << 8; - (*output)[2] = input[2] << 8; - (*output)[3] = input[3] << 8; - (*output) += 4; -} - - - - - - - - - - - - - - - -// ******************************** YUV422P -> ******************************** - -static inline void transfer_YUV422P_to_RGB8(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - *(*output) = (unsigned char)((r & 0xc0) + - ((g & 0xe0) >> 2) + - ((b & 0xe0) >> 5)); - (*output)++; -} - -static inline void transfer_YUV422P_to_BGR565(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - *(uint16_t*)(*output) = ((b & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((r & 0xf8) >> 3); - (*output) += 2; -} - -static inline void transfer_YUV422P_to_RGB565(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - *(uint16_t*)(*output) = ((r & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((b & 0xf8) >> 3); - (*output) += 2; -} - -static inline void transfer_YUV422P_to_BGR888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 3; -} - -static inline void transfer_YUV422P_to_BGR8888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 4; -} - -static inline void transfer_YUV422P_to_RGB888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ -// Signedness is important - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} - -static inline void transfer_YUV422P_to_ARGB8888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ -// Signedness is important - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = 0xff; - (*output)[1] = r; - (*output)[2] = g; - (*output)[3] = b; - (*output) += 4; -} - -static inline void transfer_YUV422P_to_ABGR8888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ -// Signedness is important - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = 0xff; - (*output)[3] = r; - (*output)[2] = g; - (*output)[1] = b; - (*output) += 4; -} - -static inline void transfer_YUV422P_to_RGBA8888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ -// Signedness is important - int y, u, v; - int r, g, b; - - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = *input_u; - v = *input_v; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xff; - (*output) += 4; -} - -static inline void transfer_YUV422P_to_RGB161616(uint16_t *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ -// Signedness is important - int y, u, v; - int r, g, b; - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = (*input_u << 8) | *input_u; - v = (*input_v << 8) | *input_v; - YUV_TO_RGB16(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - - (*output) += 3; -} - - -static inline void transfer_YUV422P_to_RGBA16161616(uint16_t *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ -// Signedness is important - int y, u, v; - int r, g, b; - y = (*input_y << 16) | (*input_y << 8) | *input_y; - u = (*input_u << 8) | *input_u; - v = (*input_v << 8) | *input_v; - YUV_TO_RGB16(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xffff; - - (*output) += 4; -} - - - -static inline void transfer_YUV422P_to_YUV888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - (*output)[0] = *input_y; - (*output)[1] = *input_u; - (*output)[2] = *input_v; - (*output) += 3; -} - -static inline void transfer_YUV422P_to_YUV161616(uint16_t *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - (*output)[0] = (*input_y << 8) | *input_y; - (*output)[1] = (*input_u << 8) | *input_u; - (*output)[2] = (*input_v << 8) | *input_v; - (*output) += 3; -} - -static inline void transfer_YUV422P_to_YUVA8888(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - (*output)[0] = *input_y; - (*output)[1] = *input_u; - (*output)[2] = *input_v; - (*output)[3] = 0xff; - (*output) += 4; -} - -static inline void transfer_YUV422P_to_YUVA16161616(uint16_t *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v) -{ - (*output)[0] = (((uint16_t)*input_y) << 8) | *input_y; - (*output)[1] = (((uint16_t)*input_u) << 8) | *input_u; - (*output)[2] = (((uint16_t)*input_v) << 8) | *input_v; - - (*output)[3] = 0xffff; - (*output) += 4; -} - -static inline void transfer_YUV422P_to_YUV420P(unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v, - unsigned char *output_y, - unsigned char *output_u, - unsigned char *output_v, - int j) -{ - output_y[j] = *input_y; - output_u[j / 2] = *input_u; - output_v[j / 2] = *input_v; -} - -static inline void transfer_YUV422P_to_YUV444P(unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v, - unsigned char *output_y, - unsigned char *output_u, - unsigned char *output_v, - int j) -{ - output_y[j] = *input_y; - output_u[j] = *input_u; - output_v[j] = *input_v; -} - -static inline void transfer_YUV422P_to_YUV422(unsigned char *(*output), - unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v, - int j) -{ -// Store U and V for even pixels only - if(!(j & 1)) - { - (*output)[1] = *input_u; - (*output)[3] = *input_v; - (*output)[0] = *input_y; - } - else -// Store Y and advance output for odd pixels only - { - (*output)[2] = *input_y; - (*output) += 4; - } -} - - - - - - - - - - - - - - - -// ******************************** YUV444P -> ******************************** - -static inline void transfer_YUV444P_to_YUV444P(unsigned char *input_y, - unsigned char *input_u, - unsigned char *input_v, - unsigned char *output_y, - unsigned char *output_u, - unsigned char *output_v, - int j) -{ - output_y[j] = *input_y; - output_u[j] = *input_u; - output_v[j] = *input_v; -} - - - - - - - - - - -// ******************************** YUV422 -> ********************************* - -static inline void transfer_YUV422_to_RGB8(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (int)(input[0]) << 16; - else -// Odd pixel - y = (int)(input[2]) << 16; - - u = input[1]; - v = input[3]; - YUV_TO_RGB(y, u, v, r, g, b) - - *(*output) = (unsigned char)((r & 0xc0) + - ((g & 0xe0) >> 2) + - ((b & 0xe0) >> 5)); - (*output)++; -} - -static inline void transfer_YUV422_to_BGR565(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (int)(input[0]) << 16; - else -// Odd pixel - y = (int)(input[2]) << 16; - u = input[1]; - v = input[3]; - YUV_TO_RGB(y, u, v, r, g, b) - - *(uint16_t*)(*output) = ((b & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((r & 0xf8) >> 3); - (*output) += 2; -} - -static inline void transfer_YUV422_to_RGB565(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (int)(input[0]) << 16; - else -// Odd pixel - y = (int)(input[2]) << 16; - u = input[1]; - v = input[3]; - YUV_TO_RGB(y, u, v, r, g, b) - - *(uint16_t*)(*output) = ((r & 0xf8) << 8) - + ((g & 0xfc) << 3) - + ((b & 0xf8) >> 3); - (*output) += 2; -} - -static inline void transfer_YUV422_to_BGR888(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (int)(input[0]) << 16; - else -// Odd pixel - y = (int)(input[2]) << 16; - u = input[1]; - v = input[3]; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 3; -} - -static inline void transfer_YUV422_to_RGB888(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (input[0] << 16) | (input[0] << 8) | input[0]; - else -// Odd pixel - y = (input[2] << 16) | (input[2] << 8) | input[2]; - u = input[1]; - v = input[3]; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} - -static inline void transfer_YUV422_to_RGBA8888(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (input[0] << 16) | (input[0] << 8) | input[0]; - else -// Odd pixel - y = (input[2] << 16) | (input[2] << 8) | input[2]; - u = input[1]; - v = input[3]; - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xff; - (*output) += 4; -} - -static inline void transfer_YUV422_to_RGB161616(uint16_t *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (input[0] << 16) | (input[0] << 8) | input[0]; - else -// Odd pixel - y = (input[2] << 16) | (input[2] << 8) | input[2]; - u = (input[1] << 8) | input[1]; - v = (input[3] << 8) | input[3]; - YUV_TO_RGB16(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output) += 3; -} - -static inline void transfer_YUV422_to_RGBA16161616(uint16_t *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (input[0] << 16) | (input[0] << 8) | input[0]; - else -// Odd pixel - y = (input[2] << 16) | (input[2] << 8) | input[2]; - u = (input[1] << 8) | input[1]; - v = (input[3] << 8) | input[3]; - YUV_TO_RGB16(y, u, v, r, g, b) - - (*output)[0] = r; - (*output)[1] = g; - (*output)[2] = b; - (*output)[3] = 0xffff; - (*output) += 4; -} - -static inline void transfer_YUV422_to_YUV888(unsigned char *(*output), - unsigned char *input, - int column) -{ -// Even pixel - if(!(column & 1)) - (*output)[0] = input[0]; - else -// Odd pixel - (*output)[0] = input[2]; - - (*output)[1] = input[1]; - (*output)[2] = input[3]; - (*output) += 3; -} - -static inline void transfer_YUV422_to_YUVA8888(unsigned char *(*output), - unsigned char *input, - int column) -{ -// Even pixel - if(!(column & 1)) - (*output)[0] = input[0]; - else -// Odd pixel - (*output)[0] = input[2]; - - (*output)[1] = input[1]; - (*output)[2] = input[3]; - (*output)[3] = 255; - (*output) += 4; -} - -static inline void transfer_YUV422_to_YUV161616(uint16_t *(*output), - unsigned char *input, - int column) -{ -// Even pixel - if(!(column & 1)) - (*output)[0] = (input[0] << 8) | input[0]; - else -// Odd pixel - (*output)[0] = (input[2] << 8) | input[2]; - - (*output)[1] = (input[1] << 8) | input[1]; - (*output)[2] = (input[3] << 8) | input[3]; - (*output) += 3; -} - -static inline void transfer_YUV422_to_YUVA16161616(uint16_t *(*output), - unsigned char *input, - int column) -{ -// Even pixel - if(!(column & 1)) - (*output)[0] = (input[0] << 8) | input[0]; - else -// Odd pixel - (*output)[0] = (input[2] << 8) | input[2]; - - (*output)[1] = (input[1] << 8) | input[1]; - (*output)[2] = (input[3] << 8) | input[3]; - (*output)[3] = 0xffff; - (*output) += 4; -} - -static inline void transfer_YUV422_to_BGR8888(unsigned char *(*output), - unsigned char *input, - int column) -{ - int y, u, v; - int r, g, b; - -// Even pixel - if(!(column & 1)) - y = (int)(input[0]) << 16; - else -// Odd pixel - y = (int)(input[2]) << 16; - u = input[1]; - v = input[3]; - - YUV_TO_RGB(y, u, v, r, g, b) - - (*output)[0] = b; - (*output)[1] = g; - (*output)[2] = r; - (*output) += 4; -} - - -static inline void transfer_YUV422_to_YUV422P(unsigned char *output_y, - unsigned char *output_u, - unsigned char *output_v, - unsigned char *input, - int output_column) -{ -// Store U and V for even pixels only - if(!(output_column & 1)) - { - output_y[output_column] = input[0]; - output_u[output_column / 2] = input[1]; - output_v[output_column / 2] = input[3]; - } - else -// Store Y and advance output for odd pixels only - { - output_y[output_column] = input[2]; - } -} - -static inline void transfer_YUV422_to_YUV420P(unsigned char *output_y, - unsigned char *output_u, - unsigned char *output_v, - unsigned char *input, - int output_column, - int output_row) -{ -// Even column - if(!(output_column & 1)) - { - output_y[output_column] = input[0]; -// Store U and V for even columns and even rows only - if(!(output_row & 1)) - { - output_u[output_column / 2] = input[1]; - output_v[output_column / 2] = input[3]; - } - } - else -// Odd column - { - output_y[output_column] = input[2]; - } -} - -static inline void transfer_YUV422_to_YUV422(unsigned char *(*output), - unsigned char *input, - int j) -{ -// Store U and V for even pixels only - if(!(j & 1)) - { - (*output)[0] = input[0]; - (*output)[1] = input[1]; - (*output)[3] = input[3]; - } - else -// Store Y and advance output for odd pixels only - { - (*output)[2] = input[2]; - (*output) += 4; - } -} diff --git a/hvirtual/quicktime/cmodel_yuv420p.c b/hvirtual/quicktime/cmodel_yuv420p.c index a1a55afb..f99a241b 100644 --- a/hvirtual/quicktime/cmodel_yuv420p.c +++ b/hvirtual/quicktime/cmodel_yuv420p.c @@ -14,9 +14,396 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ + + + #include "cmodel_permutation.h" + + +static inline void transfer_YUV_PLANAR_to_RGB8(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + int y, u, v, r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + *(*output) = (unsigned char)((r & 0xc0) + + ((g & 0xe0) >> 2) + + ((b & 0xe0) >> 5)); + (*output)++; +} + +static inline void transfer_YUV_PLANAR_to_BGR565(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + int y, u, v; + int r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + *(uint16_t*)(*output) = ((b & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((r & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_YUV_PLANAR_to_RGB565(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + int y, u, v; + int r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + *(uint16_t*)(*output) = ((r & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((b & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_YUV_PLANAR_to_BGR888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + int y, u, v; + int r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = b; + (*output)[1] = g; + (*output)[2] = r; + (*output) += 3; +} + +static inline void transfer_YUV_PLANAR_to_BGR8888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + int y, u, v; + int r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = b; + (*output)[1] = g; + (*output)[2] = r; + (*output) += 4; +} + +static inline void transfer_YUV_PLANAR_to_RGB888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + int y, u, v, r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_YUV_PLANAR_to_ARGB8888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + int y, u, v, r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = 0xff; + (*output)[1] = r; + (*output)[2] = g; + (*output)[3] = b; + (*output) += 4; +} + +static inline void transfer_YUV_PLANAR_to_ABGR8888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + int y, u, v, r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = 0xff; + (*output)[3] = r; + (*output)[2] = g; + (*output)[1] = b; + (*output) += 4; +} + +static inline void transfer_YUV_PLANAR_to_RGBA8888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + int y, u, v; + int r, g, b; + + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = *input_u; + v = *input_v; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = 0xff; + (*output) += 4; +} + +static inline void transfer_YUV_PLANAR_to_RGB161616(uint16_t *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + int y, u, v; + int r, g, b; + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = (*input_u << 8) | *input_u; + v = (*input_v << 8) | *input_v; + YUV_TO_RGB16(y, u, v, r, g, b) + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + + (*output) += 3; +} + + +static inline void transfer_YUV_PLANAR_to_RGBA16161616(uint16_t *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + int y, u, v; + int r, g, b; + y = (*input_y << 16) | (*input_y << 8) | *input_y; + u = (*input_u << 8) | *input_u; + v = (*input_v << 8) | *input_v; + YUV_TO_RGB16(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = 0xffff; + + (*output) += 4; +} + + +static inline void transfer_YUV_PLANAR_to_RGB_FLOAT(float* *output, + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + float y = (float)*input_y / 0xff; + int u, v; + float r, g, b; + u = *input_u; + v = *input_v; + YUV_TO_FLOAT(y, u, v, r, g, b) + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + + +static inline void transfer_YUV_PLANAR_to_RGBA_FLOAT(float* *output, + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ +// Signedness is important + float y = (float)*input_y / 0xff; + int u, v; + float r, g, b; + u = *input_u; + v = *input_v; + YUV_TO_FLOAT(y, u, v, r, g, b) + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 1.0; +} + + + +static inline void transfer_YUV_PLANAR_to_YUV888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + (*output)[0] = *input_y; + (*output)[1] = *input_u; + (*output)[2] = *input_v; + (*output) += 3; +} + +static inline void transfer_YUV_PLANAR_to_YUV161616(uint16_t *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + (*output)[0] = (*input_y << 8) | *input_y; + (*output)[1] = (*input_u << 8) | *input_u; + (*output)[2] = (*input_v << 8) | *input_v; + (*output) += 3; +} + +static inline void transfer_YUV_PLANAR_to_YUVA8888(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + (*output)[0] = *input_y; + (*output)[1] = *input_u; + (*output)[2] = *input_v; + (*output)[3] = 0xff; + (*output) += 4; +} + +static inline void transfer_YUV_PLANAR_to_YUVA16161616(uint16_t *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v) +{ + (*output)[0] = (((uint16_t)*input_y) << 8) | *input_y; + (*output)[1] = (((uint16_t)*input_u) << 8) | *input_u; + (*output)[2] = (((uint16_t)*input_v) << 8) | *input_v; + + (*output)[3] = 0xffff; + (*output) += 4; +} + +static inline void transfer_YUV_PLANAR_to_YUV420P(unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v, + unsigned char *output_y, + unsigned char *output_u, + unsigned char *output_v, + int j) +{ + output_y[j] = *input_y; + output_u[j / 2] = *input_u; + output_v[j / 2] = *input_v; +} + +static inline void transfer_YUV_PLANAR_to_YUV444P(unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v, + unsigned char *output_y, + unsigned char *output_u, + unsigned char *output_v, + int j) +{ + output_y[j] = *input_y; + output_u[j] = *input_u; + output_v[j] = *input_v; +} + +static inline void transfer_YUV_PLANAR_to_YUV422(unsigned char *(*output), + unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v, + int j) +{ +// Store U and V for even pixels only + if(!(j & 1)) + { + (*output)[1] = *input_u; + (*output)[3] = *input_v; + (*output)[0] = *input_y; + } + else +// Store Y and advance output for odd pixels only + { + (*output)[2] = *input_y; + (*output) += 4; + } +} + + + + + + + + + + + + + + + +// ******************************** YUV444P -> ******************************** + +static inline void transfer_YUV444P_to_YUV444P(unsigned char *input_y, + unsigned char *input_u, + unsigned char *input_v, + unsigned char *output_y, + unsigned char *output_u, + unsigned char *output_v, + int j) +{ + output_y[j] = *input_y; + output_u[j] = *input_u; + output_v[j] = *input_v; +} + + + + #define TRANSFER_FRAME_DEFAULT(output, \ input, \ y_in_offset, \ @@ -33,7 +420,7 @@ { \ case BC_RGB8: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_RGB8((output), \ + transfer_YUV_PLANAR_to_RGB8((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -41,7 +428,7 @@ break; \ case BC_BGR565: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_BGR565((output), \ + transfer_YUV_PLANAR_to_BGR565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -49,7 +436,7 @@ break; \ case BC_RGB565: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_RGB565((output), \ + transfer_YUV_PLANAR_to_RGB565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -57,7 +444,7 @@ break; \ case BC_BGR888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_BGR888((output), \ + transfer_YUV_PLANAR_to_BGR888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -65,7 +452,7 @@ break; \ case BC_BGR8888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_BGR8888((output), \ + transfer_YUV_PLANAR_to_BGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -82,7 +469,7 @@ unsigned char *input_v = in_v_plane + row_table[i] / 2 * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -94,7 +481,7 @@ break; \ case BC_YUV422: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_YUV422((output), \ + transfer_YUV_PLANAR_to_YUV422((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ @@ -112,7 +499,7 @@ unsigned char *input_v = in_v_plane + row_table[i] / 2 * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -133,7 +520,7 @@ unsigned char *input_v = in_v_plane + row_table[i] / 2 * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV444P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV444P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -145,7 +532,7 @@ break; \ case BC_RGB888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_RGB888((output), \ + transfer_YUV_PLANAR_to_RGB888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -153,7 +540,7 @@ break; \ case BC_ARGB8888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_ARGB8888((output), \ + transfer_YUV_PLANAR_to_ARGB8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -161,7 +548,7 @@ break; \ case BC_ABGR8888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_ABGR8888((output), \ + transfer_YUV_PLANAR_to_ABGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -169,7 +556,7 @@ break; \ case BC_RGBA8888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_RGBA8888((output), \ + transfer_YUV_PLANAR_to_RGBA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -177,7 +564,7 @@ break; \ case BC_RGB161616: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_RGB161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGB161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -185,7 +572,23 @@ break; \ case BC_RGBA16161616: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_RGBA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGBA16161616((uint16_t**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_YUV420P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGB_FLOAT((float**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_YUV420P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGBA_FLOAT((float**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -193,7 +596,7 @@ break; \ case BC_YUV888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_YUV888((output), \ + transfer_YUV_PLANAR_to_YUV888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -201,7 +604,7 @@ break; \ case BC_YUVA8888: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_YUVA8888((output), \ + transfer_YUV_PLANAR_to_YUVA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -209,7 +612,7 @@ break; \ case BC_YUV161616: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_YUV161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUV161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -217,7 +620,7 @@ break; \ case BC_YUVA16161616: \ TRANSFER_YUV420P_IN_HEAD \ - transfer_YUV422P_to_YUVA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUVA16161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -231,7 +634,7 @@ { \ case BC_RGB8: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_RGB8((output), \ + transfer_YUV_PLANAR_to_RGB8((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -239,7 +642,7 @@ break; \ case BC_BGR565: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_BGR565((output), \ + transfer_YUV_PLANAR_to_BGR565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -247,7 +650,7 @@ break; \ case BC_RGB565: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_RGB565((output), \ + transfer_YUV_PLANAR_to_RGB565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -255,7 +658,7 @@ break; \ case BC_BGR888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_BGR888((output), \ + transfer_YUV_PLANAR_to_BGR888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -263,7 +666,7 @@ break; \ case BC_BGR8888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_BGR8888((output), \ + transfer_YUV_PLANAR_to_BGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -280,7 +683,7 @@ unsigned char *input_v = in_v_plane + row_table[i] / 2 * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -292,7 +695,7 @@ break; \ case BC_YUV422: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_YUV422((output), \ + transfer_YUV_PLANAR_to_YUV422((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ @@ -310,7 +713,7 @@ unsigned char *input_v = in_v_plane + row_table[i] / 2 * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -331,7 +734,7 @@ unsigned char *input_v = in_v_plane + row_table[i] / 2 * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV444P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV444P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -343,7 +746,7 @@ break; \ case BC_RGB888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_RGB888((output), \ + transfer_YUV_PLANAR_to_RGB888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -351,7 +754,7 @@ break; \ case BC_ARGB8888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_ARGB8888((output), \ + transfer_YUV_PLANAR_to_ARGB8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -359,7 +762,7 @@ break; \ case BC_ABGR8888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_ABGR8888((output), \ + transfer_YUV_PLANAR_to_ABGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -367,7 +770,7 @@ break; \ case BC_RGBA8888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_RGBA8888((output), \ + transfer_YUV_PLANAR_to_RGBA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -375,7 +778,7 @@ break; \ case BC_RGB161616: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_RGB161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGB161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -383,7 +786,23 @@ break; \ case BC_RGBA16161616: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_RGBA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGBA16161616((uint16_t**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_YUV9P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGB_FLOAT((float**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_YUV9P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGBA_FLOAT((float**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -391,7 +810,7 @@ break; \ case BC_YUV888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_YUV888((output), \ + transfer_YUV_PLANAR_to_YUV888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -399,7 +818,7 @@ break; \ case BC_YUVA8888: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_YUVA8888((output), \ + transfer_YUV_PLANAR_to_YUVA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -407,7 +826,7 @@ break; \ case BC_YUV161616: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_YUV161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUV161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -415,7 +834,7 @@ break; \ case BC_YUVA16161616: \ TRANSFER_YUV9P_IN_HEAD \ - transfer_YUV422P_to_YUVA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUVA16161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -429,7 +848,7 @@ { \ case BC_RGB8: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_RGB8((output), \ + transfer_YUV_PLANAR_to_RGB8((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -437,7 +856,7 @@ break; \ case BC_BGR565: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_BGR565((output), \ + transfer_YUV_PLANAR_to_BGR565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -445,7 +864,7 @@ break; \ case BC_RGB565: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_RGB565((output), \ + transfer_YUV_PLANAR_to_RGB565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -453,7 +872,7 @@ break; \ case BC_BGR888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_BGR888((output), \ + transfer_YUV_PLANAR_to_BGR888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -461,7 +880,7 @@ break; \ case BC_BGR8888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_BGR8888((output), \ + transfer_YUV_PLANAR_to_BGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -469,7 +888,7 @@ break; \ case BC_RGB888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_RGB888((output), \ + transfer_YUV_PLANAR_to_RGB888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -477,7 +896,7 @@ break; \ case BC_ARGB8888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_ARGB8888((output), \ + transfer_YUV_PLANAR_to_ARGB8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -485,7 +904,7 @@ break; \ case BC_ABGR8888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_ABGR8888((output), \ + transfer_YUV_PLANAR_to_ABGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -493,7 +912,7 @@ break; \ case BC_RGBA8888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_RGBA8888((output), \ + transfer_YUV_PLANAR_to_RGBA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -501,7 +920,7 @@ break; \ case BC_RGB161616: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_RGB161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGB161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -509,7 +928,23 @@ break; \ case BC_RGBA16161616: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_RGBA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGBA16161616((uint16_t**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_YUV422P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGB_FLOAT((float**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_YUV422P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGBA_FLOAT((float**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -517,7 +952,7 @@ break; \ case BC_YUV888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_YUV888((output), \ + transfer_YUV_PLANAR_to_YUV888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -525,7 +960,7 @@ break; \ case BC_YUVA8888: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_YUVA8888((output), \ + transfer_YUV_PLANAR_to_YUVA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -533,7 +968,7 @@ break; \ case BC_YUV161616: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_YUV161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUV161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -541,7 +976,7 @@ break; \ case BC_YUVA16161616: \ TRANSFER_YUV422P_IN_HEAD \ - transfer_YUV422P_to_YUVA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUVA16161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -558,7 +993,7 @@ unsigned char *input_v = in_v_plane + row_table[i] * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -570,7 +1005,7 @@ break; \ case BC_YUV422: \ TRANSFER_YUV422_IN_HEAD \ - transfer_YUV422P_to_YUV422((output), \ + transfer_YUV_PLANAR_to_YUV422((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ @@ -588,7 +1023,7 @@ unsigned char *input_v = in_v_plane + row_table[i] * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -609,7 +1044,7 @@ unsigned char *input_v = in_v_plane + row_table[i] * total_in_w / 2; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV444P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV444P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -628,7 +1063,7 @@ { \ case BC_RGB8: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_RGB8((output), \ + transfer_YUV_PLANAR_to_RGB8((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -636,7 +1071,7 @@ break; \ case BC_BGR565: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_BGR565((output), \ + transfer_YUV_PLANAR_to_BGR565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -644,7 +1079,7 @@ break; \ case BC_RGB565: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_RGB565((output), \ + transfer_YUV_PLANAR_to_RGB565((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -652,7 +1087,7 @@ break; \ case BC_BGR888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_BGR888((output), \ + transfer_YUV_PLANAR_to_BGR888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -660,7 +1095,7 @@ break; \ case BC_BGR8888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_BGR8888((output), \ + transfer_YUV_PLANAR_to_BGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -668,7 +1103,7 @@ break; \ case BC_RGB888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_RGB888((output), \ + transfer_YUV_PLANAR_to_RGB888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -676,7 +1111,7 @@ break; \ case BC_ARGB8888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_ARGB8888((output), \ + transfer_YUV_PLANAR_to_ARGB8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -684,7 +1119,7 @@ break; \ case BC_ABGR8888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_ABGR8888((output), \ + transfer_YUV_PLANAR_to_ABGR8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -692,7 +1127,7 @@ break; \ case BC_RGBA8888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_RGBA8888((output), \ + transfer_YUV_PLANAR_to_RGBA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -700,7 +1135,7 @@ break; \ case BC_RGB161616: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_RGB161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGB161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -708,7 +1143,23 @@ break; \ case BC_RGBA16161616: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_RGBA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_RGBA16161616((uint16_t**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_YUV444P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGB_FLOAT((float**)(output), \ + input_y + (y_in_offset), \ + input_u + (u_in_offset), \ + input_v + (v_in_offset)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_YUV444P_IN_HEAD \ + transfer_YUV_PLANAR_to_RGBA_FLOAT((float**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -716,7 +1167,7 @@ break; \ case BC_YUV888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_YUV888((output), \ + transfer_YUV_PLANAR_to_YUV888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -724,7 +1175,7 @@ break; \ case BC_YUVA8888: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_YUVA8888((output), \ + transfer_YUV_PLANAR_to_YUVA8888((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -732,7 +1183,7 @@ break; \ case BC_YUV161616: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_YUV161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUV161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -740,7 +1191,7 @@ break; \ case BC_YUVA16161616: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_YUVA16161616((uint16_t**)(output), \ + transfer_YUV_PLANAR_to_YUVA16161616((uint16_t**)(output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset)); \ @@ -757,7 +1208,7 @@ unsigned char *input_v = in_v_plane + row_table[i] * total_in_w; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ @@ -769,7 +1220,7 @@ break; \ case BC_YUV422: \ TRANSFER_YUV444P_IN_HEAD \ - transfer_YUV422P_to_YUV422((output), \ + transfer_YUV_PLANAR_to_YUV422((output), \ input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ @@ -787,7 +1238,7 @@ unsigned char *input_v = in_v_plane + row_table[i] * total_in_w; \ for(j = 0; j < out_w; j++) \ { \ - transfer_YUV422P_to_YUV420P(input_y + (y_in_offset), \ + transfer_YUV_PLANAR_to_YUV420P(input_y + (y_in_offset), \ input_u + (u_in_offset), \ input_v + (v_in_offset), \ output_y, \ diff --git a/hvirtual/quicktime/cmodel_yuv422.c b/hvirtual/quicktime/cmodel_yuv422.c new file mode 100644 index 00000000..6721096c --- /dev/null +++ b/hvirtual/quicktime/cmodel_yuv422.c @@ -0,0 +1,550 @@ +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + + +#include "cmodel_permutation.h" + + + +static inline void transfer_YUV422_to_RGB8(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (int)(input[0]) << 16; + else +// Odd pixel + y = (int)(input[2]) << 16; + + u = input[1]; + v = input[3]; + YUV_TO_RGB(y, u, v, r, g, b) + + *(*output) = (unsigned char)((r & 0xc0) + + ((g & 0xe0) >> 2) + + ((b & 0xe0) >> 5)); + (*output)++; +} + +static inline void transfer_YUV422_to_BGR565(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (int)(input[0]) << 16; + else +// Odd pixel + y = (int)(input[2]) << 16; + u = input[1]; + v = input[3]; + YUV_TO_RGB(y, u, v, r, g, b) + + *(uint16_t*)(*output) = ((b & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((r & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_YUV422_to_RGB565(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (int)(input[0]) << 16; + else +// Odd pixel + y = (int)(input[2]) << 16; + u = input[1]; + v = input[3]; + YUV_TO_RGB(y, u, v, r, g, b) + + *(uint16_t*)(*output) = ((r & 0xf8) << 8) + + ((g & 0xfc) << 3) + + ((b & 0xf8) >> 3); + (*output) += 2; +} + +static inline void transfer_YUV422_to_BGR888(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (int)(input[0]) << 16; + else +// Odd pixel + y = (int)(input[2]) << 16; + u = input[1]; + v = input[3]; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = b; + (*output)[1] = g; + (*output)[2] = r; + (*output) += 3; +} + +static inline void transfer_YUV422_to_RGB888(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (input[0] << 16) | (input[0] << 8) | input[0]; + else +// Odd pixel + y = (input[2] << 16) | (input[2] << 8) | input[2]; + u = input[1]; + v = input[3]; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_YUV422_to_RGBA8888(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (input[0] << 16) | (input[0] << 8) | input[0]; + else +// Odd pixel + y = (input[2] << 16) | (input[2] << 8) | input[2]; + u = input[1]; + v = input[3]; + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = 0xff; + (*output) += 4; +} + +static inline void transfer_YUV422_to_RGB161616(uint16_t *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (input[0] << 16) | (input[0] << 8) | input[0]; + else +// Odd pixel + y = (input[2] << 16) | (input[2] << 8) | input[2]; + u = (input[1] << 8) | input[1]; + v = (input[3] << 8) | input[3]; + YUV_TO_RGB16(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output) += 3; +} + +static inline void transfer_YUV422_to_RGBA16161616(uint16_t *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (input[0] << 16) | (input[0] << 8) | input[0]; + else +// Odd pixel + y = (input[2] << 16) | (input[2] << 8) | input[2]; + u = (input[1] << 8) | input[1]; + v = (input[3] << 8) | input[3]; + YUV_TO_RGB16(y, u, v, r, g, b) + + (*output)[0] = r; + (*output)[1] = g; + (*output)[2] = b; + (*output)[3] = 0xffff; + (*output) += 4; +} + +static inline void transfer_YUV422_to_RGB_FLOAT(float* *output, + unsigned char *input, + int column) +{ + float y; +// Signedness is important + int u, v; + float r, g, b; + +// Even pixel + if(!(column & 1)) + y = (float)input[0] / 0xff; + else +// Odd pixel + y = (float)input[2] / 0xff; + u = input[1]; + v = input[3]; + YUV_TO_FLOAT(y, u, v, r, g, b) + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; +} + +static inline void transfer_YUV422_to_RGBA_FLOAT(float* *output, + unsigned char *input, + int column) +{ + float y; +// Signedness is important + int u, v; + float r, g, b; + +// Even pixel + if(!(column & 1)) + y = (float)input[0]; + else +// Odd pixel + y = (float)input[2]; + u = input[1]; + v = input[3]; + YUV_TO_FLOAT(y, u, v, r, g, b) + + *(*output)++ = r; + *(*output)++ = g; + *(*output)++ = b; + *(*output)++ = 1.0; +} + +static inline void transfer_YUV422_to_YUV888(unsigned char *(*output), + unsigned char *input, + int column) +{ +// Even pixel + if(!(column & 1)) + (*output)[0] = input[0]; + else +// Odd pixel + (*output)[0] = input[2]; + + (*output)[1] = input[1]; + (*output)[2] = input[3]; + (*output) += 3; +} + +static inline void transfer_YUV422_to_YUVA8888(unsigned char *(*output), + unsigned char *input, + int column) +{ +// Even pixel + if(!(column & 1)) + (*output)[0] = input[0]; + else +// Odd pixel + (*output)[0] = input[2]; + + (*output)[1] = input[1]; + (*output)[2] = input[3]; + (*output)[3] = 255; + (*output) += 4; +} + +static inline void transfer_YUV422_to_YUV161616(uint16_t *(*output), + unsigned char *input, + int column) +{ +// Even pixel + if(!(column & 1)) + (*output)[0] = (input[0] << 8) | input[0]; + else +// Odd pixel + (*output)[0] = (input[2] << 8) | input[2]; + + (*output)[1] = (input[1] << 8) | input[1]; + (*output)[2] = (input[3] << 8) | input[3]; + (*output) += 3; +} + +static inline void transfer_YUV422_to_YUVA16161616(uint16_t *(*output), + unsigned char *input, + int column) +{ +// Even pixel + if(!(column & 1)) + (*output)[0] = (input[0] << 8) | input[0]; + else +// Odd pixel + (*output)[0] = (input[2] << 8) | input[2]; + + (*output)[1] = (input[1] << 8) | input[1]; + (*output)[2] = (input[3] << 8) | input[3]; + (*output)[3] = 0xffff; + (*output) += 4; +} + +static inline void transfer_YUV422_to_BGR8888(unsigned char *(*output), + unsigned char *input, + int column) +{ + int y, u, v; + int r, g, b; + +// Even pixel + if(!(column & 1)) + y = (int)(input[0]) << 16; + else +// Odd pixel + y = (int)(input[2]) << 16; + u = input[1]; + v = input[3]; + + YUV_TO_RGB(y, u, v, r, g, b) + + (*output)[0] = b; + (*output)[1] = g; + (*output)[2] = r; + (*output) += 4; +} + + +static inline void transfer_YUV422_to_YUV422P(unsigned char *output_y, + unsigned char *output_u, + unsigned char *output_v, + unsigned char *input, + int output_column) +{ +// Store U and V for even pixels only + if(!(output_column & 1)) + { + output_y[output_column] = input[0]; + output_u[output_column / 2] = input[1]; + output_v[output_column / 2] = input[3]; + } + else +// Store Y and advance output for odd pixels only + { + output_y[output_column] = input[2]; + } +} + +static inline void transfer_YUV422_to_YUV420P(unsigned char *output_y, + unsigned char *output_u, + unsigned char *output_v, + unsigned char *input, + int output_column, + int output_row) +{ +// Even column + if(!(output_column & 1)) + { + output_y[output_column] = input[0]; +// Store U and V for even columns and even rows only + if(!(output_row & 1)) + { + output_u[output_column / 2] = input[1]; + output_v[output_column / 2] = input[3]; + } + } + else +// Odd column + { + output_y[output_column] = input[2]; + } +} + +static inline void transfer_YUV422_to_YUV422(unsigned char *(*output), + unsigned char *input, + int j) +{ +// Store U and V for even pixels only + if(!(j & 1)) + { + (*output)[0] = input[0]; + (*output)[1] = input[1]; + (*output)[3] = input[3]; + } + else +// Store Y and advance output for odd pixels only + { + (*output)[2] = input[2]; + (*output) += 4; + } +} + + + + + + +#define TRANSFER_FRAME_DEFAULT(output, \ + input, \ + y_in_offset, \ + u_in_offset, \ + v_in_offset, \ + input_column) \ +{ \ + register int i, j; \ + \ + switch(out_colormodel) \ + { \ + case BC_RGB8: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGB8((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR565: \ + case BC_RGB565: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGB565((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGB888((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGBA8888((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_YUV888((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_YUVA8888((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGB161616((uint16_t**)(output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGBA16161616((uint16_t**)(output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGB_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGB_FLOAT((float**)(output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_RGBA_FLOAT: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_RGBA_FLOAT((float**)(output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_YUV161616((uint16_t**)(output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUVA16161616: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_YUVA16161616((uint16_t**)(output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_BGR888((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_BGR8888: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_BGR8888((output), (input), (input_column)); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422P: \ + TRANSFER_YUV422P_OUT_HEAD \ + transfer_YUV422_to_YUV422P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV422: \ + TRANSFER_FRAME_HEAD \ + transfer_YUV422_to_YUV422((output), \ + (input), \ + j); \ + TRANSFER_FRAME_TAIL \ + break; \ + case BC_YUV420P: \ + TRANSFER_YUV420P_OUT_HEAD \ + transfer_YUV422_to_YUV420P(output_y, \ + output_u, \ + output_v, \ + (input), \ + j, \ + i); \ + TRANSFER_FRAME_TAIL \ + break; \ + } \ +} + +void cmodel_yuv422(PERMUTATION_ARGS) +{ + if(scale) + { + TRANSFER_FRAME_DEFAULT(&output_row, + input_row + ((column_table[j] * in_pixelsize) & 0xfffffffc), + 0, + 0, + 0, + column_table[j]); + } + else + { + TRANSFER_FRAME_DEFAULT(&output_row, + input_row + ((j * in_pixelsize) & 0xfffffffc), + 0, + 0, + 0, + j); + } +} diff --git a/hvirtual/quicktime/colormodels.c b/hvirtual/quicktime/colormodels.c index a019b070..7931198f 100644 --- a/hvirtual/quicktime/colormodels.c +++ b/hvirtual/quicktime/colormodels.c @@ -20,67 +20,127 @@ cmodel_yuv_t *yuv_table = 0; +// Compression coefficients straight out of jpeglib +#define R_TO_Y 0.29900 +#define G_TO_Y 0.58700 +#define B_TO_Y 0.11400 + +#define R_TO_U -0.16874 +#define G_TO_U -0.33126 +#define B_TO_U 0.50000 + +#define R_TO_V 0.50000 +#define G_TO_V -0.41869 +#define B_TO_V -0.08131 + +// Decompression coefficients straight out of jpeglib +#define V_TO_R 1.40200 +#define V_TO_G -0.71414 + +#define U_TO_G -0.34414 +#define U_TO_B 1.77200 + + + + + + void cmodel_init_yuv(cmodel_yuv_t *yuv_table) { int i; + +/* compression */ for(i = 0; i < 0x100; i++) { + yuv_table->rtoy_tab[i] = (int)(R_TO_Y * 0x10000 * i); + yuv_table->rtou_tab[i] = (int)(R_TO_U * 0x10000 * i); + yuv_table->rtov_tab[i] = (int)(R_TO_V * 0x10000 * i); + + yuv_table->gtoy_tab[i] = (int)(G_TO_Y * 0x10000 * i); + yuv_table->gtou_tab[i] = (int)(G_TO_U * 0x10000 * i); + yuv_table->gtov_tab[i] = (int)(G_TO_V * 0x10000 * i); + + yuv_table->btoy_tab[i] = (int)(B_TO_Y * 0x10000 * i); + yuv_table->btou_tab[i] = (int)(B_TO_U * 0x10000 * i) + 0x800000; + yuv_table->btov_tab[i] = (int)(B_TO_V * 0x10000 * i) + 0x800000; + } + /* compression */ - yuv_table->rtoy_tab[i] = (int)( 0.2990 * 0x10000 * i); - yuv_table->rtou_tab[i] = (int)(-0.1687 * 0x10000 * i); - yuv_table->rtov_tab[i] = (int)( 0.5000 * 0x10000 * i); + for(i = 0; i < 0x10000; i++) + { + yuv_table->rtoy_tab16[i] = (int)(R_TO_Y * 0x100 * i); + yuv_table->rtou_tab16[i] = (int)(R_TO_U * 0x100 * i); + yuv_table->rtov_tab16[i] = (int)(R_TO_V * 0x100 * i); - yuv_table->gtoy_tab[i] = (int)( 0.5870 * 0x10000 * i); - yuv_table->gtou_tab[i] = (int)(-0.3320 * 0x10000 * i); - yuv_table->gtov_tab[i] = (int)(-0.4187 * 0x10000 * i); + yuv_table->gtoy_tab16[i] = (int)(G_TO_Y * 0x100 * i); + yuv_table->gtou_tab16[i] = (int)(G_TO_U * 0x100 * i); + yuv_table->gtov_tab16[i] = (int)(G_TO_V * 0x100 * i); - yuv_table->btoy_tab[i] = (int)( 0.1140 * 0x10000 * i); - yuv_table->btou_tab[i] = (int)( 0.5000 * 0x10000 * i) + 0x800000; - yuv_table->btov_tab[i] = (int)(-0.0813 * 0x10000 * i) + 0x800000; + yuv_table->btoy_tab16[i] = (int)(B_TO_Y * 0x100 * i); + yuv_table->btou_tab16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000; + yuv_table->btov_tab16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000; } + + + +/* decompression */ yuv_table->vtor = &(yuv_table->vtor_tab[0x80]); yuv_table->vtog = &(yuv_table->vtog_tab[0x80]); yuv_table->utog = &(yuv_table->utog_tab[0x80]); yuv_table->utob = &(yuv_table->utob_tab[0x80]); for(i = -0x80; i < 0x80; i++) { -/* decompression */ - yuv_table->vtor[i] = (int)( 1.4020 * 0x10000 * i); - yuv_table->vtog[i] = (int)(-0.7141 * 0x10000 * i); + yuv_table->vtor[i] = (int)(V_TO_R * 0x10000 * i); + yuv_table->vtog[i] = (int)(V_TO_G * 0x10000 * i); - yuv_table->utog[i] = (int)(-0.3441 * 0x10000 * i); - yuv_table->utob[i] = (int)( 1.7720 * 0x10000 * i); + yuv_table->utog[i] = (int)(U_TO_G * 0x10000 * i); + yuv_table->utob[i] = (int)(U_TO_B * 0x10000 * i); } - for(i = 0; i < 0x10000; i++) - { -/* compression */ - yuv_table->rtoy_tab16[i] = (int)( 0.2990 * 0x100 * i); - yuv_table->rtou_tab16[i] = (int)(-0.1687 * 0x100 * i); - yuv_table->rtov_tab16[i] = (int)( 0.5000 * 0x100 * i); - yuv_table->gtoy_tab16[i] = (int)( 0.5870 * 0x100 * i); - yuv_table->gtou_tab16[i] = (int)(-0.3320 * 0x100 * i); - yuv_table->gtov_tab16[i] = (int)(-0.4187 * 0x100 * i); +/* decompression */ + yuv_table->vtor_float = &(yuv_table->vtor_float_tab[0x80]); + yuv_table->vtog_float = &(yuv_table->vtog_float_tab[0x80]); + yuv_table->utog_float = &(yuv_table->utog_float_tab[0x80]); + yuv_table->utob_float = &(yuv_table->utob_float_tab[0x80]); + for(i = -0x80; i < 0x80; i++) + { + yuv_table->vtor_float[i] = V_TO_R * i / 0xff; + yuv_table->vtog_float[i] = V_TO_G * i / 0xff; - yuv_table->btoy_tab16[i] = (int)( 0.1140 * 0x100 * i); - yuv_table->btou_tab16[i] = (int)( 0.5000 * 0x100 * i) + 0x800000; - yuv_table->btov_tab16[i] = (int)(-0.0813 * 0x100 * i) + 0x800000; + yuv_table->utog_float[i] = U_TO_G * i / 0xff; + yuv_table->utob_float[i] = U_TO_B * i / 0xff; } + +/* decompression */ yuv_table->vtor16 = &(yuv_table->vtor_tab16[0x8000]); yuv_table->vtog16 = &(yuv_table->vtog_tab16[0x8000]); yuv_table->utog16 = &(yuv_table->utog_tab16[0x8000]); yuv_table->utob16 = &(yuv_table->utob_tab16[0x8000]); for(i = -0x8000; i < 0x8000; i++) { + yuv_table->vtor16[i] = (int)(V_TO_R * 0x100 * i); + yuv_table->vtog16[i] = (int)(V_TO_G * 0x100 * i); + + yuv_table->utog16[i] = (int)(U_TO_G * 0x100 * i); + yuv_table->utob16[i] = (int)(U_TO_B * 0x100 * i); + } + + /* decompression */ - yuv_table->vtor16[i] = (int)( 1.4020 * 0x100 * i); - yuv_table->vtog16[i] = (int)(-0.7141 * 0x100 * i); + yuv_table->v16tor_float = &(yuv_table->v16tor_float_tab[0x8000]); + yuv_table->v16tog_float = &(yuv_table->v16tog_float_tab[0x8000]); + yuv_table->u16tog_float = &(yuv_table->u16tog_float_tab[0x8000]); + yuv_table->u16tob_float = &(yuv_table->u16tob_float_tab[0x8000]); + for(i = -0x8000; i < 0x8000; i++) + { + yuv_table->v16tor_float[i] = V_TO_R * i / 0xffff; + yuv_table->v16tog_float[i] = V_TO_G * i / 0xffff; - yuv_table->utog16[i] = (int)(-0.3441 * 0x100 * i); - yuv_table->utob16[i] = (int)( 1.7720 * 0x100 * i); + yuv_table->u16tog_float[i] = U_TO_G * i / 0xffff; + yuv_table->u16tob_float[i] = U_TO_B * i / 0xffff; } } @@ -107,6 +167,7 @@ int cmodel_components(int colormodel) { case BC_A8: return 1; break; case BC_A16: return 1; break; + case BC_A_FLOAT: return 1; break; case BC_RGB888: return 3; break; case BC_RGBA8888: return 4; break; case BC_RGB161616: return 3; break; @@ -116,6 +177,8 @@ int cmodel_components(int colormodel) case BC_YUV161616: return 3; break; case BC_YUVA16161616: return 4; break; case BC_YUV101010: return 3; break; + case BC_RGB_FLOAT: return 3; break; + case BC_RGBA_FLOAT: return 4; break; } } @@ -125,6 +188,7 @@ int cmodel_calculate_pixelsize(int colormodel) { case BC_A8: return 1; break; case BC_A16: return 2; break; + case BC_A_FLOAT: return 4; break; case BC_TRANSPARENCY: return 1; break; case BC_COMPRESSED: return 1; break; case BC_RGB8: return 1; break; @@ -146,6 +210,8 @@ int cmodel_calculate_pixelsize(int colormodel) case BC_YUV101010: return 4; break; case BC_VYU888: return 3; break; case BC_UYVA8888: return 4; break; + case BC_RGB_FLOAT: return 12; break; + case BC_RGBA_FLOAT: return 16; break; // Planar case BC_YUV420P: return 1; break; case BC_YUV422P: return 1; break; @@ -164,6 +230,7 @@ int cmodel_calculate_max(int colormodel) // Working bitmaps are packed to simplify processing case BC_A8: return 0xff; break; case BC_A16: return 0xffff; break; + case BC_A_FLOAT: return 1; break; case BC_RGB888: return 0xff; break; case BC_RGBA8888: return 0xff; break; case BC_RGB161616: return 0xffff; break; @@ -172,13 +239,16 @@ int cmodel_calculate_max(int colormodel) case BC_YUVA8888: return 0xff; break; case BC_YUV161616: return 0xffff; break; case BC_YUVA16161616: return 0xffff; break; + case BC_RGB_FLOAT: return 1; break; + case BC_RGBA_FLOAT: return 1; break; } return 0; } int cmodel_calculate_datasize(int w, int h, int bytes_per_line, int color_model) { - if(bytes_per_line < 0) bytes_per_line = w * cmodel_calculate_pixelsize(color_model); + if(bytes_per_line < 0) bytes_per_line = w * + cmodel_calculate_pixelsize(color_model); switch(color_model) { case BC_YUV420P: @@ -283,7 +353,7 @@ void cmodel_transfer(unsigned char **output_rows, out_x, out_y, out_x + out_w, out_y + out_h); /* - * printf("cmodel_transfer %d %d %d,%d %d,%d %d,%d %d,%d\n", + * printf("cmodel_transfer 1 %d %d %d,%d %d,%d %d,%d %d,%d\n", * in_colormodel, * out_colormodel, * out_x, @@ -331,6 +401,11 @@ void cmodel_transfer(unsigned char **output_rows, // Handle planar cmodels separately switch(in_colormodel) { + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + cmodel_float(PERMUTATION_VALUES); + break; + case BC_YUV420P: case BC_YUV422P: cmodel_yuv420p(PERMUTATION_VALUES); @@ -353,6 +428,12 @@ void cmodel_transfer(unsigned char **output_rows, break; } +/* + * printf("cmodel_transfer 100 %d %d\n", + * in_colormodel, + * out_colormodel); + */ + free(column_table); free(row_table); } @@ -383,6 +464,8 @@ void cmodel_to_text(char *string, int cmodel) case BC_YUVA8888: strcpy(string, "YUVA-8 Bit"); break; case BC_YUV161616: strcpy(string, "YUV-16 Bit"); break; case BC_YUVA16161616: strcpy(string, "YUVA-16 Bit"); break; + case BC_RGB_FLOAT: strcpy(string, "RGB-FLOAT"); break; + case BC_RGBA_FLOAT: strcpy(string, "RGBA-FLOAT"); break; default: strcpy(string, "RGB-8 Bit"); break; } } @@ -393,6 +476,8 @@ int cmodel_from_text(char *text) if(!strcasecmp(text, "RGBA-8 Bit")) return BC_RGBA8888; if(!strcasecmp(text, "RGB-16 Bit")) return BC_RGB161616; if(!strcasecmp(text, "RGBA-16 Bit")) return BC_RGBA16161616; + if(!strcasecmp(text, "RGB-FLOAT")) return BC_RGB_FLOAT; + if(!strcasecmp(text, "RGBA-FLOAT")) return BC_RGBA_FLOAT; if(!strcasecmp(text, "YUV-8 Bit")) return BC_YUV888; if(!strcasecmp(text, "YUVA-8 Bit")) return BC_YUVA8888; if(!strcasecmp(text, "YUV-16 Bit")) return BC_YUV161616; diff --git a/hvirtual/quicktime/colormodels.h b/hvirtual/quicktime/colormodels.h index 4ffab796..075d0aab 100644 --- a/hvirtual/quicktime/colormodels.h +++ b/hvirtual/quicktime/colormodels.h @@ -41,9 +41,12 @@ #define BC_YUV422 19 #define BC_A8 22 #define BC_A16 23 +#define BC_A_FLOAT 31 #define BC_YUV101010 24 #define BC_VYU888 25 #define BC_UYVA8888 26 +#define BC_RGB_FLOAT 29 +#define BC_RGBA_FLOAT 30 // Planar #define BC_YUV420P 7 #define BC_YUV422P 17 @@ -58,8 +61,12 @@ #define FOURCC_YUV2 0x32595559 /* YUV2 YUV422 */ #define FOURCC_I420 0x30323449 /* I420 Intel Indeo 4 */ -#undef RECLIP -#define RECLIP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))) +#undef CLAMP +#define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))) + +#undef CLIP +#define CLIP(x, y, z) ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))) + #ifdef __cplusplus extern "C" { @@ -73,8 +80,13 @@ typedef struct int vtor_tab[0x100], vtog_tab[0x100]; int utog_tab[0x100], utob_tab[0x100]; +// Used by init_yuv only int *vtor, *vtog, *utog, *utob; + float vtor_float_tab[0x100], vtog_float_tab[0x100]; + float utog_float_tab[0x100], utob_float_tab[0x100]; + float *vtor_float, *vtog_float, *utog_float, *utob_float; + int rtoy_tab16[0x10000], gtoy_tab16[0x10000], btoy_tab16[0x10000]; int rtou_tab16[0x10000], gtou_tab16[0x10000], btou_tab16[0x10000]; int rtov_tab16[0x10000], gtov_tab16[0x10000], btov_tab16[0x10000]; @@ -82,6 +94,10 @@ typedef struct int vtor_tab16[0x10000], vtog_tab16[0x10000]; int utog_tab16[0x10000], utob_tab16[0x10000]; int *vtor16, *vtog16, *utog16, *utob16; + + float v16tor_float_tab[0x10000], v16tog_float_tab[0x10000]; + float u16tog_float_tab[0x10000], u16tob_float_tab[0x10000]; + float *v16tor_float, *v16tog_float, *u16tog_float, *u16tob_float; } cmodel_yuv_t; extern cmodel_yuv_t *yuv_table; diff --git a/hvirtual/quicktime/funcprotos.h b/hvirtual/quicktime/funcprotos.h index ba7dc168..f1acabb4 100644 --- a/hvirtual/quicktime/funcprotos.h +++ b/hvirtual/quicktime/funcprotos.h @@ -48,6 +48,8 @@ int quicktime_write_fixed16(quicktime_t *file, float number); /* Returns number of bytes written */ int quicktime_write_data(quicktime_t *file, char *data, int size); +/* Enable or disable presave */ +void quicktime_set_presave(quicktime_t *file, int value); /* Returns 1 if equal or 0 if different */ int quicktime_match_32(char *input, char *output); int quicktime_match_24(char *input, char *output); @@ -132,6 +134,14 @@ void quicktime_finalize_hdrl(quicktime_t *file, quicktime_hdrl_t *hdrl); void quicktime_read_esds(quicktime_t *file, quicktime_atom_t *parent_atom, quicktime_stsd_table_t *table); +void quicktime_write_esds(quicktime_t *file, + quicktime_stsd_table_t *table, + int do_video, + int do_audio); +// Set esds header to a copy of the argument +void quicktime_set_mpeg4_header(quicktime_stsd_table_t *table, + unsigned char *data, + int size); diff --git a/hvirtual/quicktime/libmjpeg.c b/hvirtual/quicktime/libmjpeg.c index 2786df3d..df5691b0 100644 --- a/hvirtual/quicktime/libmjpeg.c +++ b/hvirtual/quicktime/libmjpeg.c @@ -363,7 +363,13 @@ static void allocate_temps(mjpeg_t *mjpeg) mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h); mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h); mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h); - for(i = 0; i < mjpeg->coded_h; i++) + if(mjpeg->greyscale) + { + memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h, + 0x80, + mjpeg->coded_w * mjpeg->coded_h * 2); + } + for(i = 0; i < mjpeg->coded_h; i++) { mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w; mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w; @@ -636,6 +642,10 @@ static void decompress_field(mjpeg_compressor *engine) else mjpeg->jpeg_color_model = BC_YUV444P; + if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE) + mjpeg->greyscale = 1; + +//printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor); // Must be here because the color model isn't known until now pthread_mutex_lock(&(mjpeg->decompress_init)); allocate_temps(mjpeg); @@ -1038,8 +1048,7 @@ int mjpeg_decompress(mjpeg_t *mjpeg, // For dual CPUs, don't want second thread to start until temp data is allocated by the first. // For single CPUs, don't want two threads running simultaneously - if(mjpeg->cpus < 2 || !mjpeg->temp_data - /* && i < mjpeg->fields - 1 && !mjpeg->temp_data */) + if(mjpeg->cpus < 2 || !mjpeg->temp_data) { lock_compress_loop(mjpeg->decompressors[i]); if(i == 0) got_first_thread = 1; @@ -1074,14 +1083,19 @@ int mjpeg_decompress(mjpeg_t *mjpeg, (mjpeg->temp_data || !mjpeg->error)) { + unsigned char *y_in = mjpeg->temp_rows[0][0]; + unsigned char *u_in = mjpeg->temp_rows[1][0]; + unsigned char *v_in = mjpeg->temp_rows[2][0]; + +//printf("mjpeg_decompress %p\n", row_pointers); cmodel_transfer(row_pointers, 0, y_plane, u_plane, v_plane, - mjpeg->temp_rows[0][0], - mjpeg->temp_rows[1][0], - mjpeg->temp_rows[2][0], + y_in, + u_in, + v_in, 0, 0, mjpeg->output_w, @@ -1096,7 +1110,6 @@ int mjpeg_decompress(mjpeg_t *mjpeg, mjpeg->coded_w, mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w); } -//printf("mjpeg_decompress 100\n"); return 0; } diff --git a/hvirtual/quicktime/libmjpeg.h b/hvirtual/quicktime/libmjpeg.h index d490087d..882ac039 100644 --- a/hvirtual/quicktime/libmjpeg.h +++ b/hvirtual/quicktime/libmjpeg.h @@ -98,6 +98,9 @@ typedef struct int color_model; // Color model of compressed data. Since MJPA streams use 4:2:0 int jpeg_color_model; +// To save on colormodel permutations, we flag grayscale separately and +// just set U and V to 0x80. + int greyscale; // Error in compression process int error; diff --git a/hvirtual/quicktime/plugin.c b/hvirtual/quicktime/plugin.c index 2a59a7c8..a02a7469 100644 --- a/hvirtual/quicktime/plugin.c +++ b/hvirtual/quicktime/plugin.c @@ -89,10 +89,10 @@ static void register_vcodecs() register_vcodec(quicktime_init_codec_mp4v); register_vcodec(quicktime_init_codec_svq1); register_vcodec(quicktime_init_codec_svq3); + register_vcodec(quicktime_init_codec_h263); register_vcodec(quicktime_init_codec_dv); register_vcodec(quicktime_init_codec_dvsd); - register_vcodec(quicktime_init_codec_jpeg); register_vcodec(quicktime_init_codec_mjpa); register_vcodec(quicktime_init_codec_mjpg); diff --git a/hvirtual/quicktime/qtprivate.h b/hvirtual/quicktime/qtprivate.h index 83ba6c86..1b56b58e 100644 --- a/hvirtual/quicktime/qtprivate.h +++ b/hvirtual/quicktime/qtprivate.h @@ -6,7 +6,7 @@ /* Version used internally. You need to query it with the C functions */ #define QUICKTIME_MAJOR 2 #define QUICKTIME_MINOR 0 -#define QUICKTIME_RELEASE 3 +#define QUICKTIME_RELEASE 4 #define HEADER_LENGTH 8 @@ -693,7 +693,7 @@ typedef struct char *presave_buffer; /* Presave doesn't matter a whole lot, so its size is fixed */ #define QUICKTIME_PRESAVE 0x100000 - + int use_presave; /* mapping of audio channels to movie tracks */ /* one audio map entry exists for each channel */ diff --git a/hvirtual/quicktime/quicktime.c b/hvirtual/quicktime/quicktime.c index 60c461c2..1d1861cf 100644 --- a/hvirtual/quicktime/quicktime.c +++ b/hvirtual/quicktime/quicktime.c @@ -1228,9 +1228,11 @@ quicktime_t* quicktime_open(char *filename, int rd, int wr) /* also don't want to do this if making a streamable file */ if(wr) { + quicktime_set_presave(new_file, 1); quicktime_atom_write_header64(new_file, &new_file->mdat.atom, "mdat"); + quicktime_set_presave(new_file, 0); } } else @@ -1252,6 +1254,8 @@ int quicktime_close(quicktime_t *file) { quicktime_codecs_flush(file); +// Reenable buffer for quick header writing. + quicktime_set_presave(file, 1); if(file->use_avi) { quicktime_atom_t junk_atom; diff --git a/hvirtual/quicktime/quicktime.h b/hvirtual/quicktime/quicktime.h index c56f71cd..e63da44f 100644 --- a/hvirtual/quicktime/quicktime.h +++ b/hvirtual/quicktime/quicktime.h @@ -32,6 +32,7 @@ extern "C" { /* Mormon MPEG-4 */ #define QUICKTIME_SVQ1 "SVQ1" #define QUICKTIME_SVQ3 "SVQ3" +#define QUICKTIME_H263 "h263" /* Dee Vee */ #define QUICKTIME_DV "dvc " diff --git a/hvirtual/quicktime/stsd.c b/hvirtual/quicktime/stsd.c index d96763b1..7c16dcf6 100644 --- a/hvirtual/quicktime/stsd.c +++ b/hvirtual/quicktime/stsd.c @@ -102,7 +102,8 @@ void quicktime_read_stsd(quicktime_t *file, quicktime_minf_t *minf, quicktime_st for(i = 0; i < stsd->total_entries; i++) { quicktime_stsd_table_init(&(stsd->table[i])); - quicktime_read_stsd_table(file, minf, &(stsd->table[i])); +// quicktime_read_stsd_table(file, minf, &(stsd->table[i])); + quicktime_read_stsd_table(file, minf, &(stsd->table[0])); } } diff --git a/hvirtual/quicktime/stsdtable.c b/hvirtual/quicktime/stsdtable.c index a7efbe3c..e5d5ec78 100644 --- a/hvirtual/quicktime/stsdtable.c +++ b/hvirtual/quicktime/stsdtable.c @@ -27,7 +27,20 @@ void quicktime_mjht_dump(quicktime_mjht_t *mjht) { } +// Set esds header to a copy of the argument +void quicktime_set_mpeg4_header(quicktime_stsd_table_t *table, + unsigned char *data, + int size) +{ + if(table->mpeg4_header) + { + free(table->mpeg4_header); + } + table->mpeg4_header = calloc(1, size); + memcpy(table->mpeg4_header, data, size); + table->mpeg4_header_size = size; +} static void read_wave(quicktime_t *file, quicktime_stsd_table_t *table, @@ -181,6 +194,8 @@ void quicktime_write_stsd_video(quicktime_t *file, quicktime_stsd_table_t *table quicktime_write_int16(file, table->depth); quicktime_write_int16(file, table->ctab_id); + +// Write field order for mjpa if(table->fields) { quicktime_atom_t atom; @@ -190,6 +205,12 @@ void quicktime_write_stsd_video(quicktime_t *file, quicktime_stsd_table_t *table quicktime_write_char(file, table->field_dominance); quicktime_atom_write_footer(file, &atom); } + +// Write header for mp4v + if(table->mpeg4_header_size && table->mpeg4_header) + { + quicktime_write_esds(file, table, 1, 0); + } } void quicktime_read_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table) diff --git a/hvirtual/quicktime/util.c b/hvirtual/quicktime/util.c index 4085b34b..5cd08288 100644 --- a/hvirtual/quicktime/util.c +++ b/hvirtual/quicktime/util.c @@ -214,58 +214,99 @@ printf("read data Size is larger than preload size. size=%llx preload_size=%llx\ return result; } +void quicktime_set_presave(quicktime_t *file, int value) +{ +// Flush presave buffer + if(!value && file->use_presave) + { + quicktime_fseek(file, file->presave_position - file->presave_size); + fwrite(file->presave_buffer, 1, file->presave_size, file->stream); + file->presave_size = 0; + file->file_position = file->presave_position; + file->ftell_position = file->presave_position; + if(file->total_length < file->ftell_position) + file->total_length = file->ftell_position; + } + else + if(value && !file->use_presave) + { + ; + } + + file->use_presave = value; +} + int quicktime_write_data(quicktime_t *file, char *data, int size) { int data_offset = 0; int writes_attempted = 0; int writes_succeeded = 0; int iterations = 0; -//printf("quicktime_write_data 1 %d\n", size); -// Flush existing buffer and seek to new position - if(file->file_position != file->presave_position) + if(!file->use_presave) + { +//printf("quicktime_write_data 1\n"); + writes_attempted = 1; + writes_succeeded = fwrite(data, + size, + 1, + file->stream); + file->file_position += size; + file->ftell_position += size; +//printf("quicktime_write_data 2\n"); + } + else { - if(file->presave_size) +// Flush existing buffer and seek to new position + if(file->file_position != file->presave_position) { - quicktime_fseek(file, file->presave_position - file->presave_size); - writes_succeeded += fwrite(file->presave_buffer, 1, file->presave_size, file->stream); - writes_attempted += file->presave_size; - file->presave_size = 0; + if(file->presave_size) + { + quicktime_fseek(file, file->presave_position - file->presave_size); + writes_succeeded += fwrite(file->presave_buffer, 1, file->presave_size, file->stream); + writes_attempted += file->presave_size; + file->presave_size = 0; + } + file->presave_position = file->file_position; } - file->presave_position = file->file_position; - } // Write presave buffers until done - while(size > 0) - { - int fragment_size = QUICKTIME_PRESAVE; - if(fragment_size > size) fragment_size = size; - if(fragment_size + file->presave_size > QUICKTIME_PRESAVE) - fragment_size = QUICKTIME_PRESAVE- file->presave_size; + while(size > 0) + { + int fragment_size = QUICKTIME_PRESAVE; + if(fragment_size > size) fragment_size = size; + if(fragment_size + file->presave_size > QUICKTIME_PRESAVE) + fragment_size = QUICKTIME_PRESAVE- file->presave_size; - memcpy(file->presave_buffer + file->presave_size, - data + data_offset, - fragment_size); + memcpy(file->presave_buffer + file->presave_size, + data + data_offset, + fragment_size); - file->presave_position += fragment_size; - file->presave_size += fragment_size; - data_offset += fragment_size; - size -= fragment_size; + file->presave_position += fragment_size; + file->presave_size += fragment_size; + data_offset += fragment_size; + size -= fragment_size; - if(file->presave_size >= QUICKTIME_PRESAVE) - { + if(file->presave_size >= QUICKTIME_PRESAVE) + { //if(++iterations > 1) printf("quicktime_write_data 2 iterations=%d\n", iterations); - quicktime_fseek(file, file->presave_position - file->presave_size); - writes_succeeded += fwrite(file->presave_buffer, 1, file->presave_size, file->stream); - writes_attempted += file->presave_size; - file->presave_size = 0; + quicktime_fseek(file, file->presave_position - file->presave_size); + writes_succeeded += fwrite(file->presave_buffer, + file->presave_size, + 1, + file->stream); + writes_attempted += file->presave_size; + file->presave_size = 0; + } } - } /* Adjust file position */ - file->file_position = file->presave_position; + file->file_position = file->presave_position; /* Adjust ftell position */ - file->ftell_position = file->presave_position; + file->ftell_position = file->presave_position; + } + + /* Adjust total length */ if(file->total_length < file->ftell_position) file->total_length = file->ftell_position; diff --git a/hvirtual/quicktime/vorbis.c b/hvirtual/quicktime/vorbis.c index bc749104..45279ce6 100644 --- a/hvirtual/quicktime/vorbis.c +++ b/hvirtual/quicktime/vorbis.c @@ -671,6 +671,11 @@ static int encode(quicktime_t *file, quicktime_atom_t chunk_atom; + if(samplerate < 32000) + { + printf("encode: sample rate %d not supported.\n", samplerate); + return 1; + } diff --git a/hvirtual/quicktime/workarounds.c b/hvirtual/quicktime/workarounds.c index c73ea6ea..38a42c1b 100644 --- a/hvirtual/quicktime/workarounds.c +++ b/hvirtual/quicktime/workarounds.c @@ -10,3 +10,8 @@ int64_t quicktime_add3(int64_t a, int64_t b, int64_t c) { return a + b + c; } + +uint16_t quicktime_copy(int value) +{ + return value; +} diff --git a/hvirtual/quicktime/workarounds.h b/hvirtual/quicktime/workarounds.h index 9a87a65c..1360ed59 100644 --- a/hvirtual/quicktime/workarounds.h +++ b/hvirtual/quicktime/workarounds.h @@ -5,5 +5,6 @@ int64_t quicktime_add(int64_t a, int64_t b); int64_t quicktime_add3(int64_t a, int64_t b, int64_t c); +uint16_t quicktime_copy(int value); #endif -- 2.11.4.GIT