Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- @title video exposure control
- by fudgey 2010/08/22
- Requires CHDK built with native call support
- Thanks to ewavr (method) and reyalp (lua things, eventprocs)
- This script uses hard coded firmware function entry points which will only
- work on this specific camera + firmware version.
- If 1, camera will reset to autoexposure when script ends:
- @param a set auto exp on exit?
- @default a 1
- How large adjust steps to use. 32 is 1/3 stop, 96 is full stop:
- @param b tv96 step (96=full stop)
- @default b 32
- @param c av96 step (96=full stop)
- @default c 32
- param d sv96 step (96=full stop)
- default d 32
- The script uses certain camera functions to set exposure values. These functions
- appear to return whatever value they actually set. If this argument is zero,
- the camera return value is used as the current exposure value shown on the console
- and as the seed value for the next adjustment. Thus the camera may will limit
- the adjustment range. If you feel brave and optimistic, set this to '1' to see if
- you can go further than the camera wants to let you go. There are built-in limits
- in the script too, you may need to relax them too to do this:
- @param e override cam limits
- @default e 0
- --]]
- --[[
- todo:
- - ISO control
- - show Av in 1/f
- - show Tv in milliseconds or fractional or divisor from video frame rate
- - ND filter control (ExpCtrlTool.ND or whatever CHDK uses?). I can't do this since I don't have a suitable camera.
- --]]
- TVSTEP=b
- AVSTEP=c
- --SVSTEP=d
- OVERRIDE=e
- --**************************************************************************
- -- configure camera model and sub here once entry points have been changed
- --**************************************************************************
- bi=get_buildinfo()
- print("platform: ",bi.platform," ",bi.platsub)
- if bi.platform~="a570" then
- error("wrong camera model")
- elseif bi.platsub~="100e" then
- error("wrong firmware version")
- end
- -- don't run in play mode
- rec,vid,mode=get_mode()
- print("rec:",rec,"vid:",vid)
- sleep(1000)
- if rec~=true then
- error("Not in rec mode.")
- end
- --**************************************************************************
- -- configure limiting values here
- --**************************************************************************
- -- tv96 is tied to exposure time in seconds by equation tv = 2^-(tv96/96)
- tv96_min=5*96 -- 448 crashes a570, this one seems stable (1/30 s is slightly slower than 30 fps but this works in 60 fps mode too)
- -- av96 is tied to aperture number N in f/N by equation av96 = 96 * 2*log2(N)
- av96_min=2*96
- --av96_min=get_prop(prop.MIN_AV) -- returns 0 for my cam, which sounds dangerous (literally). Also, require "propcase" hangs during video record.
- av96_max=8*96 -- (f/16)
- --sv96_min=4*96
- --sv96_max=9*96
- if (type(call_event_proc) ~= "function" ) then
- error("your CHDK does not support native calls")
- end
- -- this is required for event procedure AllocateMemory
- if (call_event_proc("SystemEventInit") == -1) then
- error("SystemEventInit failed")
- end
- -- this is required for event procedures ExpCtrlTool.*
- if (call_event_proc("Capture.Create") == -1) then
- error("Capture.Create failed")
- end
- -- to make lua happy
- tv96=get_tv96()
- av96=get_av96()
- --sv96=get_sv96()
- decrease=0
- increase=1
- -- 1/3 stop Tv adjustment
- -- too slow tv crashes the cam.
- function tv_adj(incr)
- if incr==increase then
- tv96=tv96-TVSTEP
- else
- tv96=tv96+TVSTEP
- end
- -- prevent tv from going slower than safe minumum or higher than signed short can go
- if tv96<tv96_min then
- tv96=tv96_min
- elseif tv96>32767 then
- tv96=32767
- end
- -- Sets exposure by calling an eventproc which takes a pointer to a 16-bit signed short as argument.
- -- We need to allocate a word of memory and poke our value there before calling:
- buf=call_event_proc("AllocateMemory",4)
- if buf > 0 then
- poke(buf,tv96)
- --**************************************************************************
- -- configure entry point here or switch to event proc if you can
- --**************************************************************************
- ret=call_func_ptr(0xffe0b70c,buf) --SetAE_ShutterSpeed(&tv)
- --ret=call_event_proc("SetAE_ShutterSpeed",buf)
- --**************************************************************************
- -- Canon's function seems to return sane values, let's use them as limits:
- if OVERRIDE ~= 1 then
- tv96=ret
- end
- call_event_proc("FreeMemory",buf)
- else
- error("AllocateMemory failed")
- end
- -- change menu text to show new value
- curmenu[curitem].name=function() return(tostring(string.format("%s %d", "Tv", tv96))) end
- end
- -- 1/3 stop Av adjustment
- function av_adj(incr)
- if incr==increase then
- av96=av96-AVSTEP
- else
- av96=av96+AVSTEP
- end
- -- prevent tv from going slower than safe minumum or higher than signed short can go
- if av96<av96_min then
- av96=av96_min
- elseif av96>av96_max then
- av96=av96_max
- end
- -- Sets exposure by calling an eventproc which takes a pointer to a 16-bit signed short as argument.
- -- We need to allocate a word of memory and poke our value there before calling:
- buf=call_event_proc("AllocateMemory",4)
- if buf > 0 then
- poke(buf,av96)
- --**************************************************************************
- -- configure entry point here or switch to event proc if you can
- --**************************************************************************
- ret=call_func_ptr(0xffe05ba4,buf) --MoveIrisToAv(&tv)
- --ret=call_event_proc("MoveIrisToAv",buf)
- --**************************************************************************
- -- Canon's function seems to return sane values, let's use them as limits:
- if OVERRIDE ~= 1 then
- av96=ret
- end
- call_event_proc("FreeMemory",buf)
- else
- error("AllocateMemory failed")
- end
- -- change menu text to show new value
- curmenu[curitem].name=function() return(tostring(string.format("%s %d", "Av", av96))) end
- end
- function sv_adj(incr)
- -- TODO
- -- maybe using call_event_proc("SetAE_CdsGainValue", ...)
- end
- -- go to manual exposure mode
- function manualexp()
- ret=call_event_proc("ExpCtrlTool.StopConti")
- if ret==-1 then
- error("ExpCtrlTool.StopConti failed")
- end
- end
- -- go to auto exposure mode
- function autoexp()
- call_event_proc("ExpCtrlTool.StartConti")
- if ret==-1 then
- error("ExpCtrlTool.StartConti failed")
- end
- end
- function menuitem(name,item)
- t={item = item}
- if type(name) ~= "function" then
- t.name = function()
- return(tostring(name))
- end
- else
- t.name = name
- end
- return t
- end
- mainmenu={
- menuitem("Tv "..tv96,tv_adj),
- menuitem("Av "..av96,av_adj),
- --menuitem("ISO",sv_adj),
- }
- function domenu()
- curmenu=mainmenu
- curitem=1
- while true do
- cls()
- print("U/D:pick | quit:MENU")
- print("L/R:adj | autoexp:SET ")
- if curitem > 1 then
- print(string.format("|%s",curmenu[curitem-1].name()))
- else
- print("-----------------------")
- end
- print(string.format(">%s",curmenu[curitem].name()))
- if curmenu[curitem+1] then
- print(string.format("|%s",curmenu[curitem+1].name()))
- else
- print("-----------------------")
- end
- wait_click(5000)
- if is_pressed("down") then
- if curmenu[curitem+1] then
- curitem = curitem + 1
- end
- elseif is_pressed("up") then
- if curitem > 1 then
- curitem = curitem - 1
- end
- elseif is_pressed("left") then
- if type(curmenu[curitem].item) == "function" then
- curmenu[curitem].item(increase)
- end
- elseif is_pressed("right") then
- if type(curmenu[curitem].item) == "function" then
- curmenu[curitem].item(decrease)
- end
- elseif is_pressed("set") then
- print("auto exposure, wait...")
- autoexp()
- sleep(1000)
- -- update values in menu
- tv96=get_tv96()
- mainmenu[1].name=function() return(tostring(string.format("%s %d", "Tv", tv96))) end
- av96=get_av96()
- mainmenu[2].name=function() return(tostring(string.format("%s %d", "Av", av96))) end
- --sv96=get_sv96()
- --mainmenu[3].name=function() return(tostring(string.format("%s %d", "Sv", sv96))) end
- manualexp()
- elseif is_pressed("menu") then
- break
- end
- end
- end
- function restore()
- if a==1 then
- print("enabling autoexposure")
- autoexp()
- end
- end
- manualexp()
- -- startup values
- tv96=get_tv96()
- av96=get_av96()
- --sv96=get_sv96()
- domenu()
- restore()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement