Remove legacy parameter from add_string()
[vlc/asuraparaju-public.git] / modules / video_output / snapshot.c
blobed02ab5d55348ea33f5cee3819d33d4187ee7f60
1 /*****************************************************************************
2 * snapshot.c : snapshot plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2002 the VideoLAN team
5 * $Id$
7 * Authors: Olivier Aubert <oaubert@lisi.univ-lyon1.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * This module is a pseudo video output that offers the possibility to
26 * keep a cache of low-res snapshots.
27 * The snapshot structure is defined in include/snapshot.h
28 * In order to access the current snapshot cache, object variables are used:
29 * vout-snapshot-list-pointer : the pointer on the first element in the list
30 * vout-snapshot-datasize : size of a snapshot
31 * (also available in snapshot_t->i_datasize)
32 * vout-snapshot-cache-size : size of the cache list
34 * It is used for the moment by the CORBA module and a specialized
35 * python-vlc binding.
36 *****************************************************************************/
38 /*****************************************************************************
39 * Preamble
40 *****************************************************************************/
42 #ifdef HAVE_CONFIG_H
43 # include "config.h"
44 #endif
46 #include <vlc_common.h>
47 #include <vlc_plugin.h>
48 #include <vlc_vout_display.h>
49 #include <vlc_picture_pool.h>
50 #include <vlc_input.h>
52 /*****************************************************************************
53 * Module descriptor
54 *****************************************************************************/
55 #define WIDTH_TEXT N_("Snapshot width")
56 #define WIDTH_LONGTEXT N_("Width of the snapshot image.")
58 #define HEIGHT_TEXT N_("Snapshot height")
59 #define HEIGHT_LONGTEXT N_("Height of the snapshot image.")
61 #define CHROMA_TEXT N_("Chroma")
62 #define CHROMA_LONGTEXT N_("Output chroma for the snapshot image " \
63 "(a 4 character string, like \"RV32\").")
65 #define CACHE_TEXT N_("Cache size (number of images)")
66 #define CACHE_LONGTEXT N_("Snapshot cache size (number of images to keep).")
68 static int Open (vlc_object_t *);
69 static void Close(vlc_object_t *);
71 vlc_module_begin ()
72 set_description(N_("Snapshot output"))
73 set_shortname(N_("Snapshot"))
75 set_category(CAT_VIDEO)
76 set_subcategory(SUBCAT_VIDEO_VOUT)
77 set_capability("vout display", 0)
79 add_integer("vout-snapshot-width", 320, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, false)
80 add_integer("vout-snapshot-height", 200, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, false)
81 add_string("vout-snapshot-chroma", "RV32", CHROMA_TEXT, CHROMA_LONGTEXT, true)
82 add_deprecated_alias("snapshot-chroma")
83 add_integer("vout-snapshot-cache-size", 50, NULL, CACHE_TEXT, CACHE_LONGTEXT, true)
84 add_deprecated_alias("snapshot-cache-size")
86 set_callbacks(Open, Close)
87 vlc_module_end ()
90 /*****************************************************************************
91 * Local prototypes
92 *****************************************************************************/
93 static picture_pool_t *Pool (vout_display_t *, unsigned);
94 static void Display(vout_display_t *, picture_t *);
95 static int Control(vout_display_t *, int, va_list);
96 static void Manage (vout_display_t *);
98 typedef struct {
99 mtime_t date; /* Presentation time */
100 int width; /* In pixels */
101 int height; /* In pixels */
102 int data_size; /* In bytes */
103 uint8_t *data; /* Data area */
104 } snapshot_t;
106 struct vout_display_sys_t {
107 int count; /* Size of the cache */
108 snapshot_t **snapshot; /* List of available snapshots */
109 int index; /* Index of the next available list member */
110 int data_size; /* Size of an image */
111 picture_pool_t *pool;
113 input_thread_t *input; /* The input thread */
116 /* */
117 static int Open(vlc_object_t *object)
119 vout_display_t *vd = (vout_display_t *)object;
120 vout_display_sys_t *sys;
122 /* Allocate instance and initialize some members */
123 vd->sys = sys = malloc(sizeof(*sys));
124 if (!sys)
125 return VLC_ENOMEM;
127 char *chroma_fmt = var_InheritString(vd, "vout-snapshot-chroma");
128 const vlc_fourcc_t chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma_fmt);
129 free(chroma_fmt);
131 if (!chroma) {
132 msg_Err(vd, "snapshot-chroma should be 4 characters long");
133 free(sys);
134 return VLC_EGENERIC;
137 const int width = var_InheritInteger(vd, "vout-snapshot-width");
138 const int height = var_InheritInteger(vd, "vout-snapshot-height");
139 if (width <= 0 || height <= 0) {
140 msg_Err(vd, "snapshot-width/height are invalid");
141 free(sys);
142 return VLC_EGENERIC;
145 /* */
146 video_format_t fmt = vd->fmt;
147 fmt.i_chroma = chroma;
148 fmt.i_width = width;
149 fmt.i_height = height;
150 fmt.i_rmask = 0;
151 fmt.i_gmask = 0;
152 fmt.i_bmask = 0;
153 video_format_FixRgb(&fmt);
155 picture_t *picture = picture_NewFromFormat(&fmt);
156 if (!picture) {
157 free(sys);
158 return VLC_EGENERIC;
160 sys->pool = picture_pool_New(1, &picture);
161 if (!sys->pool) {
162 picture_Release(picture);
163 free(sys);
164 return VLC_EGENERIC;
166 sys->data_size = 0;
167 for (int i = 0; i < picture->i_planes; i++) {
168 const plane_t *plane = &picture->p[i];
169 sys->data_size += plane->i_visible_pitch *
170 plane->i_visible_lines *
171 plane->i_pixel_pitch;
174 sys->index = 0;
175 sys->count = var_InheritInteger(vd, "vout-snapshot-cache-size");
177 /* FIXME following code leaks in case of error */
179 if (sys->count < 2) {
180 msg_Err(vd, "vout-snapshot-cache-size must be at least 1.");
181 return VLC_EGENERIC;
184 sys->snapshot = calloc(sys->count, sizeof(*sys->snapshot));
186 if (!sys->snapshot)
187 return VLC_ENOMEM;
189 /* Initialize the structures for the circular buffer */
190 for (int index = 0; index < sys->count; index++) {
191 snapshot_t *snapshot = malloc(sizeof(*snapshot));
193 if (!snapshot)
194 return VLC_ENOMEM;
196 snapshot->date = VLC_TS_INVALID;
197 snapshot->width = fmt.i_width;
198 snapshot->height = fmt.i_height;
199 snapshot->data_size = sys->data_size;
200 snapshot->data = malloc(sys->data_size);
201 if (!snapshot->data) {
202 free(snapshot);
203 return VLC_ENOMEM;
205 sys->snapshot[index] = snapshot;
208 /* */
209 var_Create(vd, "vout-snapshot-width", VLC_VAR_INTEGER);
210 var_Create(vd, "vout-snapshot-height", VLC_VAR_INTEGER);
211 var_Create(vd, "vout-snapshot-datasize", VLC_VAR_INTEGER);
212 var_Create(vd, "vout-snapshot-cache-size", VLC_VAR_INTEGER);
213 var_Create(vd, "vout-snapshot-list-pointer", VLC_VAR_ADDRESS);
215 var_SetInteger(vd, "vout-snapshot-width", fmt.i_width);
216 var_SetInteger(vd, "vout-snapshot-height", fmt.i_height);
217 var_SetInteger(vd, "vout-snapshot-datasize", sys->data_size);
218 var_SetInteger(vd, "vout-snapshot-cache-size", sys->count);
219 var_SetAddress(vd, "vout-snapshot-list-pointer", sys->snapshot);
221 /* Get the p_input pointer (to access video times) */
222 sys->input = vlc_object_find(vd, VLC_OBJECT_INPUT, FIND_PARENT);
223 if (!sys->input)
224 return VLC_ENOOBJ;
226 if (var_Create(sys->input, "vout-snapshot-id", VLC_VAR_ADDRESS)) {
227 msg_Err(vd, "Cannot create vout-snapshot-id variable in p_input(%p).",
228 sys->input);
229 return VLC_EGENERIC;
232 /* Register the snapshot vout module at the input level */
233 if (var_SetAddress(sys->input, "vout-snapshot-id", vd)) {
234 msg_Err(vd, "Cannot register vout-snapshot-id in p_input(%p).",
235 sys->input);
236 return VLC_EGENERIC;
239 /* */
240 vout_display_info_t info = vd->info;
241 info.has_hide_mouse = true;
243 /* */
244 vd->fmt = fmt;
245 vd->info = info;
246 vd->pool = Pool;
247 vd->prepare = NULL;
248 vd->display = Display;
249 vd->control = Control;
250 vd->manage = Manage;
252 /* */
253 vout_display_SendEventFullscreen(vd, false);
254 return VLC_SUCCESS;
257 /* */
258 static void Close(vlc_object_t *object)
260 vout_display_t *vd = (vout_display_t *)object;
261 vout_display_sys_t *sys = vd->sys;
263 var_Destroy(sys->input, "vout-snapshot-id");
265 vlc_object_release(sys->input);
266 var_Destroy(vd, "vout-snapshot-width");
267 var_Destroy(vd, "vout-snapshot-height");
268 var_Destroy(vd, "vout-snapshot-datasize");
270 for (int index = 0 ; index < sys->count; index++) {
271 free(sys->snapshot[index]->data);
272 free(sys->snapshot[index]);
274 free(sys->snapshot);
276 picture_pool_Delete(sys->pool);
278 free(sys);
281 /*****************************************************************************
283 *****************************************************************************/
284 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
286 VLC_UNUSED(count);
287 return vd->sys->pool;
290 /* Return the position in ms from the start of the movie */
291 static mtime_t snapshot_GetMovietime(vout_display_t *vd)
293 vout_display_sys_t *sys = vd->sys;
295 if (!sys->input)
296 return VLC_TS_INVALID;
297 return var_GetTime(sys->input, "time") / 1000;
300 static void Display(vout_display_t *vd, picture_t *picture)
302 vout_display_sys_t *sys = vd->sys;
304 const int index = sys->index;
306 /* FIXME a lock or an event of some sort would be needed to protect
307 * the content of sys->snapshot vs external users */
308 uint8_t *p_dst = sys->snapshot[index]->data;
309 for (int i = 0; i < picture->i_planes; i++) {
310 const plane_t *plane = &picture->p[i];
311 for( int y = 0; y < plane->i_visible_lines; y++) {
312 vlc_memcpy(p_dst, &plane->p_pixels[y*plane->i_pitch],
313 plane->i_visible_pitch);
314 p_dst += plane->i_visible_pitch;
317 sys->snapshot[index]->date = snapshot_GetMovietime(vd);
319 sys->index = (index + 1) % sys->count;
322 static int Control(vout_display_t *vd, int query, va_list args)
324 VLC_UNUSED(vd);
325 switch (query) {
326 case VOUT_DISPLAY_CHANGE_FULLSCREEN: {
327 const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
328 if (cfg->is_fullscreen)
329 return VLC_EGENERIC;
330 return VLC_SUCCESS;
332 default:
333 return VLC_EGENERIC;
337 static void Manage (vout_display_t *vd)
339 VLC_UNUSED(vd);