rpicamsrc: fix indentation
[platform/upstream/gstreamer.git] / sys / rpicamsrc / RaspiPreview.c
1 /* *INDENT-OFF* */
2 /*
3  * Copyright (c) 2013-2015 Jan Schmidt <jan@centricular.com>
4 Portions:
5 Copyright (c) 2013, Broadcom Europe Ltd
6 Copyright (c) 2013, James Hughes
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
11     * Redistributions of source code must retain the above copyright
12       notice, this list of conditions and the following disclaimer.
13     * Redistributions in binary form must reproduce the above copyright
14       notice, this list of conditions and the following disclaimer in the
15       documentation and/or other materials provided with the distribution.
16     * Neither the name of the copyright holder nor the
17       names of its contributors may be used to endorse or promote products
18       derived from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
24 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <memory.h>
36 #include <gst/gst.h>
37
38 #include "interface/vcos/vcos.h"
39
40 #include "interface/mmal/mmal.h"
41 #include "interface/mmal/mmal_logging.h"
42 #include "interface/mmal/mmal_buffer.h"
43 #include "interface/mmal/util/mmal_util.h"
44 #include "interface/mmal/util/mmal_util_params.h"
45 #include "interface/mmal/util/mmal_default_components.h"
46 #include "interface/mmal/util/mmal_connection.h"
47
48 #include "RaspiPreview.h"
49 #include "RaspiCapture.h"
50
51 #if 0
52 #define CommandPreview        1
53 #define CommandFullScreen     2
54 #define CommandOpacity        3
55 #define CommandDisablePreview 4
56
57 static COMMAND_LIST cmdline_commands[] =
58 {
59    { CommandPreview,       "-preview",    "p",  "Preview window settings <'x,y,w,h'>", 1 },
60    { CommandFullScreen,    "-fullscreen", "f",  "Fullscreen preview mode", 0 },
61    { CommandOpacity,       "-opacity",    "op", "Preview window opacity (0-255)", 1},
62    { CommandDisablePreview,"-nopreview",  "n",  "Do not display a preview window", 0},
63 };
64
65 static int cmdline_commands_size = sizeof(cmdline_commands) / sizeof(cmdline_commands[0]);
66 #endif
67
68 /**
69  * Create the preview component, set up its ports
70  *
71  * @param state Pointer to state control struct
72  *
73  * @return MMAL_SUCCESS if all OK, something else otherwise
74  *
75  */
76 MMAL_STATUS_T raspipreview_create(RASPIPREVIEW_STATE *state,
77     RASPIPREVIEW_PARAMETERS *config)
78 {
79    MMAL_COMPONENT_T *preview = 0;
80    MMAL_STATUS_T status;
81
82    state->havePreview = config->wantPreview;
83
84    if (!config->wantPreview)
85    {
86       // No preview required, so create a null sink component to take its place
87       status = mmal_component_create("vc.null_sink", &preview);
88
89       if (status != MMAL_SUCCESS)
90       {
91          vcos_log_error("Unable to create null sink component");
92          goto error;
93       }
94
95       state->preview_component = preview;
96    }
97    else
98    {
99       status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER,
100             &preview);
101       if (status != MMAL_SUCCESS)
102       {
103          vcos_log_error("Unable to create preview component");
104          goto error;
105       }
106
107       if (!preview->input_num)
108       {
109          status = MMAL_ENOSYS;
110          vcos_log_error("No input ports found on component");
111          goto error;
112       }
113
114       state->preview_component = preview;
115
116       raspipreview_update_config (state, config);
117       if (status != MMAL_SUCCESS && status != MMAL_ENOSYS)
118       {
119          vcos_log_error("unable to set preview port parameters (%u)", status);
120          goto error;
121       }
122    }
123
124    /* Enable component */
125    status = mmal_component_enable(preview);
126    if (status != MMAL_SUCCESS)
127    {
128       vcos_log_error("Unable to enable preview/null sink component (%u)", status);
129       goto error;
130    }
131
132    return status;
133
134 error:
135   if (preview) {
136     mmal_component_destroy(preview);
137     state->preview_component = NULL;
138   }
139
140    return status;
141 }
142
143 MMAL_STATUS_T
144 raspipreview_update_config (RASPIPREVIEW_STATE *state,
145   RASPIPREVIEW_PARAMETERS *config)
146 {
147   MMAL_COMPONENT_T *preview = state->preview_component;
148   MMAL_PORT_T *preview_port = NULL;
149   MMAL_DISPLAYREGION_T param;
150   MMAL_STATUS_T status;
151
152   /* Can't update props on the null preview component */
153   if (state->havePreview == 0)
154     return MMAL_SUCCESS;
155
156   preview_port = preview->input[0];
157
158   param.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
159   param.hdr.size = sizeof(MMAL_DISPLAYREGION_T);
160
161   param.set = MMAL_DISPLAY_SET_LAYER;
162   param.layer = PREVIEW_LAYER;
163
164   param.set |= MMAL_DISPLAY_SET_ALPHA;
165   param.alpha = config->opacity;
166
167   if (config->wantFullScreenPreview)
168   {
169      param.set |= MMAL_DISPLAY_SET_FULLSCREEN;
170      param.fullscreen = 1;
171   }
172   else
173   {
174      param.set |= (MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN);
175      param.fullscreen = 0;
176      param.dest_rect = config->previewWindow;
177   }
178
179   status = mmal_port_parameter_set(preview_port, &param.hdr);
180   if (status == MMAL_ENOSYS)
181     status = MMAL_SUCCESS;
182
183   return status;
184 }
185
186 /**
187  * Destroy the preview component
188  *
189  * @param state Pointer to state control struct
190  *
191  */
192 void raspipreview_destroy(RASPIPREVIEW_STATE *state)
193 {
194    if (state->preview_component)
195    {
196       mmal_component_destroy(state->preview_component);
197       state->preview_component = NULL;
198    }
199 }
200
201 /**
202  * Assign set of default parameters to the passed in parameter block
203  *
204  * @param state Pointer to parameter block
205  *
206  */
207 void raspipreview_set_defaults(RASPIPREVIEW_PARAMETERS *config)
208 {
209    config->wantPreview = 1;
210    config->wantFullScreenPreview = 1;
211    config->opacity = 255;
212    config->previewWindow.x = 0;
213    config->previewWindow.y = 0;
214    config->previewWindow.width = 1024;
215    config->previewWindow.height = 768;
216 }
217
218 /**
219  * Dump parameters as human readable to stdout
220  *
221  * @param state Pointer to parameter block
222  *
223  */
224 void raspipreview_dump_parameters(RASPIPREVIEW_PARAMETERS *config)
225 {
226    fprintf(stderr, "Preview %s, Full screen %s\n", config->wantPreview ? "Yes" : "No",
227       config->wantFullScreenPreview ? "Yes" : "No");
228
229    fprintf(stderr, "Preview window %d,%d,%d,%d\nOpacity %d\n", config->previewWindow.x,
230       config->previewWindow.y, config->previewWindow.width,
231       config->previewWindow.height, config->opacity);
232 };
233
234 #if 0
235 /**
236  * Parse a possible command pair - command and parameter
237  * @param arg1 Command
238  * @param arg2 Parameter (could be NULL)
239  * @return How many parameters were used, 0,1,2
240  */
241 int raspipreview_parse_cmdline(RASPIPREVIEW_PARAMETERS *params, const char *arg1, const char *arg2)
242 {
243    int command_id, used = 0, num_parameters;
244
245    if (!arg1)
246        return 0;
247
248    command_id = raspicli_get_command_id(cmdline_commands, cmdline_commands_size, arg1, &num_parameters);
249
250    // If invalid command, or we are missing a parameter, drop out
251    if (command_id==-1 || (command_id != -1 && num_parameters > 0 && arg2 == NULL))
252       return 0;
253
254    switch (command_id)
255    {
256       case CommandPreview: // Preview window
257       {
258          int tmp;
259
260          params->wantPreview = 1;
261
262          tmp = sscanf(arg2, "%d,%d,%d,%d",
263                &params->previewWindow.x, &params->previewWindow.y,
264                &params->previewWindow.width, &params->previewWindow.height);
265
266          // Failed to get any window parameters, so revert to full screen
267          if (tmp == 0)
268             params->wantFullScreenPreview = 1;
269          else
270             params->wantFullScreenPreview = 0;
271
272          used = 2;
273
274          break;
275       }
276
277       case CommandFullScreen: // Want full screen preview mode (overrides display rect)
278          params->wantPreview = 1;
279          params->wantFullScreenPreview = 1;
280
281          used = 1;
282          break;
283
284       case CommandOpacity: // Define preview window opacity
285          if (sscanf(arg2, "%u", &params->opacity) != 1)
286             params->opacity = 255;
287          else
288             used = 2;
289          break;
290
291       case CommandDisablePreview: // Turn off preview output
292          params->wantPreview = 0;
293          used = 1;
294          break;
295    }
296
297    return used;
298 }
299
300 /**
301  * Display help for command line options
302  */
303 void raspipreview_display_help()
304 {
305    fprintf(stderr, "\nPreview parameter commands\n\n");
306    raspicli_display_help(cmdline_commands, cmdline_commands_size);
307 }
308 #endif
309 /* *INDENT-ON* */