Guest User

VideExp.lua

a guest
Aug 22nd, 2010
331
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/23
  4.  
  5. Requires CHDK built with native call support
  6. Thanks to ewavr (method) and reyalp (lua things, eventprocs)
  7.  
  8. This script uses several event procedures (native function calls) which supposedly are
  9. portable across many camera models, but may not exist or may fail to work on others
  10. or the way to register them on a570 may cause problems. In addition, even on the
  11. author's a570 100e this script causes frequent crashes.
  12.  
  13. You have been warned, try at your own risk!
  14.  
  15. If 1, camera will reset to autoexposure when script ends:
  16. @param a set auto exp on exit?
  17. @default a 1
  18.  
  19. How large adjust steps to use. 32 is 1/3 stop, 96 is full stop:
  20. @param b tv96 step (96=full stop)
  21. @default b 32
  22. @param c av96 step (96=full stop)
  23. @default c 32
  24. @param d sv step (unknown unit)
  25. @default d 128
  26.  
  27. The script uses certain camera functions to set exposure values. Tv and Av functions
  28. appear to return whatever value they actually set. If this argument is zero,
  29. the camera return value is used as the current exposure value shown on the console
  30. and as the seed value for the next adjustment. Thus the camera may will limit
  31. the adjustment range. If you feel brave and optimistic, set this to '1' to see if
  32. you can go further than the camera wants to let you go. On a570 it looks like camera
  33. limits are at or near CHDK override limits, not the usual Canon UI limits.
  34.  
  35. There are built-in limits in the script too, you may need to relax them too to do this:
  36. @param e override cam limits
  37. @default e 0
  38. --]]
  39.  
  40.  
  41. --[[
  42. todo:
  43. - find a way to get working start value for ISO (currently just gives 0 which is not right)
  44. - show Av in 1/f
  45. - show Tv in milliseconds or fractional or divisor from video frame rate
  46. - ND filter control (ExpCtrlTool.ND or whatever CHDK uses?). I can't do this since I don't have a suitable camera.
  47. --]]
  48.  
  49. TVSTEP=b
  50. AVSTEP=c
  51. SVSTEP=d
  52. OVERRIDE=e
  53.  
  54. -- don't run in play mode
  55. rec,vid,mode=get_mode()
  56. print("rec:",rec,"vid:",vid)
  57. sleep(1000)
  58. if rec~=true then
  59.   error("Not in rec mode.")
  60. end
  61.  
  62. --**************************************************************************
  63. -- configure limiting values here
  64. --**************************************************************************
  65. -- tv96 is tied to exposure time in seconds by equation tv = 2^-(tv96/96)
  66. 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)
  67.  
  68. -- av96 is tied to aperture number N in f/N by equation av96 = 96 * 2*log2(N)
  69. av96_min=2*96
  70. --av96_min=get_prop(prop.MIN_AV) -- returns 0 for my cam, which sounds dangerous (literally). Also, require "propcase" hangs during video record.
  71. av96_max=8*96 -- (f/16)
  72.  
  73. -- sv96 is tied to ISO speed rating S by equation sv96 = 96 * 2*log2(S/3.125)
  74. -- but the sv96 used in this script is not really sv96. I don't know what it is,
  75. -- possibly a 10-bit PGA amp gain control setting ranging from 0 to 1024 for ISO100 to ISO800 (or 1600, but that's a software mode)
  76. -- that's a 3 Ev range, so a step size of 128 crudely approximates 1/3 stop change
  77. sv96_min=0
  78. sv96_max=2000
  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. -- this is required for event procedures SetAE_ShutterSpeed, MoveIrisToAv, SetCDSGain
  95. if (call_event_proc("InitializeAdjustmentFunction") == -1) then
  96.     error("InitializeAdjustmentFunction failed")
  97. end
  98.  
  99. -- returns 0 if no ND present, 1 if ND present and real diaphragm NOT present, 2 if both ND & diaphragm present.
  100. nd=get_nd_present()  
  101. if nd==1 then
  102.   iris=false
  103. else
  104.   iris=true
  105. end
  106.  
  107. -- to make lua happy
  108. tv96=get_tv96()
  109. av96=get_av96()
  110. sv96=get_sv96()
  111.  
  112. decrease=0
  113. increase=1
  114.  
  115. -- 1/3 stop Tv adjustment
  116. -- too slow tv crashes the cam.
  117. function tv_adj(incr)
  118.     if incr==increase then
  119.         tv96=tv96-TVSTEP
  120.     else
  121.         tv96=tv96+TVSTEP
  122.     end
  123.     -- prevent tv from going slower than safe minumum or higher than signed short can go
  124.     if tv96<tv96_min then
  125.         tv96=tv96_min
  126.     elseif tv96>32767 then
  127.         tv96=32767
  128.     end
  129.     -- adjust tv
  130.     ret=call_event_proc("SetAE_ShutterSpeed",tv96)
  131.     -- Canon's function seems to return sane values, let's use them as limits:
  132.     if OVERRIDE ~= 1 then
  133.       tv96=ret
  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 iris==true then
  142.         if incr==increase then
  143.             av96=av96-AVSTEP
  144.         else
  145.             av96=av96+AVSTEP
  146.         end
  147.         -- prevent tv from going slower than safe minumum or higher than signed short can go
  148.         if av96<av96_min then
  149.             av96=av96_min
  150.         elseif av96>av96_max then
  151.             av96=av96_max
  152.         end
  153.         -- adjust iris
  154.         ret=call_event_proc("MoveIrisToAv",av96)
  155.         -- Canon's function seems to return sane values, let's use them as limits:
  156.         if OVERRIDE ~= 1 then
  157.           av96=ret
  158.         end
  159.         -- change menu text to show new value
  160.         curmenu[curitem].name=function() return(tostring(string.format("%s %d", "Av", av96))) end
  161.     end
  162. end
  163.  
  164. function sv_adj(incr)
  165.     if incr==increase then
  166.         sv96=sv96-SVSTEP
  167.     else
  168.         sv96=sv96+SVSTEP
  169.     end
  170.     -- range limit
  171.     if sv96<sv96_min then
  172.         sv96=sv96_min
  173.     elseif sv96>sv96_max then
  174.         sv96=sv96_max
  175.     end
  176.     -- 0 to 1024 vale range to ISO 100--800 or 1600 range (I think)
  177.     ret=call_event_proc("SetCDSGain",sv96)
  178.     --print("SetCDSGain="..ret)  
  179.     --this one appears to return 0 always
  180.     --sleep(500)
  181.     curmenu[curitem].name=function() return(tostring(string.format("%s %d", "Sv", sv96))) end
  182. end
  183.  
  184. -- go to manual exposure mode
  185. function manualexp()
  186.     ret=call_event_proc("ExpCtrlTool.StopConti")
  187.     if ret==-1 then
  188.       error("ExpCtrlTool.StopConti failed")
  189.     end
  190. end
  191.  
  192. -- go to auto exposure mode
  193. function autoexp()
  194.     call_event_proc("ExpCtrlTool.StartConti")
  195.     if ret==-1 then
  196.       error("ExpCtrlTool.StartConti failed")
  197.     end
  198. end
  199.  
  200. function menuitem(name,item)
  201.     t={item = item}
  202.     if type(name) ~= "function" then
  203.         t.name = function()
  204.             return(tostring(name))
  205.         end
  206.     else
  207.         t.name = name
  208.     end
  209.     return t
  210. end
  211.  
  212. mainmenu={
  213.     menuitem("Tv "..tv96,tv_adj),
  214.     menuitem("Av "..av96,av_adj),
  215.     menuitem("Sv "..sv96,sv_adj),
  216. }
  217.  
  218. function domenu()
  219.     curmenu=mainmenu
  220.     curitem=1
  221.     while true do
  222.         cls()
  223.         print("U/D:pick |    quit:MENU")
  224.         print("L/R:adj  | autoexp:SET ")
  225.         if curitem > 1  then
  226.             print(string.format("|%s",curmenu[curitem-1].name()))
  227.         else
  228.             print("-----------------------")
  229.         end
  230.         print(string.format(">%s",curmenu[curitem].name()))
  231.         if curmenu[curitem+1] then
  232.             print(string.format("|%s",curmenu[curitem+1].name()))
  233.         else
  234.             print("-----------------------")
  235.         end
  236.         wait_click(5000)
  237.         if is_pressed("down") then
  238.             if curmenu[curitem+1] then
  239.                 curitem = curitem + 1
  240.             end
  241.         elseif is_pressed("up") then
  242.             if curitem > 1 then
  243.                 curitem = curitem - 1
  244.             end
  245.         elseif is_pressed("left") then
  246.             if type(curmenu[curitem].item) == "function" then
  247.                 curmenu[curitem].item(increase)
  248.             end
  249.         elseif is_pressed("right") then
  250.             if type(curmenu[curitem].item) == "function" then
  251.                 curmenu[curitem].item(decrease)
  252.             end
  253.         elseif is_pressed("set") then
  254.             print("auto exposure, wait...")
  255.             autoexp()
  256.             sleep(1000)
  257.             -- update values in menu
  258.             tv96=get_tv96()
  259.             mainmenu[1].name=function() return(tostring(string.format("%s %d", "Tv", tv96))) end
  260.             av96=get_av96()
  261.             mainmenu[2].name=function() return(tostring(string.format("%s %d", "Av", av96))) end
  262.             sv96=get_sv96()
  263.             mainmenu[3].name=function() return(tostring(string.format("%s %d", "Sv", sv96))) end
  264.             manualexp()
  265.         elseif is_pressed("menu") then
  266.             break
  267.         end
  268.     end
  269. end
  270.  
  271. function restore()
  272.   if a==1 then
  273.     print("enabling autoexposure")
  274.     autoexp()
  275.   end
  276. end
  277.  
  278. manualexp()
  279.  
  280. -- startup values
  281. tv96=get_tv96()
  282. av96=get_av96()
  283. sv96=get_sv96()
  284.  
  285. domenu()
  286. restore()
RAW Paste Data