• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
raspipreview_create(RASPIPREVIEW_STATE * state,RASPIPREVIEW_PARAMETERS * config)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
raspipreview_update_config(RASPIPREVIEW_STATE * state,RASPIPREVIEW_PARAMETERS * config)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  */
raspipreview_destroy(RASPIPREVIEW_STATE * state)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  */
raspipreview_set_defaults(RASPIPREVIEW_PARAMETERS * config)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  */
raspipreview_dump_parameters(RASPIPREVIEW_PARAMETERS * config)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* */
310