4 * Copyright (C) Georg Martius - June 2007
5 * georg dot martius at web dot de
7 * This file is part of transcode, a video stream processing tool
9 * transcode 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, or (at your option)
14 * transcode 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 GNU Make; see the file COPYING. If not, write to
21 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26 * transcode -V -J stabilize=shakiness=5:show=1,preview
27 * -i inp.mpeg -y null,null -o dummy
28 * all parameters are optional
31 #include "libvidstab.h"
33 #define MOD_NAME "filter_stabilize.so"
34 #define MOD_VERSION LIBVIDSTAB_VERSION
35 #define MOD_CAP "extracts relative transformations of \n\
36 subsequent frames (used for stabilization together with the\n\
37 transform filter in a second pass)"
38 #define MOD_AUTHOR "Georg Martius"
41 - Try OpenCL/Cuda, this should work great
42 - use smoothing on the frames and then use gradient decent!
43 - stepsize could be adapted (maybe to check only one field with large
44 stepsize and use the maximally required for the other fields
47 #define MOD_FEATURES \
48 TC_MODULE_FEATURE_FILTER|TC_MODULE_FEATURE_VIDEO
50 TC_MODULE_FLAG_RECONFIGURABLE | TC_MODULE_FLAG_DELAY
53 #define DEFAULT_TRANS_FILE_NAME "transforms.dat"
58 #include "transcode.h"
60 #include "libtc/libtc.h"
61 #include "libtc/optstr.h"
62 #include "libtc/tccodecs.h"
63 #include "libtc/tcmodule-plugin.h"
65 #include "transcode_specifics.h"
67 /* private date structure of this filter*/
68 typedef struct _stab_data
{
70 vob_t
* vob
; // pointer to information structure
75 char conf_str
[TC_BUF_MIN
];
78 /*************************************************************************/
80 /* Module interface routines and data. */
82 /*************************************************************************/
85 * stabilize_init: Initialize this instance of the module. See
86 * tcmodule-data.h for function details.
89 static int stabilize_init(TCModuleInstance
*self
, uint32_t features
)
92 TC_MODULE_SELF_CHECK(self
, "init");
93 TC_MODULE_INIT_CHECK(self
, MOD_FEATURES
, features
);
97 sd
= tc_zalloc(sizeof(StabData
)); // allocation with zero values
99 if (verbose
> TC_INFO
)
100 tc_log_error(MOD_NAME
, "init: out of memory!");
104 sd
->vob
= tc_get_vob();
108 /**** Initialise private data structure */
111 if (verbose
& TC_INFO
){
112 tc_log_info(MOD_NAME
, "%s %s", MOD_VERSION
, MOD_CAP
);
120 * stabilize_fini: Clean up after this instance of the module. See
121 * tcmodule-data.h for function details.
123 static int stabilize_fini(TCModuleInstance
*self
)
126 TC_MODULE_SELF_CHECK(self
, "fini");
130 self
->userdata
= NULL
;
135 * stabilize_configure: Configure this instance of the module. See
136 * tcmodule-data.h for function details.
138 static int stabilize_configure(TCModuleInstance
*self
,
139 const char *options
, vob_t
*vob
)
142 TC_MODULE_SELF_CHECK(self
, "configure");
143 char* filenamecopy
, *filebasename
;
147 /* sd->framesize = sd->vob->im_v_width * MAX_PLANES *
148 sizeof(char) * 2 * sd->vob->im_v_height * 2; */
150 VSMotionDetect
* md
= &(sd
->md
);
152 vsFrameInfoInit(&fi
, sd
->vob
->ex_v_width
, sd
->vob
->ex_v_height
,
153 transcode2ourPF(vob
->im_v_codec
));
155 VSMotionDetectConfig conf
= vsMotionDetectGetDefaultConfig(MOD_NAME
);
157 sd
->result
= tc_malloc(TC_BUF_LINE
);
158 filenamecopy
= tc_strdup(sd
->vob
->video_in_file
);
159 filebasename
= basename(filenamecopy
);
160 if (strlen(filebasename
) < TC_BUF_LINE
- 4) {
161 tc_snprintf(sd
->result
, TC_BUF_LINE
, "%s.trf", filebasename
);
163 tc_log_warn(MOD_NAME
, "input name too long, using default `%s'",
164 DEFAULT_TRANS_FILE_NAME
);
165 tc_snprintf(sd
->result
, TC_BUF_LINE
, DEFAULT_TRANS_FILE_NAME
);
168 if (options
!= NULL
) {
169 // for some reason this plugin is called in the old fashion
170 // (not with inspect). Anyway we support both ways of getting help.
171 if(optstr_lookup(options
, "help")) {
172 tc_log_info(MOD_NAME
,vs_motiondetect_help
);
173 return(TC_IMPORT_ERROR
);
176 optstr_get(options
, "result", "%[^:]", sd
->result
);
177 optstr_get(options
, "shakiness", "%d", &conf
.shakiness
);
178 optstr_get(options
, "accuracy", "%d", &conf
.accuracy
);
179 optstr_get(options
, "stepsize", "%d", &conf
.stepSize
);
180 optstr_get(options
, "algo", "%d", &conf
.algo
);
181 optstr_get(options
, "mincontrast","%lf",&conf
.contrastThreshold
);
182 optstr_get(options
, "tripod", "%d", &conf
.virtualTripod
);
183 optstr_get(options
, "show", "%d", &conf
.show
);
186 if(vsMotionDetectInit(md
, &conf
, &fi
) != VS_OK
){
187 tc_log_error(MOD_NAME
, "initialization of Motion Detection failed");
190 vsMotionDetectGetConfig(&conf
,md
);
193 tc_log_info(MOD_NAME
, "Image Stabilization Settings:");
194 tc_log_info(MOD_NAME
, " shakiness = %d", conf
.shakiness
);
195 tc_log_info(MOD_NAME
, " accuracy = %d", conf
.accuracy
);
196 tc_log_info(MOD_NAME
, " stepsize = %d", conf
.stepSize
);
197 tc_log_info(MOD_NAME
, " algo = %d", conf
.algo
);
198 tc_log_info(MOD_NAME
, " mincontrast = %f", conf
.contrastThreshold
);
199 tc_log_info(MOD_NAME
, " tripod = %d", conf
.virtualTripod
);
200 tc_log_info(MOD_NAME
, " show = %d", conf
.show
);
201 tc_log_info(MOD_NAME
, " result = %s", sd
->result
);
204 sd
->f
= fopen(sd
->result
, "w");
206 tc_log_error(MOD_NAME
, "cannot open result file %s!\n", sd
->result
);
209 if(vsPrepareFile(md
, sd
->f
) != VS_OK
){
210 tc_log_error(MOD_NAME
, "cannot write to result file %s", sd
->result
);
220 * stabilize_filter_video: performs the analysis of subsequent frames
221 * See tcmodule-data.h for function details.
224 static int stabilize_filter_video(TCModuleInstance
*self
,
225 vframe_list_t
*frame
)
229 TC_MODULE_SELF_CHECK(self
, "filter_video");
230 TC_MODULE_SELF_CHECK(frame
, "filter_video");
233 VSMotionDetect
* md
= &(sd
->md
);
234 LocalMotions localmotions
;
236 vsFrameFillFromBuffer(&vsFrame
,frame
->video_buf
, &md
->fi
);
238 if(vsMotionDetection(md
, &localmotions
, &vsFrame
)!= VS_OK
){
239 tc_log_error(MOD_NAME
, "motion detection failed");
242 if(vsWriteToFile(md
, sd
->f
, &localmotions
) != VS_OK
){
243 vs_vector_del(&localmotions
);
246 vs_vector_del(&localmotions
);
252 * stabilize_stop: Reset this instance of the module. See tcmodule-data.h
253 * for function details.
256 static int stabilize_stop(TCModuleInstance
*self
)
259 TC_MODULE_SELF_CHECK(self
, "stop");
261 VSMotionDetect
* md
= &(sd
->md
);
267 vsMotionDetectionCleanup(md
);
275 /* checks for parameter in function _inspect */
276 #define CHECKPARAM(paramname, formatstring, variable) \
277 if (optstr_lookup(param, paramname)) { \
278 tc_snprintf(sd->conf_str, sizeof(sd->conf_str), \
279 formatstring, variable); \
280 *value = sd->conf_str; \
284 * stabilize_inspect: Return the value of an option in this instance of
285 * the module. See tcmodule-data.h for function details.
288 static int stabilize_inspect(TCModuleInstance
*self
,
289 const char *param
, const char **value
)
293 TC_MODULE_SELF_CHECK(self
, "inspect");
294 TC_MODULE_SELF_CHECK(param
, "inspect");
295 TC_MODULE_SELF_CHECK(value
, "inspect");
297 VSMotionDetect
* md
= &(sd
->md
);
298 if (optstr_lookup(param
, "help")) {
299 *value
= vs_motiondetect_help
;
301 VSMotionDetectConfig conf
;
302 vsMotionDetectGetConfig(&conf
,md
);
304 CHECKPARAM("shakiness","shakiness=%d", conf
.shakiness
);
305 CHECKPARAM("accuracy", "accuracy=%d", conf
.accuracy
);
306 CHECKPARAM("stepsize", "stepsize=%d", conf
.stepSize
);
307 CHECKPARAM("algo", "algo=%d", conf
.algo
);
308 CHECKPARAM("tripod", "tripod=%d", conf
.virtualTripod
);
309 CHECKPARAM("show", "show=%d", conf
.show
);
310 CHECKPARAM("result", "result=%s", sd
->result
);
314 static const TCCodecID stabilize_codecs_in
[] = {
315 TC_CODEC_YUV420P
, TC_CODEC_YUV422P
, TC_CODEC_RGB
, TC_CODEC_ERROR
317 static const TCCodecID stabilize_codecs_out
[] = {
318 TC_CODEC_YUV420P
, TC_CODEC_YUV422P
, TC_CODEC_RGB
, TC_CODEC_ERROR
320 TC_MODULE_FILTER_FORMATS(stabilize
);
322 TC_MODULE_INFO(stabilize
);
324 static const TCModuleClass stabilize_class
= {
325 TC_MODULE_CLASS_HEAD(stabilize
),
327 .init
= stabilize_init
,
328 .fini
= stabilize_fini
,
329 .configure
= stabilize_configure
,
330 .stop
= stabilize_stop
,
331 .inspect
= stabilize_inspect
,
333 .filter_video
= stabilize_filter_video
,
336 TC_MODULE_ENTRY_POINT(stabilize
)
338 /*************************************************************************/
340 static int stabilize_get_config(TCModuleInstance
*self
, char *options
)
342 TC_MODULE_SELF_CHECK(self
, "get_config");
344 optstr_filter_desc(options
, MOD_NAME
, MOD_CAP
, MOD_VERSION
,
345 MOD_AUTHOR
, "VRY4", "1");
350 static int stabilize_process(TCModuleInstance
*self
, frame_list_t
*frame
)
352 TC_MODULE_SELF_CHECK(self
, "process");
354 // if (frame->tag & TC_PRE_S_PROCESS && frame->tag & TC_VIDEO) {
355 if (frame
->tag
& TC_POST_S_PROCESS
&& frame
->tag
& TC_VIDEO
) {
356 return stabilize_filter_video(self
, (vframe_list_t
*)frame
);
361 /*************************************************************************/
363 TC_FILTER_OLDINTERFACE(stabilize
)
365 /*************************************************************************/
369 * c-file-style: "stroustrup"
370 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
371 * indent-tabs-mode: nil
372 * c-basic-offset: 2 t
375 * vim: expandtab shiftwidth=2: