1 /*****************************************************************************
2 * extract.c : Extract RGB components
3 *****************************************************************************
4 * Copyright (C) 2000-2006 VLC authors and VideoLAN
7 * Authors: Antoine Cellerier <dionoea .t videolan d@t org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
35 #include <vlc_filter.h>
36 #include "filter_picture.h"
40 /*****************************************************************************
42 *****************************************************************************/
43 static int Create ( vlc_object_t
* );
44 static void Destroy ( vlc_object_t
* );
46 static picture_t
*Filter( filter_t
*, picture_t
* );
47 static int ExtractCallback( vlc_object_t
*, char const *,
48 vlc_value_t
, vlc_value_t
, void * );
50 static void get_red_from_yuv420( picture_t
*, picture_t
*, int, int, int );
51 static void get_green_from_yuv420( picture_t
*, picture_t
*, int, int, int );
52 static void get_blue_from_yuv420( picture_t
*, picture_t
*, int, int, int );
53 static void get_red_from_yuv422( picture_t
*, picture_t
*, int, int, int );
54 static void get_green_from_yuv422( picture_t
*, picture_t
*, int, int, int );
55 static void get_blue_from_yuv422( picture_t
*, picture_t
*, int, int, int );
56 static void make_projection_matrix( filter_t
*, int color
, int *matrix
);
57 static void get_custom_from_yuv420( picture_t
*, picture_t
*, int, int, int, int * );
58 static void get_custom_from_yuv422( picture_t
*, picture_t
*, int, int, int, int * );
59 static void get_custom_from_packedyuv422( picture_t
*, picture_t
*, int * );
62 #define COMPONENT_TEXT N_("RGB component to extract")
63 #define COMPONENT_LONGTEXT N_("RGB component to extract. 0 for Red, 1 for Green and 2 for Blue.")
64 #define FILTER_PREFIX "extract-"
66 static const int pi_component_values
[] = { 0xFF0000, 0x00FF00, 0x0000FF };
67 static const char *const ppsz_component_descriptions
[] = {
68 "Red", "Green", "Blue" };
70 /*****************************************************************************
72 *****************************************************************************/
74 set_description( N_("Extract RGB component video filter") )
75 set_shortname( N_("Extract" ))
76 set_category( CAT_VIDEO
)
77 set_subcategory( SUBCAT_VIDEO_VFILTER
)
78 set_capability( "video filter", 0 )
79 add_shortcut( "extract" )
81 add_integer_with_range( FILTER_PREFIX
"component", 0xFF0000, 1, 0xFFFFFF,
82 COMPONENT_TEXT
, COMPONENT_LONGTEXT
, false )
83 change_integer_list( pi_component_values
, ppsz_component_descriptions
)
85 set_callbacks( Create
, Destroy
)
88 static const char *const ppsz_filter_options
[] = {
92 enum { RED
=0xFF0000, GREEN
=0x00FF00, BLUE
=0x0000FF };
96 int *projection_matrix
;
100 /*****************************************************************************
102 *****************************************************************************/
103 static int Create( vlc_object_t
*p_this
)
105 filter_t
*p_filter
= (filter_t
*)p_this
;
107 switch( p_filter
->fmt_in
.video
.i_chroma
)
120 /* We only want planar YUV 4:2:0 or 4:2:2 */
121 msg_Err( p_filter
, "Unsupported input chroma (%4.4s)",
122 (char*)&(p_filter
->fmt_in
.video
.i_chroma
) );
126 /* Allocate structure */
127 p_filter
->p_sys
= malloc( sizeof( filter_sys_t
) );
128 if( p_filter
->p_sys
== NULL
)
130 p_filter
->p_sys
->projection_matrix
= malloc( 9 * sizeof( int ) );
131 if( !p_filter
->p_sys
->projection_matrix
)
133 free( p_filter
->p_sys
);
137 config_ChainParse( p_filter
, FILTER_PREFIX
, ppsz_filter_options
,
140 p_filter
->p_sys
->i_color
= var_CreateGetIntegerCommand( p_filter
,
141 FILTER_PREFIX
"component" );
142 /* Matrix won't be used for RED, GREEN or BLUE in planar formats */
143 make_projection_matrix( p_filter
, p_filter
->p_sys
->i_color
,
144 p_filter
->p_sys
->projection_matrix
);
145 vlc_mutex_init( &p_filter
->p_sys
->lock
);
146 var_AddCallback( p_filter
, FILTER_PREFIX
"component",
147 ExtractCallback
, p_filter
->p_sys
);
149 p_filter
->pf_video_filter
= Filter
;
154 /*****************************************************************************
156 *****************************************************************************/
157 static void Destroy( vlc_object_t
*p_this
)
159 filter_t
*p_filter
= (filter_t
*)p_this
;
160 filter_sys_t
*p_sys
= p_filter
->p_sys
;
162 var_DelCallback( p_filter
, FILTER_PREFIX
"component", ExtractCallback
,
164 vlc_mutex_destroy( &p_sys
->lock
);
165 free( p_sys
->projection_matrix
);
169 /*****************************************************************************
171 *****************************************************************************/
172 static picture_t
*Filter( filter_t
*p_filter
, picture_t
*p_pic
)
175 filter_sys_t
*p_sys
= p_filter
->p_sys
;
177 if( !p_pic
) return NULL
;
179 p_outpic
= filter_NewPicture( p_filter
);
182 picture_Release( p_pic
);
186 vlc_mutex_lock( &p_sys
->lock
);
187 switch( p_pic
->format
.i_chroma
)
192 switch( p_sys
->i_color
)
195 get_red_from_yuv420( p_pic
, p_outpic
,
196 Y_PLANE
, U_PLANE
, V_PLANE
);
199 get_green_from_yuv420( p_pic
, p_outpic
,
200 Y_PLANE
, U_PLANE
, V_PLANE
);
203 get_blue_from_yuv420( p_pic
, p_outpic
,
204 Y_PLANE
, U_PLANE
, V_PLANE
);
207 get_custom_from_yuv420( p_pic
, p_outpic
,
208 Y_PLANE
, U_PLANE
, V_PLANE
,
209 p_sys
->projection_matrix
);
216 switch( p_filter
->p_sys
->i_color
)
219 get_red_from_yuv422( p_pic
, p_outpic
,
220 Y_PLANE
, U_PLANE
, V_PLANE
);
223 get_green_from_yuv422( p_pic
, p_outpic
,
224 Y_PLANE
, U_PLANE
, V_PLANE
);
227 get_blue_from_yuv422( p_pic
, p_outpic
,
228 Y_PLANE
, U_PLANE
, V_PLANE
);
231 get_custom_from_yuv422( p_pic
, p_outpic
,
232 Y_PLANE
, U_PLANE
, V_PLANE
,
233 p_sys
->projection_matrix
);
239 get_custom_from_packedyuv422( p_pic
, p_outpic
,
240 p_sys
->projection_matrix
);
244 vlc_mutex_unlock( &p_sys
->lock
);
245 msg_Warn( p_filter
, "Unsupported input chroma (%4.4s)",
246 (char*)&(p_pic
->format
.i_chroma
) );
247 picture_Release( p_pic
);
250 vlc_mutex_unlock( &p_sys
->lock
);
252 return CopyInfoAndRelease( p_outpic
, p_pic
);
258 static void mmult( double *res
, double *a
, double *b
)
260 for( int i
= 0; i
< 3; i
++ )
262 for( int j
= 0; j
< 3; j
++ )
265 for( int k
= 0; k
< 3; k
++ )
267 res
[ i
*3 + j
] += a
[ i
*3 + k
] * b
[ k
*3 + j
];
272 static void make_projection_matrix( filter_t
*p_filter
, int color
, int *matrix
)
274 double left_matrix
[9] =
275 { 76.24500, 149.68500, 29.07000,
276 -43.02765, -84.47235, 127.50000,
277 127.50000, -106.76534, -20.73466 };
278 double right_matrix
[9] =
279 { 257.00392, 0.00000, 360.31950,
280 257.00392, -88.44438, -183.53583,
281 257.00392, 455.41095, 0.00000 };
282 double red
= ((double)(( 0xFF0000 & color
)>>16))/255.;
283 double green
= ((double)(( 0x00FF00 & color
)>>8))/255.;
284 double blue
= ((double)( 0x0000FF & color
))/255.;
285 double norm
= sqrt( red
*red
+ green
*green
+ blue
*blue
);
292 /* XXX: We might still need to norm the rgb_matrix */
293 double rgb_matrix
[9] =
294 { red
*red
, red
*green
, red
*blue
,
295 red
*green
, green
*green
, green
*blue
,
296 red
*blue
, green
*blue
, blue
*blue
};
299 msg_Dbg( p_filter
, "red: %f", red
);
300 msg_Dbg( p_filter
, "green: %f", green
);
301 msg_Dbg( p_filter
, "blue: %f", blue
);
302 mmult( result1
, rgb_matrix
, right_matrix
);
303 mmult( result
, left_matrix
, result1
);
304 for( int i
= 0; i
< 9; i
++ )
306 matrix
[i
] = (int)result
[i
];
308 msg_Dbg( p_filter
, "Projection matrix:" );
309 msg_Dbg( p_filter
, "%6d %6d %6d", matrix
[0], matrix
[1], matrix
[2] );
310 msg_Dbg( p_filter
, "%6d %6d %6d", matrix
[3], matrix
[4], matrix
[5] );
311 msg_Dbg( p_filter
, "%6d %6d %6d", matrix
[6], matrix
[7], matrix
[8] );
314 static void get_custom_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
315 int yp
, int up
, int vp
, int *m
)
317 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
319 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
320 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
322 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
324 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
325 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
327 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
328 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
330 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
331 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
332 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
334 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
337 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
338 y2in
= y1in
+ i_in_pitch
;
339 y2out
= y1out
+ i_out_pitch
;
340 while( y1in
< y1end
)
342 *uout
++ = vlc_uint8( (*y1in
* m
[3] + (*uin
-U
) * m
[4] + (*vin
-V
) * m
[5])
344 *vout
++ = vlc_uint8( (*y1in
* m
[6] + (*uin
-U
) * m
[7] + (*vin
-V
) * m
[8])
346 *y1out
++ = vlc_uint8( (*y1in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
348 *y1out
++ = vlc_uint8( (*y1in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
350 *y2out
++ = vlc_uint8( (*y2in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
352 *y2out
++ = vlc_uint8( (*y2in
++ * m
[0] + (*uin
++ - U
) * m
[1] + (*vin
++ -V
) * m
[2])
355 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
356 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
357 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
358 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
359 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
360 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
363 static void get_custom_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
364 int yp
, int up
, int vp
, int *m
)
366 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
367 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
368 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
370 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
371 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
372 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
374 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
375 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
377 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
378 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
379 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
381 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
384 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
385 while( y1in
< y1end
)
387 *uout
++ = vlc_uint8( (*y1in
* m
[3] + (*uin
-U
) * m
[4] + (*vin
-V
) * m
[5])
389 *vout
++ = vlc_uint8( (*y1in
* m
[6] + (*uin
-U
) * m
[7] + (*vin
-V
) * m
[8])
391 *y1out
++ = vlc_uint8( (*y1in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
393 *y1out
++ = vlc_uint8( (*y1in
++ * m
[0] + (*uin
++ -U
) * m
[1] + (*vin
++ -V
) * m
[2])
396 y1in
+= i_in_pitch
- i_visible_pitch
;
397 y1out
+= i_out_pitch
- i_visible_pitch
;
398 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
399 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
400 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
401 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
405 static void get_custom_from_packedyuv422( picture_t
*p_inpic
,
409 int i_y_offset
, i_u_offset
, i_v_offset
;
410 if( GetPackedYuvOffsets( p_inpic
->format
.i_chroma
, &i_y_offset
,
411 &i_u_offset
, &i_v_offset
) != VLC_SUCCESS
)
414 uint8_t *yin
= p_inpic
->p
->p_pixels
+ i_y_offset
;
415 uint8_t *uin
= p_inpic
->p
->p_pixels
+ i_u_offset
;
416 uint8_t *vin
= p_inpic
->p
->p_pixels
+ i_v_offset
;
418 uint8_t *yout
= p_outpic
->p
->p_pixels
+ i_y_offset
;
419 uint8_t *uout
= p_outpic
->p
->p_pixels
+ i_u_offset
;
420 uint8_t *vout
= p_outpic
->p
->p_pixels
+ i_v_offset
;
422 const int i_in_pitch
= p_inpic
->p
->i_pitch
;
423 const int i_out_pitch
= p_outpic
->p
->i_pitch
;
424 const int i_visible_pitch
= p_inpic
->p
->i_visible_pitch
;
425 const int i_visible_lines
= p_inpic
->p
->i_visible_lines
;
427 const uint8_t *yend
= yin
+ i_visible_lines
* i_in_pitch
;
430 const uint8_t *ylend
= yin
+ i_visible_pitch
;
433 *uout
= vlc_uint8( (*yin
* m
[3] + (*uin
-U
) * m
[4] + (*vin
-V
) * m
[5])
436 *vout
= vlc_uint8( (*yin
* m
[6] + (*uin
-U
) * m
[7] + (*vin
-V
) * m
[8])
439 *yout
= vlc_uint8( (*yin
* m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
443 *yout
= vlc_uint8( (*yin
* m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
450 yin
+= i_in_pitch
- i_visible_pitch
;
451 yout
+= i_out_pitch
- i_visible_pitch
;
452 uin
+= i_in_pitch
- i_visible_pitch
;
453 uout
+= i_out_pitch
- i_visible_pitch
;
454 vin
+= i_in_pitch
- i_visible_pitch
;
455 vout
+= i_out_pitch
- i_visible_pitch
;
459 static void get_red_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
460 int yp
, int up
, int vp
)
462 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
464 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
466 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
468 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
469 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
471 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
472 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
474 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
475 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
476 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
478 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
481 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
482 y2in
= y1in
+ i_in_pitch
;
483 y2out
= y1out
+ i_out_pitch
;
484 while( y1in
< y1end
)
491 *uout
++ = vlc_uint8( (*y1in
* -11058 + (*vin
- V
) * -15504)
493 *vout
++ = vlc_uint8( (*y1in
* 32768 + (*vin
- V
) * 45941)
495 *y1out
++ = vlc_uint8( (*y1in
++ * 19595 + (*vin
- V
) * 27473)
497 *y1out
++ = vlc_uint8( (*y1in
++ * 19595 + (*vin
- V
) * 27473)
499 *y2out
++ = vlc_uint8( (*y2in
++ * 19594 + (*vin
- V
) * 27473)
501 *y2out
++ = vlc_uint8( (*y2in
++ * 19594 + (*vin
++ - V
) * 27473)
504 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
505 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
506 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
507 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
508 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
512 static void get_green_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
513 int yp
, int up
, int vp
)
515 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
517 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
518 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
520 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
522 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
523 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
525 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
526 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
528 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
529 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
531 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
533 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
536 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
537 y2in
= y1in
+ i_in_pitch
;
538 y2out
= y1out
+ i_out_pitch
;
539 while( y1in
< y1end
)
546 *uout
++ = vlc_uint8( (*y1in
* -21710 + (*uin
-U
) * 7471 + (*vin
-V
) * 15504)
548 *vout
++ = vlc_uint8( (*y1in
* -27439 + (*uin
-U
) * 9443 + (*vin
-V
) * 19595)
550 *y1out
++ = vlc_uint8( (*y1in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
552 *y1out
++ = vlc_uint8( (*y1in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
554 *y2out
++ = vlc_uint8( (*y2in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
556 *y2out
++ = vlc_uint8( (*y2in
++ * 38470 + (*uin
++ - U
) * -13239 + (*vin
++ -V
) * -27473)
559 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
560 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
561 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
562 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
563 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
564 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
568 static void get_blue_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
569 int yp
, int up
, int vp
)
571 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
573 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
575 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
577 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
578 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
580 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
581 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
583 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
584 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
585 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
587 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
590 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
591 y2in
= y1in
+ i_in_pitch
;
592 y2out
= y1out
+ i_out_pitch
;
593 while( y1in
< y1end
)
600 *uout
++ = vlc_uint8( (*y1in
* 32768 + (*uin
- U
) * 58065 )
602 *vout
++ = vlc_uint8( (*y1in
* -5329 + (*uin
- U
) * -9443 )
604 *y1out
++ = vlc_uint8( (*y1in
++ * 7471 + (*uin
- U
) * 13239 )
606 *y1out
++ = vlc_uint8( (*y1in
++ * 7471 + (*uin
- U
) * 13239 )
608 *y2out
++ = vlc_uint8( (*y2in
++ * 7471 + (*uin
- U
) * 13239 )
610 *y2out
++ = vlc_uint8( (*y2in
++ * 7471 + (*uin
++ - U
) * 13239 )
613 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
614 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
615 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
616 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
617 vout
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
621 static void get_red_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
622 int yp
, int up
, int vp
)
624 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
625 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
627 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
628 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
629 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
631 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
632 const int i_out_pitch
= p_inpic
->p
[yp
].i_pitch
;
634 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
635 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
636 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
638 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
641 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
642 while( y1in
< y1end
)
649 *uout
++ = vlc_uint8( (*y1in
* -11058 + (*vin
- V
) * -15504)
651 *vout
++ = vlc_uint8( (*y1in
* 32768 + (*vin
- V
) * 45941)
653 *y1out
++ = vlc_uint8( (*y1in
++ * 19595 + (*vin
- V
) * 27473)
655 *y1out
++ = vlc_uint8( (*y1in
++ * 19595 + (*vin
++ - V
) * 27473)
658 y1in
+= i_in_pitch
- i_visible_pitch
;
659 y1out
+= i_out_pitch
- i_visible_pitch
;
660 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
661 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
662 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
666 static void get_green_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
667 int yp
, int up
, int vp
)
669 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
670 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
671 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
673 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
674 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
675 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
677 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
678 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
680 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
681 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
682 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
684 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
687 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
688 while( y1in
< y1end
)
695 *uout
++ = vlc_uint8( (*y1in
* -21710 + (*uin
-U
) * 7471 + (*vin
-V
) * 15504)
697 *vout
++ = vlc_uint8( (*y1in
* -27439 + (*uin
-U
) * 9443 + (*vin
-V
) * 19595)
699 *y1out
++ = vlc_uint8( (*y1in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
701 *y1out
++ = vlc_uint8( (*y1in
++ * 38470 + (*uin
++-U
) * -13239 + (*vin
++-V
) * -27473)
704 y1in
+= i_in_pitch
- i_visible_pitch
;
705 y1out
+= i_out_pitch
- i_visible_pitch
;
706 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
707 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
708 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
709 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
713 static void get_blue_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
714 int yp
, int up
, int vp
)
716 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
717 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
719 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
720 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
721 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
723 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
724 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
726 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
727 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
728 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
730 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
733 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
734 while( y1in
< y1end
)
741 *uout
++ = vlc_uint8( (*y1in
* 32768 + (*uin
- U
) * 58065 )
743 *vout
++ = vlc_uint8( (*y1in
* -5329 + (*uin
- U
) * -9443 )
745 *y1out
++ = vlc_uint8( (*y1in
++ * 7471 + (*uin
- U
) * 13239 )
747 *y1out
++ = vlc_uint8( (*y1in
++ * 7471 + (*uin
++ - U
) * 13239 )
750 y1in
+= i_in_pitch
- i_visible_pitch
;
751 y1out
+= i_out_pitch
- i_visible_pitch
;
752 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
753 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
754 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
758 static int ExtractCallback( vlc_object_t
*p_this
, char const *psz_var
,
759 vlc_value_t oldval
, vlc_value_t newval
,
763 filter_sys_t
*p_sys
= (filter_sys_t
*)p_data
;
765 vlc_mutex_lock( &p_sys
->lock
);
766 if( !strcmp( psz_var
, FILTER_PREFIX
"component" ) )
768 p_sys
->i_color
= newval
.i_int
;
769 /* Matrix won't be used for RED, GREEN or BLUE in planar formats */
770 make_projection_matrix( (filter_t
*)p_this
, p_sys
->i_color
,
771 p_sys
->projection_matrix
);
775 msg_Warn( p_this
, "Unknown callback command." );
777 vlc_mutex_unlock( &p_sys
->lock
);