Make PROP_HANDLER(PROP_ORIENTATION) work outside of LiveView?

Started by 1ab, October 02, 2012, 12:24:46 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

1ab

Hi,

I am a newbie to ML, just went through the Getting Started With Development docs and skimmed some of the *.h files. Since I have no experience at all with coding so close to hardware, I will most probably be missing a lot of things, however, I like the idea of event handlers and in PROP_HANDLER() from property.h I thought I found something that I could use. However, it seems to work differently than I expected, or I may not be using it correctly,  or I may need to take an all-different approach. Any help appreciated.

My goal: I'd like to implement an ML contribution about the AF points when the camera is turned into +/-90deg positions. Basically two operation modes, "remember" should allow me to set different AF points (or different patterns via ML's Focus Pattern feature) for each camera orientation. "follow turn" should automatically turn the focus pattern with the camera, so that, if I have selected an "upper" pattern to focus a person's face rather than feet, and I turn the camera around any way (i.e. not only from landscape to +/-90deg portrait or vice versa, but also upside-down from -90deg directly to +90deg), still have the focus points at the person's face rather than feet. (It would help me a lot for action/candid shots.)
The high-level implementation of this feature does actually not seem to be too difficult, see the code below.

My approach: To use PROP_HANDLER(PROP_ORIENTATION) seems to be just the right thing to be notified from the camera when the camera is turned around, so that I can then switch the AF points around (and using some similar code as in af_patterns.c to achieve the latter).

My problem: When I test my implementation on my camera, a 550D, it works only in Liveview mode with QuickFocus (clang-clatter-clunk mode), but it does not work in normal viewfinder photography mode. The problem seems to be that PROP_HANDLER(PROP_ORIENTATION) is not called for a camera turnaround/turnover when liveview is off.

My question: Any other way / any working way by which my code could get notified when the camera is turned around? In order to be actually useable, it should work in normal viewfinder mode first place, and whether it also works in liveview is negligible.

focus-orientation.h:

#define ORI_HORIZONTAL 0
#define ORI_PLUS90DEG  1
#define ORI_MINUS90DEG 2

typedef enum {
    FO_DISABLE,
    FO_REMEMBER,
    FO_FOLLOW_TURN
} type_FOCUS_ORIENTATION_MODE;


focus-orientation.c:

#include "dryos.h"
#include "bmp.h"
#include "menu.h"
#include "property.h"
#include "config.h"
#include "gui.h"
#include "af_patterns.h"
#include "focus-orientation.h"

#define NUM_ORIENTATIONS 3 // Cameras seem to use only 3 actually, is there none for upside down?
int orientation = 0;
int old_orientation = 0;
int focuspoints[NUM_ORIENTATIONS][2] = { { 0, 0 }, {0, 0}, {0, 0}, {0, 0} };

typedef struct {
    int focuspoint;
    int turnleft;  /* -90deg */
    int turnright; /* +90deg */
    int mirror_rightleft;
} type_FOCUS_TURN;

type_FOCUS_TURN focus_turns[] = {
    { AF_POINT_C , AF_POINT_C , AF_POINT_C , AF_POINT_C },
    { AF_POINT_T , AF_POINT_R , AF_POINT_L , AF_POINT_T },
    { AF_POINT_B , AF_POINT_L , AF_POINT_R , AF_POINT_B },
    { AF_POINT_L , AF_POINT_T , AF_POINT_B , AF_POINT_R },
    { AF_POINT_R , AF_POINT_B , AF_POINT_T , AF_POINT_L },
    { AF_POINT_TL, AF_POINT_TR, AF_POINT_BL, AF_POINT_TR},
    { AF_POINT_TR, AF_POINT_BR, AF_POINT_TL, AF_POINT_TL},
    { AF_POINT_BL, AF_POINT_TL, AF_POINT_BR, AF_POINT_BR},
    { AF_POINT_BR, AF_POINT_BL, AF_POINT_TR, AF_POINT_BL},
    { 0, 0, 0, 0}
};


// much the same as in af_patterns.c
// to be generalized somehow??
int focuspoint[2] = { 0, 0 };
int focuspoint_len = 0;
PROP_HANDLER(PROP_AFPOINT)
{
    focuspoint[0] = buf[0];
    focuspoint[1] = buf[1];
    focuspoint_len = len;
}


void orientation_focuspoints()
{
    /*extern*/ int focus_orientation_mode = FO_FOLLOW_TURN;

    if (focuspoint_len != 0)
    {
        switch(focus_orientation_mode)
        {
            case FO_REMEMBER:
            {
                focuspoints[old_orientation][0] = focuspoint[0];
                focuspoints[old_orientation][1] = focuspoint[1];
                if ((focuspoints [orientation][0] != 0) || (focuspoints [orientation][1] != 0))
                {
                    bmp_printf(FONT_LARGE, 10, 280, "New: %d    ", focuspoints [orientation][0]);
                    prop_request_change(PROP_AFPOINT, focuspoints [orientation], focuspoint_len);
//                    task_create("focus_orientation_showInVF", 0x18, 0, afp_show_in_viewfinder, 0);
                }
                break;
            }
            case FO_FOLLOW_TURN:
            {
                int new_focuspoint = 0;
                if ((old_orientation == ORI_HORIZONTAL && orientation == ORI_PLUS90DEG)
                    || (old_orientation == ORI_MINUS90DEG && orientation == ORI_HORIZONTAL))
                { // rel+90deg, turn right
                    type_FOCUS_TURN *item;
                    for(item=focus_turns; item->focuspoint != 0; item++)
                    {
                        if (focuspoint[0] & item->focuspoint)
                        {
                            new_focuspoint |= item->turnright;
                        }
                    }
                }
                else if ((old_orientation == ORI_HORIZONTAL && orientation == ORI_MINUS90DEG)
                    || (old_orientation == ORI_PLUS90DEG && orientation == ORI_HORIZONTAL))
                { // rel-90deg, turn left
                    type_FOCUS_TURN *item;
                    for(item=focus_turns; item->focuspoint != 0; item++)
                    {
                        if (focuspoint[0] & item->focuspoint)
                        {
                            new_focuspoint |= item->turnleft;
                        }
                    }
                }
                else if ((old_orientation == ORI_PLUS90DEG && orientation == ORI_MINUS90DEG)
                    || (old_orientation == ORI_MINUS90DEG && orientation == ORI_PLUS90DEG))
                { // turn over/upsidedown portrait -> mirror rightleft
                    type_FOCUS_TURN *item;
                    for(item=focus_turns; item->focuspoint != 0; item++)
                    {
                        if (focuspoint[0] & item->focuspoint)
                        {
                            new_focuspoint |= item->mirror_rightleft;
                        }
                    }
                }
                if (new_focuspoint != 0)
                {
                    prop_request_change(PROP_AFPOINT, &new_focuspoint, focuspoint_len);
//            task_create("focus_orientation_showInVF", 0x18, 0, afp_show_in_viewfinder, 0);
                }
                break;
            }
        }
    }
}

PROP_HANDLER(PROP_ORIENTATION)
{
    if (buf[0] < NUM_ORIENTATIONS)
    {
        old_orientation = orientation;
        orientation = buf [0];
        task_create("orientation_focuspoints", 0x18, 0, orientation_focuspoints, 0);
    }
}