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