1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #include "mmal.h" |
29 | #include "core/mmal_component_private.h" |
30 | #include "core/mmal_port_private.h" |
31 | #include "util/mmal_graph.h" |
32 | #include "mmal_logging.h" |
33 | |
34 | #define AGGREGATOR_PREFIX "aggregator" |
35 | #define AGGREGATOR_PIPELINE_PREFIX "pipeline" |
36 | |
37 | typedef struct MMAL_GRAPH_USERDATA_T { |
38 | int dummy; |
39 | } MMAL_GRAPH_USERDATA_T; |
40 | |
41 | static MMAL_STATUS_T aggregator_parameter_set(MMAL_GRAPH_T *graph, |
42 | MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param) |
43 | { |
44 | MMAL_PARAM_UNUSED(graph); |
45 | MMAL_PARAM_UNUSED(port); |
46 | MMAL_PARAM_UNUSED(param); |
47 | LOG_TRACE("graph %p, port %p, param %p" , graph, port, param); |
48 | return MMAL_ENOSYS; |
49 | } |
50 | |
51 | static MMAL_STATUS_T aggregator_parameter_get(MMAL_GRAPH_T *graph, |
52 | MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) |
53 | { |
54 | MMAL_PARAM_UNUSED(graph); |
55 | MMAL_PARAM_UNUSED(port); |
56 | MMAL_PARAM_UNUSED(param); |
57 | LOG_TRACE("graph %p, port %p, param %p" , graph, port, param); |
58 | return MMAL_ENOSYS; |
59 | } |
60 | |
61 | /** Create an instance of a component */ |
62 | static MMAL_STATUS_T mmal_component_create_aggregator_pipeline(const char *full_name, |
63 | const char *component_names, MMAL_COMPONENT_T *component) |
64 | { |
65 | MMAL_GRAPH_T *graph = 0; |
66 | MMAL_COMPONENT_T *subcomponent[2] = {0}; |
67 | MMAL_STATUS_T status = MMAL_ENOMEM; |
68 | unsigned int length; |
69 | char *orig, *names; |
70 | |
71 | length = strlen(component_names); |
72 | names = orig = vcos_calloc(1, length + 1, "mmal aggregator" ); |
73 | if (!names) |
74 | goto error; |
75 | memcpy(names, component_names, length); |
76 | |
77 | /* We'll build the aggregator using a graph */ |
78 | status = mmal_graph_create(&graph, sizeof(MMAL_GRAPH_USERDATA_T)); |
79 | if (status != MMAL_SUCCESS) |
80 | goto error; |
81 | graph->pf_parameter_get = aggregator_parameter_get; |
82 | graph->pf_parameter_set = aggregator_parameter_set; |
83 | |
84 | /* Iterate through all the specified components */ |
85 | while (*names) |
86 | { |
87 | MMAL_CONNECTION_T *connection; |
88 | const char *name; |
89 | |
90 | /* Switch to a new connection */ |
91 | if (subcomponent[0]) |
92 | mmal_component_destroy(subcomponent[0]); |
93 | subcomponent[0] = subcomponent[1]; |
94 | subcomponent[1] = 0; |
95 | |
96 | /* Extract the name of the next component */ |
97 | for (name = names; *names && *names != ':'; names++); |
98 | |
99 | /* Replace the separator */ |
100 | if (*names) |
101 | *(names++) = 0; |
102 | |
103 | /* Skip empty strings */ |
104 | if (!*name) |
105 | continue; |
106 | |
107 | status = mmal_component_create(name, &subcomponent[1]); |
108 | if (status != MMAL_SUCCESS) |
109 | goto error; |
110 | |
111 | status = mmal_graph_add_component(graph, subcomponent[1]); |
112 | if (status != MMAL_SUCCESS) |
113 | goto error; |
114 | |
115 | /* Special case for dealing with the first component in the chain */ |
116 | if (!subcomponent[0]) |
117 | { |
118 | /* Add first input port if any */ |
119 | if (subcomponent[1]->input_num) |
120 | { |
121 | status = mmal_graph_add_port(graph, subcomponent[1]->input[0]); |
122 | if (status != MMAL_SUCCESS) |
123 | goto error; |
124 | } |
125 | continue; |
126 | } |
127 | |
128 | /* Create connection between the 2 ports */ |
129 | if (subcomponent[0]->output_num < 1 || subcomponent[1]->input_num < 1) |
130 | goto error; |
131 | status = mmal_connection_create(&connection, subcomponent[0]->output[0], |
132 | subcomponent[1]->input[0], 0); |
133 | if (status != MMAL_SUCCESS) |
134 | goto error; |
135 | |
136 | status = mmal_graph_add_connection(graph, connection); |
137 | /* Now the connection is added to the graph we don't care about it anymore */ |
138 | mmal_connection_destroy(connection); |
139 | if (status != MMAL_SUCCESS) |
140 | goto error; |
141 | } |
142 | |
143 | /* Add last output port if any */ |
144 | if (subcomponent[1] && subcomponent[1]->output_num && subcomponent[1]->output[0]) |
145 | { |
146 | status = mmal_graph_add_port(graph, subcomponent[1]->output[0]); |
147 | if (status != MMAL_SUCCESS) |
148 | goto error; |
149 | } |
150 | |
151 | /* Build the graph */ |
152 | component->priv->module = (struct MMAL_COMPONENT_MODULE_T *)graph; |
153 | status = mmal_graph_component_constructor(full_name, component); |
154 | if (status != MMAL_SUCCESS) |
155 | goto error; |
156 | |
157 | end: |
158 | if (subcomponent[0]) |
159 | mmal_component_destroy(subcomponent[0]); |
160 | if (subcomponent[1]) |
161 | mmal_component_destroy(subcomponent[1]); |
162 | vcos_free(orig); |
163 | return status; |
164 | |
165 | error: |
166 | if (graph) |
167 | mmal_graph_destroy(graph); |
168 | goto end; |
169 | } |
170 | |
171 | /** Create an instance of a component */ |
172 | static MMAL_STATUS_T mmal_component_create_aggregator(const char *name, MMAL_COMPONENT_T *component) |
173 | { |
174 | const char *stripped = name + sizeof(AGGREGATOR_PREFIX); |
175 | |
176 | /* Select the requested aggregator */ |
177 | if (!strncmp(stripped, AGGREGATOR_PIPELINE_PREFIX ":" , sizeof(AGGREGATOR_PIPELINE_PREFIX))) |
178 | return mmal_component_create_aggregator_pipeline(name, |
179 | stripped + sizeof(AGGREGATOR_PIPELINE_PREFIX), component); |
180 | |
181 | return MMAL_ENOSYS; |
182 | } |
183 | |
184 | MMAL_CONSTRUCTOR(mmal_register_component_aggregator); |
185 | void mmal_register_component_aggregator(void) |
186 | { |
187 | mmal_component_supplier_register(AGGREGATOR_PREFIX, mmal_component_create_aggregator); |
188 | } |
189 | |