1 /*
2 * common.c
3 * Copyright (C) 2014 Meltytech, LLC
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #include <framework/mlt.h>
20 #include <vid.stab/libvidstab.h>
21 #include "common.h"
22
validate_format(mlt_image_format format)23 mlt_image_format validate_format( mlt_image_format format )
24 {
25 switch( format )
26 {
27 case mlt_image_yuv420p:
28 return mlt_image_yuv420p;
29 default:
30 return mlt_image_yuv422;
31 }
32 }
33
34 /** Convert an MLT image to one that can be used by VS.
35 * Use free_vsimage() when done with the resulting image.
36 */
37
mltimage_to_vsimage(mlt_image_format mlt_format,int width,int height,uint8_t * mlt_img,uint8_t ** vs_img)38 VSPixelFormat mltimage_to_vsimage( mlt_image_format mlt_format, int width, int height, uint8_t* mlt_img, uint8_t** vs_img )
39 {
40 switch( mlt_format )
41 {
42 case mlt_image_yuv420p:
43 // This format maps with no conversion
44 {
45 *vs_img = mlt_img;
46 return PF_YUV420P;
47 }
48 case mlt_image_yuv422:
49 // Convert packed YUV422 to planar YUV444
50 // Note: vid.stab 0.98 seems to suffer chroma bleeding
51 // when using PF_YUV422P - which is why PF_YUV444P is used.
52 {
53 *vs_img = mlt_pool_alloc( width * height * 3 );
54 uint8_t* yp = *vs_img;
55 uint8_t* up = yp + ( width * height );
56 uint8_t* vp = up + ( width * height );
57 int i, j, n = width / 2 + 1;
58
59 for ( i = 0; i < height; i++ )
60 {
61 j = n;
62 while ( --j )
63 {
64 *yp++ = mlt_img[0];
65 *up++ = mlt_img[1];
66 *vp++ = mlt_img[3];
67 *yp++ = mlt_img[2];
68 *up++ = mlt_img[1];
69 *vp++ = mlt_img[3];
70 mlt_img += 4;
71 }
72 if ( width % 2 )
73 {
74 *yp++ = mlt_img[0];
75 *up++ = mlt_img[1];
76 *vp++ = (mlt_img - 4)[3];
77 mlt_img += 2;
78 }
79 }
80
81 return PF_YUV444P;
82 }
83 default:
84 return PF_NONE;
85 }
86 }
87
88 /** Convert a VS image back to the MLT image it originally came from in mltimage_to_vsimage().
89 */
90
vsimage_to_mltimage(uint8_t * vs_img,uint8_t * mlt_img,mlt_image_format mlt_format,int width,int height)91 void vsimage_to_mltimage( uint8_t* vs_img, uint8_t* mlt_img, mlt_image_format mlt_format, int width, int height )
92 {
93 switch( mlt_format )
94 {
95 case mlt_image_yuv420p:
96 // This format was never converted
97 break;
98 case mlt_image_yuv422:
99 // Convert planar YUV444 to packed YUV422
100 {
101 uint8_t* yp = vs_img;
102 uint8_t* up = yp + ( width * height );
103 uint8_t* vp = up + ( width * height );
104 int i, j, n = width / 2 + 1;
105
106 for ( i = 0; i < height; i++ )
107 {
108 j = n;
109 while ( --j )
110 {
111 *mlt_img++ = yp[0];
112 *mlt_img++ = ( up[0] + up[1] ) >> 1;
113 *mlt_img++ = yp[1];
114 *mlt_img++ = ( vp[0] + vp[1] ) >> 1;
115 yp += 2;
116 up += 2;
117 vp += 2;
118 }
119 if ( width % 2 )
120 {
121 *mlt_img++ = yp[0];
122 *mlt_img++ = up[0];
123 yp += 1;
124 up += 1;
125 vp += 1;
126 }
127 }
128 }
129 break;
130 default:
131 break;
132 }
133 }
134
135 /** Free an image allocated by mltimage_to_vsimage().
136 */
137
free_vsimage(uint8_t * vs_img,VSPixelFormat format)138 void free_vsimage( uint8_t* vs_img, VSPixelFormat format )
139 {
140 if( format != PF_YUV420P )
141 {
142 mlt_pool_release( vs_img );
143 }
144 }
145
146 /** Compare two VSMotionDetectConfig structures.
147 * Return 1 if they are different. 0 if they are the same.
148 */
149
compare_motion_config(VSMotionDetectConfig * a,VSMotionDetectConfig * b)150 int compare_motion_config( VSMotionDetectConfig* a, VSMotionDetectConfig* b )
151 {
152 if( a->shakiness != b->shakiness ||
153 a->accuracy != b->accuracy ||
154 a->stepSize != b->stepSize ||
155 // Skip: Deprecated
156 // a->algo != b->algo ||
157 a->virtualTripod != b->virtualTripod ||
158 a->show != b->show ||
159 // Skip: inconsequential?
160 // a->modName != b->modName ||
161 a->contrastThreshold != b->contrastThreshold )
162 {
163 return 1;
164 }
165 return 0;
166 }
167
168 /** Compare two VSTransformConfig structures.
169 * Return 1 if they are different. 0 if they are the same.
170 */
171
compare_transform_config(VSTransformConfig * a,VSTransformConfig * b)172 int compare_transform_config( VSTransformConfig* a, VSTransformConfig* b )
173 {
174 if( a->relative != b->relative ||
175 a->smoothing != b->smoothing ||
176 a->crop != b->crop ||
177 a->invert != b->invert ||
178 a->zoom != b->zoom ||
179 a->optZoom != b->optZoom ||
180 a->zoomSpeed != b->zoomSpeed ||
181 a->interpolType != b->interpolType ||
182 a->maxShift != b->maxShift ||
183 a->maxAngle != b->maxAngle ||
184 // Skip: inconsequential?
185 // a->modName != b->modName ||
186 // Skip: unused?
187 // a->verbose != b->verbose ||
188 a->simpleMotionCalculation != b->simpleMotionCalculation ||
189 // Skip: unused?
190 // a->storeTransforms != b->storeTransforms ||
191 a->smoothZoom != b->smoothZoom ||
192 a->camPathAlgo != b->camPathAlgo )
193 {
194 return 1;
195 }
196 return 0;
197 }
198
vs_log_wrapper(int type,const char * tag,const char * format,...)199 static int vs_log_wrapper( int type, const char *tag, const char *format, ... )
200 {
201 va_list vl;
202
203 if ( type > mlt_log_get_level() )
204 return VS_OK;
205
206 va_start( vl, format );
207 fprintf( stderr, "[%s] ", tag );
208 vfprintf( stderr, format, vl );
209 va_end( vl );
210
211 return VS_OK;
212 }
213
init_vslog()214 void init_vslog()
215 {
216 VS_ERROR_TYPE = MLT_LOG_ERROR;
217 VS_WARN_TYPE = MLT_LOG_WARNING;
218 VS_INFO_TYPE = MLT_LOG_INFO;
219 VS_MSG_TYPE = MLT_LOG_VERBOSE;
220 vs_log = vs_log_wrapper;
221 }
222