Auto ETTR on EOSM

Started by Morghus, March 04, 2014, 12:46:37 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Morghus

Alright since I wanted to use my EOS M as a secondary timelapse camera I wanted to fix ETTR on it and finally dive into ML hacking. Here are a few things I discovered so far:


  • auto_ettr_step_lv_slow() and auto_ettr_on_request_task_slow() work, the quick fix would be to use them instead of the *_fast functions, but that's not what I want
  • the *_fast functions use CBR_VSYNC_SETPARAM to modify the exposures for each frame
  • in auto_ettr_vsync_cbr() the exposure is adjusted for each frame and on my 6D changes are visible immediately, on the M however, exposure is smoothly changed after around 1 second of delay, get_frame_iso() and get_frame_shutter_timer() still return the old value from the previous frame even though set_frame_iso() and set_frame_shutter_timer() have been called
  • the *_fast functions expect the exposure to change within 2 frames, it does not happen for some reason and so it over-compensates in each step
  • HDR video's hdr_step() uses a similar mechanism to change the exposure for each frame, although not exactly the same because it's not a module, ISO seems to change correctly and immediately for each frame

I'm stuck here... the quick fix would be to use the *_slow functions obviously, but it must be possible to fix auto_ettr_vsync_cbr(). I'd really appreciate it if someone pointed me into the right direction as this is my first time diving into ML code and I have no clue where to start. Is it possible that LV just behaves differently in movie mode? Can I put the camera into this mode if that's true? What other possibilities should I look into?

a1ex

That's a great start. Indeed, the key to fast ETTR in LiveView is to be able to change shuter speeds via FRAME_SHUTTER_TIMER (simply by setting it to some constant value from a vsync CBR). Also see this explanation: http://www.magiclantern.fm/forum/index.php?topic=9741.msg101808#msg101808

So, I would start by checking Canon's values at different shutter speeds, but considering EOS-M's quirks, I would do that while recording H.264. Then, you can cross-check the values with standby and photo modes, take into account the ExpSim mechanism, and see if you can get something useful out of it. In any case, FRAME_BV should indicate the overall exposure (8 units = 1 EV), and changes in FRAME_SHUTTER_TIMER should be consistent with changes in FRAME_SHUTTER. So, feel free to create a table with some values from these macros.

You may need to program directly in the core to access these macros, or copy their definition in the module while investigating.

Next, you should try to override these things; for ETTR, we are interested in overriding ISO (FRAME_ISO) and shutter speed (FRAME_SHUTTER_TIMER, which behaves like 1/exposure_time).

If it works, but it's changing smoothly, something's fishy. You might try to use exposure override, double-check the vsync input/state in the state transition (but this one looks OK from here), or hexdump the memory starting from VIDEO_PARAMETERS_SRC_3 and try to identify some more exposure variables (change Canon settings and see which offsets change).

Morghus

Thanks for your guidance so far, I did what you suggested:



I'm not really sure what happens there though. I can see where FRAME_ISO, FRAME_APERTURE, FRAME_SHUTTER and FRAME_SHUTTER_TIMER come from but setting FRAME_ISO or FRAME_SHUTTER_TIMER does not seem to have an effect. Every time the digit left of FRAME_BV changes, FRAME_ISO is set to ISO_100 or ISO_800 and you can see it change in the dump for a frame, LV does not seem to be affected though.

It's only smoothing in photo mode, in movie mode or with Expo. Override on it does not smooth the changes. Any other suggestions where I can poke at?




a1ex

So... setting FRAME_ISO and FRAME_SHUTTER_TIMER have no effect, but HDR video works. To be clear:

- did you try HDR video with ISO or also the advanced one with shutter?
- are these two things working in movie mode?
- are these two things working in expo override mode?

If the last answer is yes, you could try enabling expo override temporarily, from auto_ettr_prepare_lv. Look for "workaround for Canon's manual lens underexposure bug" and try using that for photo mode.

There is also a test in AUTO_ETTR_DEBUG; that one tests the vsync mechanism and checks if the exposure is indeed altered as requested (e.g. you request darkening by X EV, you get an image actually darker by X EV +/- a small measurement error).

This test should probably be moved to core code, in Debug menu, or maybe in raw_diag, to check this backend support everywhere (would cover LV RAW histogram, set_frame_iso/set_frame_shutter_timer and the vsync hook).

Morghus

Quick update to answer those three questions:



Expo override does not fix it.
While HDR video is doing its thing I can not see the changes it should be doing in the dump... I'll try that AUTO_ETTR_DEBUG test now.

a1ex

You don't see the changes because the module code runs before hdr video, and these things are reset by Canon code for each frame.

ETTR code actually assumes the exposure variables are reset by Canon code each time.

Morghus

I tried that AUTO_ETTR_DEBUG block and I assume those blue dots should be on the diagonal red line? They are all horizontal and when the scene changes they go up and down.

I also tried setting ISO and shutter in each call now, no effect. Just for clarificaion, the Advanced Bracketing/Movie HDR code runs after the vsync hook has been called? What is done in between? It seems to work for those two things and those are not modules with vsync hooks.

a1ex

Yes, the dots should be on the diagonal red line.

Advanced bracketing is for photos (does not use vsync).

Between HDR video (hdr_step) and your vsync hook there may be... other vsync hooks from other modules. The module vsync code is actually called from hdr_step.

Morghus

That is useful information, I didn't know what that line was doing in hdr_step() but I couldn't find any other references to that, so it makes sense that the module callback is called from in there.

I did a quick test in hdr_step(), changing the ISO and shutter timer in some intervals and it only works while recording h264. Movie mode and not recording, or photo mode => no dice.


Edit: I moved the same code to the ettr callback and it seems to work there too when recording... I'm not sure why it didn't work yesterday, must have been something I missed

a1ex

You could try playing with the state object hooks; it's mostly trial and error. This vsync hook runs in Canon's LiveView task (EVF), which is this one: http://a1ex.bitbucket.io/ML/states/EOSM-alt/sm28.htm

I suggest trying all the inputs from state 5 that do not change the state.

Another possibility is to rewrite the backend in order to override shutter via ADTG. This one should be a little more portable but we need to find a hook point for it first (on 5D3 I found something in DebugMsg, but it's not exactly portable and was not designed as a replacement for FRAME_SHUTTER_TIMER, so it may need some major rewrite).

Morghus

I tried setting the ISO in all inputs of state 5, no dice... it works when starting to record a movie, but outside of that it doesn't. At least I think I tried it. As far as I know this code should do that:

state-object.c:
   
...
#ifdef EVF_STATE

    if (self == EVF_STATE && old_state == 5)
    {
    int iso = vsync_counter % 2 ? 72 : 96;
    set_frame_iso(iso);
    NotifyBox(1000, "%d", iso);
    }

...



a1ex

What about:


if (self == EVF_STATE)
    {
    int iso = rand() % 2 ? 72 : 96;
    set_frame_iso(iso);
    //NotifyBox(1000, "%d", iso); /* don't enable this one, since it may slow down liveview */
    }


If that one works, all it's left is to narrow down the state/transition pair.

Morghus

Nope, same behavior, no flickering until I start recording a movie, and flickering stops when recording stops :( If my understanding is right, the evfSetParamInterrupt input is called/spied on when LV is ready to accept new exposure params in the memory addresses?

a1ex

Yap.

In this case... I'm afraid the only solution is to do this via ADTG. Will push a workaround meanwhile so it falls back to the slow method.

Let me know if this works: https://bitbucket.org/hudson/magic-lantern/commits/a6ff18c6aa44

Morghus

It works for Always ON and HalfS DblClick, Auto Snap and using ETTR with the intervalometer doesn't seem to work, maybe something goes wrong while analyzing the image in image review? (I set it to 2 sec) Also, the Press SET trigger doesn't work since the M has a combined Q/SET button, maybe we can remove this entry for the M.

a1ex

Probably it's worth checking button codes; do you get a BGMT_PRESS_SET event in LiveView?

If half-shutter trigger is working, I guess the preconditions are all OK, so... the only thing left is the button code, no?

1%

Photo mode and not recording H264 are actually the same as 60P just cut down to 30 fps. I could have sworn that the shutter fine tuning worked at rest though.

Morghus

in auto_ettr_keypress_cbr
if (!display_idle()) return 1;
causes it to stop handling the event when Q/SET is pressed, even though the event gets there correctly with the right codes... this is because when you press that button, the Q menu comes up
if (key == MODULE_KEY_PRESS_SET) {
    NotifyBox(100, "SET PRESSED %d %d %d", AUTO_ETTR_TRIGGER_BY_SET, key == MODULE_KEY_PRESS_SET, key);
}

works before the display_idle check, not after

a1ex

This means the Q menu already came up before the SET event (so it must be some other event).

Can you find that event and try to block it? (that is, return 0 when you receive that event)

1%

same behavior both ways, on to something

Morghus

Alright that took a while... Since gui.h contains this
#define BGMT_Q TOUCH_1_FINGER
and key codes are mapped to different values in module.c (and unknown ones mapped to 0) I couldn't access the key code in the module. By outputting the pressed raw keycodes in module.c I was able to find out that blocking 0x1d in handle_module_keys prevents the quick menu from being opened, but that also blocks the BGMT_PRESS_SET event for some reason. However, it does not block the BGMT_UNPRESS_SET event so listening for that to start ETTR I could get it to work by also translating the 0x1d key code to a module code. While ETTR is enabled and set to Press SET, the quick menu becomes inaccessible though... would that be preferable to not being able to use SET as a trigger? I can clean up the code and submit a pull request if yes.

1%

does ETTR + intervalometer work after the fix? I'm only able to use it in TV/AV not M... it just never adjusts in the QR

Morghus

No it doesn't work there yet, something doesn't work after analyzing the photo in image review, it should work in manual always on or with halfs dblclick

a1ex

In "always on", whatever it does in QR will be canceled as soon as you get back to LiveView.

This probably needs re-thought for EOS-M; on other cameras, this mode is meant to be used outside LiveView.

Morghus

So a CONFIG_IS_MIRRORLESS or CONFIG_EVF_ONLY or something should be introduced and then disable the parts where it tries to change things outside LV? I figure the EOS M and M2 won't be the last mirrorless cameras from canon and other ones probably should behave like the M.

Also:
Quote from: Morghus on March 05, 2014, 11:11:41 PM
While ETTR is enabled and set to Press SET, the quick menu becomes inaccessible though... would that be preferable to not being able to use SET as a trigger? I can clean up the code and submit a pull request if yes.
Where would be the right place to discuss this?