I don't know how Dan wrote his code for motion. I know that he didn't spend much time on it, so we don't have much invested in Motion. If you can think of a better way, we don't have to stick to the current implementation much.
I can comment, though, on the structure as I see it from DCE's standpoint. If you look at the Device Template for "Generic Analog Camera", you'll see that Implements DCE is *not* checked. That means this is a dumb device--dumb in the sense that there is no code that will be run for this device. Some other device--an intelligent device--will need to be responsible for all the code. That device will be the 'Controlled Via' device, or the parent device when you look at the tree in Advanced Devices. A device is responsible for handling all the code for it's children that do not implement DCE.
You see that the Camera has: This device is controlled via category: Category: Generic Analog Capture Card. That section of the device template page is where you specify what are the valid choices for the parent (or controlled via). If you don't specify anything in either of the "This device is controlled via", then when the user creates this device, he can pick any parent/controlled via device he wants. He could stuck a camera underneath the Xine DVD Player, for example. If the Camera was an intelligent device that *did* implement DCE, this actually would be okay. According to the framework, each device just spawns all of it's intelligent children as separate devices. So, if the camera implemented DCE (meaning had it's own binary executible), you could make the parent anything you wanted. If it was Xine, Xine would just spawn the program 'Camera' and let it take care of itself.
But since the 'Camera' is not an intelligent device, the parent/Controlled Via must be specified since that device needs to know what to do with it, and if the user put a dumb Camera as a child of Xine, Xine would just ignore it not knowing what it was.
So, the first question is: Is this structure with an intelligent device (the capture card) and dumb children (the cameras) correct? With the structure the way it is now, that means there is only 1 binary, 1 thread that is going to be spawned--the Capture Card (the intelligent device that implements DCE). The capture card's child devices (the cameras), as dumb devices, are really nothing more than a 'for your information' for the capture card. So, when you wrote: "I don't get threads properly activated and started" for the cameras, understand that with this structure the Pluto DCE framework will not spawn any threads or devices for the cameras--Pluto will only spawn 1 thread for the capture card, which must do whatever it needs to do internally to support the cameras.
Going back to the issue of 'is this the right approach', note that it's possible to mix. You can have some cameras that are intelligent devices, with their own binaries, and others that are not.
We have this same mixture throughout Pluto. For example, most of the time light switches are dumb devices. With X10, there's only 1 intelligent device--the CM11A interface--and that's the only thread that's run. A light switch called "Living Room Light" is actually just a dumb device. When the user hits the button to run on the Living Room Light, the "ON" command ends up in the CM11A device, which has the code to handle the "ON" command--it just looks up the child device, looks up the house code from it's data, and then sends the X10 command. But, later, someone may add an intelligent light switch that acts independently, without needing a cm11a interface. In this case, the light swith would be "intelligent" (ie implement DCE) and would get it's commands itself. From the users standpoint, there is no difference. Whether a device implements DCE isn't even shown on any of the wizard pages--it's too technical. The user just adds light switches and knows that they can turn any switch on. Where the code resides is unimportant.
So, it sounds like there may be a similar mix for motion, where some cameras are intelligent and some are dumb. When you're using a single capture board, like the Grandtek BT878-based 16-port analog board we use, it seems to make the most sense that the cameras are dumb. You don't want to run 16 different programs for each of the cameras--you just want 1 program that runs for the capture board. When a command is sent to provide a video frame from camera #5, then you want that command to go to the single device for the capture board, and the capture board device will grab a frame from port #5.
However, in the case of USB cameras, perhaps the cameras should be intelligent (implement DCE and have their own device) since there is no 'capture board' device that will handle the logic for them.
Therefore, from a hardware standpoint, the way I would see the devices is as follows (smart devices shown in caps, dumb in lower case).
GRANDTEK BT878 CAPTURE BOARD
generic analog camera #1
generic analog camera #2
generic analog camera #3
IP BASED CAMERA
From the user's standpoint (ie the wizard), this arrangement is very clean. When they add a USB camera or IP Camera, as an intelligent device, the parent/Controlled Via device is just the PC that the software runs on. But when the user adds a "generic analog camera" device, the wizard pages will automatically require him to first add the capture board, and will make the capture board the parent device. In the above example, then, 3 separate programs would be run by the framework: the capture board, the USB camera, and the IP Camera.
However, this whole situation does get a little more fuzzy in my mind when Motion enters the picture. If there were only the GRANDTEK capture board and it's analog cameras, it wouldn't be so difficult. The Grandtek capture board would be both the wrapper for motion, as well as having the logic for controlling the analog cameras. However, in the above example, where does motion enter the picture? In that example, there are 3 intelligent devices, which will therefore all be spawned as 3 completely separate devices. Should all 3 of them have their own copy of motion, making them completely independent? That's one possibility. But what if you want only 1 copy of motion for both the analog cameras, USB cameras, and IP Cameras? In that case, I can think of two possibilities. First, leave them as shown, with 3 separate devices. However, each of the 3 devices (GRANDTEK, USB, IP CAM) will attempt to connect with a Motion back-end, starting it if it's not already started, and each will work with motion. In that case motion doesn't exist as a separate device, but rather a tool that all 3 devices will use. The second possibility would be to create a device called Motion that was a wrapper for motion, and then make the 3 devices children of motion (the analog cameras would be grand-children then).
Normally, when we're creating a new, major module, the senior developers get together and brainstorm to be sure we come up with the most logical structure that will grow with us. At the moment we're all pretty busy with Media, Orbiter, the Installer, and our focus has been on getting 1 piece--the media--to work flawlessly before branching out too much, so we just kind of gave Dan H the task of getting a motion interface going--something basic that would work for our demo. It hasn't been really thought out, and I haven't even looked at Dan's code before to see what he did. But, from peeking at it now, it seems this was his intention:
There's only 1 intelligent device which a combination of both a motion wrapper, and an interface for the analog capture board we gave him (the bt878 based Grandtek). The child devices (the cameras) are dumb devices. In the constructor, Generic_Analog_Capture_Card::Generic_Analog_Capture_Card, he doesn't appear to actually look at his list of child devices (cameras), which one would normally expect of a device that has dumb children. The children are in m_pData->m_vectDeviceData_Impl_Children. Normally I would have expected him to see what kind of children he had and how many there were. But it appears that the capture card device has a device data parameter, DATA_Get_Number_of_ports(), and so he just creates a generic threadX conf file for each port. This isn't really complete. There are likely parameters that should be specific to each camera, such as sensitivity to motion, etc. So the dumb camera device should have a device data parameter like 'sensity level', and the constructor should iterate through it's children, reading DATA_Get_Sensitivity_Level() for each of the child cameras, and write out the specific settings for each camera.
There's only 1 command involved, "Get Video Frame". Since the child cameras are dumb devices, any commands to them come in this, the parents, Generic_Analog_Capture_Card::ReceivedCommandForChild function. Here he find the child device (the camera) that is the target of the command. // find child device There's only 1 command: case COMMAND_Get_Video_Frame_CONST: He gets the port number of the camera: string sPortNumber = pDeviceData->mapParameters_Find(DEVICEDATA_Port_Number_CONST);
So the framework that's there is really simple. He's got about 65 lines for the constructor, and 50 lines to get a frame, and that's the whole extent. What he wrote would seem to work okay if there's only 1 capture card in the system, but doesn't really have any means to account for USB cameras, IP Cameras, or be a full-fledged video monitoring solution. BTW, that's ok--that was Dan's instructions, to throw something together quick for the video surveillance since we had to do a demo.
In terms of a more robust solution, without knowing much about how motion works, my gut feeling would be to use a structure like that shown above, with no specific device for motion, and then let all the devices that need motion to either spawn their own copy of motion, or attach to a shared one. I remember from series 1 that Motion can require a lot of CPU, particularly with lots of cameras. So, we were directing customers with lots of cameras away from the analog capture card in favor of IP cameras which had their own motion detection built-in. Making motion a separate device, and making the user decide what cameras use motion and what don't might be complicated. So, by taking Motion out of the picture, then in the example above, the DCE Device for the Grandtek capture board may use motion, as may the USB Camera, but the IP Camera may not, if it has its own motion detection built-in.
I'll talk to Dan about it, and since you understand motion (and hopefully after this long discourse more about DCE), let me know your ideas too.