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.
24 * transcode -J transform -i inp.mpeg -y xdiv,tcaud inp_stab.avi
27 #include "libvidstab.h"
29 #define MOD_NAME "filter_transform.so"
30 #define MOD_VERSION LIBVIDSTAB_VERSION
31 #define MOD_CAP "transforms each frame according to transformations\n\
32 given in an input file (e.g. translation, rotate) see also filter stabilize"
33 #define MOD_AUTHOR "Georg Martius"
34 #define MOD_FEATURES \
35 TC_MODULE_FEATURE_FILTER|TC_MODULE_FEATURE_VIDEO
37 TC_MODULE_FLAG_RECONFIGURABLE
39 #include "transcode.h"
42 #include "libtc/libtc.h"
43 #include "libtc/optstr.h"
44 #include "libtc/tccodecs.h"
45 #include "libtc/tcmodule-plugin.h"
47 #include "transcode_specifics.h"
49 #define DEFAULT_TRANS_FILE_NAME "transforms.dat"
53 vob_t
* vob
; // pointer to information structure
55 VSTransformations trans
; // transformations
58 double sharpen
; // amount of sharpening
59 char input
[TC_BUF_LINE
];
60 char conf_str
[TC_BUF_MIN
];
64 * transform_init: Initialize this instance of the module. See
65 * tcmodule-data.h for function details.
67 static int transform_init(TCModuleInstance
*self
, uint32_t features
)
69 FilterData
* fd
= NULL
;
70 TC_MODULE_SELF_CHECK(self
, "init");
71 TC_MODULE_INIT_CHECK(self
, MOD_FEATURES
, features
);
75 fd
= tc_zalloc(sizeof(FilterData
));
77 tc_log_error(MOD_NAME
, "init: out of memory!");
82 tc_log_info(MOD_NAME
, "%s %s", MOD_VERSION
, MOD_CAP
);
90 * transform_configure: Configure this instance of the module. See
91 * tcmodule-data.h for function details.
93 static int transform_configure(TCModuleInstance
*self
,
94 const char *options
, vob_t
*vob
)
96 FilterData
*fd
= NULL
;
97 char* filenamecopy
, *filebasename
;
99 TC_MODULE_SELF_CHECK(self
, "configure");
102 VSTransformData
* td
= &(fd
->td
);
106 return TC_ERROR
; /* cannot happen */
108 /**** Initialise private data structure */
112 vsFrameInfoInit(&fi_src
, fd
->vob
->ex_v_width
, fd
->vob
->ex_v_height
,
113 transcode2ourPF(fd
->vob
->im_v_codec
));
114 vsFrameInfoInit(&fi_dest
, fd
->vob
->ex_v_width
, fd
->vob
->ex_v_height
,
115 transcode2ourPF(fd
->vob
->im_v_codec
));
117 VSTransformConfig conf
= vsTransformGetDefaultConfig(MOD_NAME
);
118 conf
.verbose
= verbose
;
122 vsTransformationsInit(&fd
->trans
);
124 filenamecopy
= tc_strdup(fd
->vob
->video_in_file
);
125 filebasename
= basename(filenamecopy
);
126 if (strlen(filebasename
) < TC_BUF_LINE
- 4) {
127 tc_snprintf(fd
->input
, TC_BUF_LINE
, "%s.trf", filebasename
);
129 tc_log_warn(MOD_NAME
, "input name too long, using default `%s'",
130 DEFAULT_TRANS_FILE_NAME
);
131 tc_snprintf(fd
->input
, TC_BUF_LINE
, DEFAULT_TRANS_FILE_NAME
);
136 /* process remaining options */
137 if (options
!= NULL
) {
138 // We support also the help option.
139 if(optstr_lookup(options
, "help")) {
140 tc_log_info(MOD_NAME
,vs_transform_help
);
141 return(TC_IMPORT_ERROR
);
143 optstr_get(options
, "input", "%[^:]", (char*)&fd
->input
);
144 optstr_get(options
, "maxshift", "%d", &conf
.maxShift
);
145 optstr_get(options
, "maxangle", "%lf", &conf
.maxAngle
);
146 optstr_get(options
, "smoothing", "%d", &conf
.smoothing
);
147 optstr_get(options
, "invert" , "%d", &conf
.invert
);
148 optstr_get(options
, "relative" , "%d", &conf
.relative
);
149 optstr_get(options
, "zoom" ,"%lf", &conf
.zoom
);
150 optstr_get(options
, "optzoom" , "%d", &conf
.optZoom
);
151 optstr_get(options
, "zoomspeed", "%lf",&conf
.zoomSpeed
);
152 optstr_get(options
, "interpol" , "%d", (int*)(&conf
.interpolType
));
153 optstr_get(options
, "sharpen" ,"%lf", &fd
->sharpen
);
154 if(optstr_lookup(options
, "tripod")){
155 tc_log_info(MOD_NAME
,"Virtual tripod mode: relative=False, smoothing=0");
161 if(vsTransformDataInit(td
, &conf
, &fi_src
, &fi_dest
) != VS_OK
){
162 tc_log_error(MOD_NAME
, "initialization of VSTransformData failed");
165 vsTransformGetConfig(&conf
,td
);
168 tc_log_info(MOD_NAME
, "Image Transformation/Stabilization Settings:");
169 tc_log_info(MOD_NAME
, " input = %s", fd
->input
);
170 tc_log_info(MOD_NAME
, " smoothing = %d", conf
.smoothing
);
171 tc_log_info(MOD_NAME
, " maxshift = %d", conf
.maxShift
);
172 tc_log_info(MOD_NAME
, " maxangle = %f", conf
.maxAngle
);
173 tc_log_info(MOD_NAME
, " crop = %s",
174 conf
.crop
? "Black" : "Keep");
175 tc_log_info(MOD_NAME
, " relative = %s",
176 conf
.relative
? "True": "False");
177 tc_log_info(MOD_NAME
, " invert = %s",
178 conf
.invert
? "True" : "False");
179 tc_log_info(MOD_NAME
, " zoom = %f", conf
.zoom
);
180 tc_log_info(MOD_NAME
, " optzoom = %d", conf
.optZoom
);
182 tc_log_info(MOD_NAME
, " zoomspeed = %f", conf
.zoomSpeed
);
184 tc_log_info(MOD_NAME
, " interpol = %s",
185 getInterpolationTypeName(conf
.interpolType
));
186 tc_log_info(MOD_NAME
, " sharpen = %f", fd
->sharpen
);
189 f
= fopen(fd
->input
, "r");
191 tc_log_error(MOD_NAME
, "cannot open input file %s!\n", fd
->input
);
192 /* return (-1); when called using tcmodinfo this will fail */
194 VSManyLocalMotions mlms
;
195 if(vsReadLocalMotionsFile(f
,&mlms
)==VS_OK
){
196 // calculate the actual transforms from the localmotions
197 if(vsLocalmotions2Transforms(td
, &mlms
,&fd
->trans
)!=VS_OK
)
198 tc_log_error(MOD_NAME
, "calculating transformations failed!\n");
199 }else{ // try to read old format
200 if (!vsReadOldTransforms(td
, f
, &fd
->trans
)) { /* read input file */
201 tc_log_error(MOD_NAME
, "error parsing input file %s!\n", fd
->input
);
207 if (vsPreprocessTransforms(td
, &fd
->trans
)!= VS_OK
) {
208 tc_log_error(MOD_NAME
, "error while preprocessing transforms!");
212 // sharpen is still in transcode...
213 /* Is this the right point to add the filter? Seems to be the case.*/
215 /* load unsharp filter */
216 char unsharp_param
[256];
217 sprintf(unsharp_param
,"luma=%f:%s:chroma=%f:%s",
218 fd
->sharpen
, "luma_matrix=5x5",
219 fd
->sharpen
/2, "chroma_matrix=5x5");
220 if (!tc_filter_add("unsharp", unsharp_param
)) {
221 tc_log_warn(MOD_NAME
, "cannot load unsharp filter!");
230 * transform_filter_video: performs the transformation of frames
231 * See tcmodule-data.h for function details.
233 static int transform_filter_video(TCModuleInstance
*self
,
234 vframe_list_t
*frame
)
236 FilterData
*fd
= NULL
;
238 TC_MODULE_SELF_CHECK(self
, "filter_video");
239 TC_MODULE_SELF_CHECK(frame
, "filter_video");
243 vsFrameFillFromBuffer(&vsFrame
,frame
->video_buf
, vsTransformGetSrcFrameInfo(&fd
->td
));
245 vsTransformPrepare(&fd
->td
, &vsFrame
, &vsFrame
);
247 VSTransform t
= vsGetNextTransform(&fd
->td
, &fd
->trans
);
249 vsDoTransform(&fd
->td
, t
);
251 vsTransformFinish(&fd
->td
);
257 * transform_fini: Clean up after this instance of the module. See
258 * tcmodule-data.h for function details.
260 static int transform_fini(TCModuleInstance
*self
)
262 FilterData
*fd
= NULL
;
263 TC_MODULE_SELF_CHECK(self
, "fini");
266 self
->userdata
= NULL
;
272 * transform_stop: Reset this instance of the module. See tcmodule-data.h
273 * for function details.
275 static int transform_stop(TCModuleInstance
*self
)
277 FilterData
*fd
= NULL
;
278 TC_MODULE_SELF_CHECK(self
, "stop");
280 vsTransformDataCleanup(&fd
->td
);
282 vsTransformationsCleanup(&fd
->trans
);
286 /* checks for parameter in function _inspect */
287 #define CHECKPARAM(paramname, formatstring, variable) \
288 if (optstr_lookup(param, paramname)) { \
289 tc_snprintf(fd->conf_str, sizeof(fd->conf_str), \
290 formatstring, variable); \
291 *value = fd->conf_str; \
295 * stabilize_inspect: Return the value of an option in this instance of
296 * the module. See tcmodule-data.h for function details.
298 static int transform_inspect(TCModuleInstance
*self
,
299 const char *param
, const char **value
)
301 FilterData
*fd
= NULL
;
302 TC_MODULE_SELF_CHECK(self
, "inspect");
303 TC_MODULE_SELF_CHECK(param
, "inspect");
304 TC_MODULE_SELF_CHECK(value
, "inspect");
308 if (optstr_lookup(param
, "help")) {
309 *value
= vs_transform_help
;
311 VSTransformConfig conf
;
312 vsTransformGetConfig(&conf
,&fd
->td
);
313 CHECKPARAM("maxshift", "maxshift=%d", conf
.maxShift
);
314 CHECKPARAM("maxangle", "maxangle=%f", conf
.maxAngle
);
315 CHECKPARAM("smoothing","smoothing=%d", conf
.smoothing
);
316 CHECKPARAM("crop", "crop=%d", conf
.crop
);
317 CHECKPARAM("relative", "relative=%d", conf
.relative
);
318 CHECKPARAM("invert", "invert=%i", conf
.invert
);
319 CHECKPARAM("input", "input=%s", fd
->input
);
320 CHECKPARAM("optzoom", "optzoom=%i", conf
.optZoom
);
321 CHECKPARAM("zoom", "zoom=%f", conf
.zoom
);
322 CHECKPARAM("sharpen", "sharpen=%f", fd
->sharpen
);
328 static const TCCodecID transform_codecs_in
[] = {
329 TC_CODEC_YUV420P
, TC_CODEC_YUV422P
, TC_CODEC_RGB
, TC_CODEC_ERROR
331 static const TCCodecID transform_codecs_out
[] = {
332 TC_CODEC_YUV420P
, TC_CODEC_YUV422P
, TC_CODEC_RGB
, TC_CODEC_ERROR
334 TC_MODULE_FILTER_FORMATS(transform
);
336 TC_MODULE_INFO(transform
);
338 static const TCModuleClass transform_class
= {
339 TC_MODULE_CLASS_HEAD(transform
),
341 .init
= transform_init
,
342 .fini
= transform_fini
,
343 .configure
= transform_configure
,
344 .stop
= transform_stop
,
345 .inspect
= transform_inspect
,
347 .filter_video
= transform_filter_video
,
350 TC_MODULE_ENTRY_POINT(transform
)
352 /*************************************************************************/
354 static int transform_get_config(TCModuleInstance
*self
, char *options
)
356 TC_MODULE_SELF_CHECK(self
, "get_config");
358 optstr_filter_desc(options
, MOD_NAME
, MOD_CAP
, MOD_VERSION
,
359 MOD_AUTHOR
, "VRY4", "1");
364 static int transform_process(TCModuleInstance
*self
, frame_list_t
*frame
)
366 TC_MODULE_SELF_CHECK(self
, "process");
368 if (frame
->tag
& TC_PRE_S_PROCESS
&& frame
->tag
& TC_VIDEO
) {
369 return transform_filter_video(self
, (vframe_list_t
*)frame
);
374 /*************************************************************************/
376 TC_FILTER_OLDINTERFACE(transform
)
378 /*************************************************************************/
382 * c-file-style: "stroustrup"
383 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
384 * indent-tabs-mode: nil
385 * c-basic-offset: 4 t
388 * vim: expandtab shiftwidth=4: