Guest User

VideExp.lua

a guest
Aug 22nd, 2010
278
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. @title video exposure control
  3. by fudgey 2010/08/22
  4.  
  5. Requires CHDK built with native call support
  6. Thanks to ewavr (method) and reyalp (lua things, eventprocs)
  7.  
  8. This script uses hard coded firmware function entry points which will only
  9. work on this specific camera + firmware version.
  10.  
  11. If 1, camera will reset to autoexposure when script ends:
  12. @param a set auto exp on exit?
  13. @default a 1
  14.  
  15. How large adjust steps to use. 32 is 1/3 stop, 96 is full stop:
  16. @param b tv96 step (96=full stop)
  17. @default b 32
  18. @param c av96 step (96=full stop)
  19. @default c 32
  20. param d sv96 step (96=full stop)
  21. default d 32
  22.  
  23. The script uses certain camera functions to set exposure values. These functions
  24. appear to return whatever value they actually set. If this argument is zero,
  25. the camera return value is used as the current exposure value shown on the console
  26. and as the seed value for the next adjustment. Thus the camera may will limit
  27. the adjustment range. If you feel brave and optimistic, set this to '1' to see if
  28. you can go further than the camera wants to let you go. There are built-in limits
  29. in the script too, you may need to relax them too to do this:
  30. @param e override cam limits
  31. @default e 0
  32. --]]
  33.  
  34.  
  35. --[[
  36. todo:
  37. - ISO control
  38. - show Av in 1/f
  39. - show Tv in milliseconds or fractional or divisor from video frame rate
  40. - ND filter control (ExpCtrlTool.ND or whatever CHDK uses?). I can't do this since I don't have a suitable camera.
  41. --]]
  42.  
  43. TVSTEP=b
  44. AVSTEP=c
  45. --SVSTEP=d
  46. OVERRIDE=e
  47.  
  48. --**************************************************************************
  49. -- configure camera model and sub here once entry points have been changed
  50. --**************************************************************************
  51. bi=get_buildinfo()
  52. print("platform: ",bi.platform," ",bi.platsub)
  53. if bi.platform~="a570" then
  54.   error("wrong camera model")
  55. elseif bi.platsub~="100e" then
  56.   error("wrong firmware version")
  57. end
  58.  
  59. -- don't run in play mode
  60. rec,vid,mode=get_mode()
  61. print("rec:",rec,"vid:",vid)
  62. sleep(1000)
  63. if rec~=true then
  64.   error("Not in rec mode.")
  65. end
  66.  
  67. --**************************************************************************
  68. -- configure limiting values here
  69. --**************************************************************************
  70. -- tv96 is tied to exposure time in seconds by equation tv = 2^-(tv96/96)
  71. 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)
  72.  
  73. -- av96 is tied to aperture number N in f/N by equation av96 = 96 * 2*log2(N)
  74. av96_min=2*96
  75. --av96_min=get_prop(prop.MIN_AV) -- returns 0 for my cam, which sounds dangerous (literally). Also, require "propcase" hangs during video record.
  76. av96_max=8*96 -- (f/16)
  77. --sv96_min=4*96
  78. --sv96_max=9*96
  79.  
  80. if (type(call_event_proc) ~= "function" ) then
  81.     error("your CHDK does not support native calls")
  82. end
  83.  
  84. -- this is required for event procedure AllocateMemory
  85. if (call_event_proc("SystemEventInit") == -1) then
  86.     error("SystemEventInit failed")
  87. end
  88.  
  89. -- this is required for event procedures ExpCtrlTool.*
  90. if (call_event_proc("Capture.Create") == -1) then
  91.     error("Capture.Create failed")
  92. end
  93.  
  94. -- to make lua happy
  95. tv96=get_tv96()
  96. av96=get_av96()
  97. --sv96=get_sv96()
  98.  
  99. decrease=0
  100. increase=1
  101.  
  102. -- 1/3 stop Tv adjustment
  103. -- too slow tv crashes the cam.
  104. function tv_adj(incr)
  105.     if incr==increase then
  106.         tv96=tv96-TVSTEP
  107.     else
  108.         tv96=tv96+TVSTEP
  109.     end
  110.     -- prevent tv from going slower than safe minumum or higher than signed short can go
  111.     if tv96<tv96_min then
  112.         tv96=tv96_min
  113.     elseif tv96>32767 then
  114.         tv96=32767
  115.     end
  116.     -- Sets exposure by calling an eventproc which takes a pointer to a 16-bit signed short as argument.
  117.     -- We need to allocate a word of memory and poke our value there before calling:
  118.     buf=call_event_proc("AllocateMemory",4)
  119.     if buf > 0 then
  120.         poke(buf,tv96)
  121. --**************************************************************************
  122. -- configure entry point here or switch to event proc if you can
  123. --**************************************************************************
  124.         ret=call_func_ptr(0xffe0b70c,buf) --SetAE_ShutterSpeed(&tv)
  125.         --ret=call_event_proc("SetAE_ShutterSpeed",buf)
  126. --**************************************************************************
  127.         -- Canon's function seems to return sane values, let's use them as limits:
  128.         if OVERRIDE ~= 1 then
  129.           tv96=ret
  130.         end
  131.         call_event_proc("FreeMemory",buf)
  132.     else
  133.         error("AllocateMemory failed")
  134.     end
  135.     -- change menu text to show new value
  136.     curmenu[curitem].name=function() return(tostring(string.format("%s %d", "Tv", tv96))) end
  137. end
  138.  
  139. -- 1/3 stop Av adjustment
  140. function av_adj(incr)
  141.     if incr==increase then
  142.         av96=av96-AVSTEP
  143.     else
  144.         av96=av96+AVSTEP
  145.     end
  146.     -- prevent tv from going slower than safe minumum or higher than signed short can go
  147.     if av96<av96_min then
  148.         av96=av96_min
  149.     elseif av96>av96_max then
  150.         av96=av96_max
  151.     end
  152.     -- Sets exposure by calling an eventproc which takes a pointer to a 16-bit signed short as argument.
  153.     -- We need to allocate a word of memory and poke our value there before calling:
  154.     buf=call_event_proc("AllocateMemory",4)
  155.     if buf > 0 then
  156.         poke(buf,av96)
  157. --**************************************************************************
  158. -- configure entry point here or switch to event proc if you can
  159. --**************************************************************************
  160.         ret=call_func_ptr(0xffe05ba4,buf) --MoveIrisToAv(&tv)
  161.         --ret=call_event_proc("MoveIrisToAv",buf)
  162. --**************************************************************************
  163.         -- Canon's function seems to return sane values, let's use them as limits:
  164.         if OVERRIDE ~= 1 then
  165.           av96=ret
  166.         end
  167.         call_event_proc("FreeMemory",buf)
  168.     else
  169.         error("AllocateMemory failed")
  170.     end
  171.     -- change menu text to show new value
  172.     curmenu[curitem].name=function() return(tostring(string.format("%s %d", "Av", av96))) end
  173. end
  174.  
  175. function sv_adj(incr)
  176.   -- TODO
  177.   -- maybe using call_event_proc("SetAE_CdsGainValue", ...)
  178. end
  179.  
  180. -- go to manual exposure mode
  181. function manualexp()
  182.     ret=call_event_proc("ExpCtrlTool.StopConti")
  183.     if ret==-1 then
  184.       error("ExpCtrlTool.StopConti failed")
  185.     end
  186. end
  187.  
  188. -- go to auto exposure mode
  189. function autoexp()
  190.     call_event_proc("ExpCtrlTool.StartConti")
  191.     if ret==-1 then
  192.       error("ExpCtrlTool.StartConti failed")
  193.     end
  194. end
  195.  
  196. function menuitem(name,item)
  197.     t={item = item}
  198.     if type(name) ~= "function" then
  199.         t.name = function()
  200.             return(tostring(name))
  201.         end
  202.     else
  203.         t.name = name
  204.     end
  205.     return t
  206. end
  207.  
  208. mainmenu={
  209.     menuitem("Tv "..tv96,tv_adj),
  210.     menuitem("Av "..av96,av_adj),
  211.     --menuitem("ISO",sv_adj),
  212. }
  213.  
  214. function domenu()
  215.     curmenu=mainmenu
  216.     curitem=1
  217.     while true do
  218.         cls()
  219.         print("U/D:pick |    quit:MENU")
  220.         print("L/R:adj  | autoexp:SET ")
  221.         if curitem > 1  then
  222.             print(string.format("|%s",curmenu[curitem-1].name()))
  223.         else
  224.             print("-----------------------")
  225.         end
  226.         print(string.format(">%s",curmenu[curitem].name()))
  227.         if curmenu[curitem+1] then
  228.             print(string.format("|%s",curmenu[curitem+1].name()))
  229.         else
  230.             print("-----------------------")
  231.         end
  232.         wait_click(5000)
  233.         if is_pressed("down") then
  234.             if curmenu[curitem+1] then
  235.                 curitem = curitem + 1
  236.             end
  237.         elseif is_pressed("up") then
  238.             if curitem > 1 then
  239.                 curitem = curitem - 1
  240.             end
  241.         elseif is_pressed("left") then
  242.             if type(curmenu[curitem].item) == "function" then
  243.                 curmenu[curitem].item(increase)
  244.             end
  245.         elseif is_pressed("right") then
  246.             if type(curmenu[curitem].item) == "function" then
  247.                 curmenu[curitem].item(decrease)
  248.             end
  249.         elseif is_pressed("set") then
  250.             print("auto exposure, wait...")
  251.             autoexp()
  252.             sleep(1000)
  253.             -- update values in menu
  254.             tv96=get_tv96()
  255.             mainmenu[1].name=function() return(tostring(string.format("%s %d", "Tv", tv96))) end
  256.             av96=get_av96()
  257.             mainmenu[2].name=function() return(tostring(string.format("%s %d", "Av", av96))) end
  258.             --sv96=get_sv96()
  259.             --mainmenu[3].name=function() return(tostring(string.format("%s %d", "Sv", sv96))) end
  260.             manualexp()
  261.         elseif is_pressed("menu") then
  262.             break
  263.         end
  264.     end
  265. end
  266.  
  267. function restore()
  268.   if a==1 then
  269.     print("enabling autoexposure")
  270.     autoexp()
  271.   end
  272. end
  273.  
  274. manualexp()
  275.  
  276. -- startup values
  277. tv96=get_tv96()
  278. av96=get_av96()
  279. --sv96=get_sv96()
  280.  
  281. domenu()
  282. restore()
RAW Paste Data