1 /*****************************************************************************
2 * extract.c : Extract RGB components
3 *****************************************************************************
4 * Copyright (C) 2000-2006 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea .t videolan d@t org>
9 * This program 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 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, 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 filter2", 0 )
79 add_shortcut( "extract" )
81 add_integer_with_range( FILTER_PREFIX
"component", 0xFF0000, 1, 0xFFFFFF,
82 NULL
, COMPONENT_TEXT
, COMPONENT_LONGTEXT
, false )
83 change_integer_list( pi_component_values
, ppsz_component_descriptions
, NULL
)
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
);
255 static inline uint8_t crop( int a
)
257 if( a
< 0 ) return 0;
258 if( a
> 255 ) return 255;
259 else return (uint8_t)a
;
265 static void mmult( double *res
, double *a
, double *b
)
268 for( i
= 0; i
< 3; i
++ )
270 for( j
= 0; j
< 3; j
++ )
273 for( k
= 0; k
< 3; k
++ )
275 res
[ i
*3 + j
] += a
[ i
*3 + k
] * b
[ k
*3 + j
];
280 static void make_projection_matrix( filter_t
*p_filter
, int color
, int *matrix
)
282 double left_matrix
[9] =
283 { 76.24500, 149.68500, 29.07000,
284 -43.02765, -84.47235, 127.50000,
285 127.50000, -106.76534, -20.73466 };
286 double right_matrix
[9] =
287 { 257.00392, 0.00000, 360.31950,
288 257.00392, -88.44438, -183.53583,
289 257.00392, 455.41095, 0.00000 };
290 double red
= ((double)(( 0xFF0000 & color
)>>16))/255.;
291 double green
= ((double)(( 0x00FF00 & color
)>>8))/255.;
292 double blue
= ((double)( 0x0000FF & color
))/255.;
293 double norm
= sqrt( red
*red
+ green
*green
+ blue
*blue
);
297 /* XXX: We might still need to norm the rgb_matrix */
298 double rgb_matrix
[9] =
299 { red
*red
, red
*green
, red
*blue
,
300 red
*green
, green
*green
, green
*blue
,
301 red
*blue
, green
*blue
, blue
*blue
};
305 msg_Dbg( p_filter
, "red: %f", red
);
306 msg_Dbg( p_filter
, "green: %f", green
);
307 msg_Dbg( p_filter
, "blue: %f", blue
);
308 mmult( result1
, rgb_matrix
, right_matrix
);
309 mmult( result
, left_matrix
, result1
);
310 for( i
= 0; i
< 9; i
++ )
312 matrix
[i
] = (int)result
[i
];
314 msg_Dbg( p_filter
, "Projection matrix:" );
315 msg_Dbg( p_filter
, "%6d %6d %6d", matrix
[0], matrix
[1], matrix
[2] );
316 msg_Dbg( p_filter
, "%6d %6d %6d", matrix
[3], matrix
[4], matrix
[5] );
317 msg_Dbg( p_filter
, "%6d %6d %6d", matrix
[6], matrix
[7], matrix
[8] );
320 static void get_custom_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
321 int yp
, int up
, int vp
, int *m
)
323 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
325 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
326 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
328 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
330 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
331 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
333 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
334 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
336 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
337 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
338 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
340 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
343 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
344 y2in
= y1in
+ i_in_pitch
;
345 y2out
= y1out
+ i_out_pitch
;
346 while( y1in
< y1end
)
348 *uout
++ = crop( (*y1in
* m
[3] + (*uin
-U
) * m
[4] + (*vin
-V
) * m
[5])
350 *vout
++ = crop( (*y1in
* m
[6] + (*uin
-U
) * m
[7] + (*vin
-V
) * m
[8])
352 *y1out
++ = crop( (*y1in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
354 *y1out
++ = crop( (*y1in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
356 *y2out
++ = crop( (*y2in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
358 *y2out
++ = crop( (*y2in
++ * m
[0] + (*uin
++ - U
) * m
[1] + (*vin
++ -V
) * m
[2])
361 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
362 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
363 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
364 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
365 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
366 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
369 static void get_custom_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
370 int yp
, int up
, int vp
, int *m
)
372 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
373 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
374 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
376 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
377 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
378 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
380 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
381 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
383 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
384 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
385 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
387 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
390 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
391 while( y1in
< y1end
)
393 *uout
++ = crop( (*y1in
* m
[3] + (*uin
-U
) * m
[4] + (*vin
-V
) * m
[5])
395 *vout
++ = crop( (*y1in
* m
[6] + (*uin
-U
) * m
[7] + (*vin
-V
) * m
[8])
397 *y1out
++ = crop( (*y1in
++ * m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
399 *y1out
++ = crop( (*y1in
++ * m
[0] + (*uin
++ -U
) * m
[1] + (*vin
++ -V
) * m
[2])
402 y1in
+= i_in_pitch
- i_visible_pitch
;
403 y1out
+= i_out_pitch
- i_visible_pitch
;
404 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
405 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
406 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
407 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
411 static void get_custom_from_packedyuv422( picture_t
*p_inpic
,
415 int i_y_offset
, i_u_offset
, i_v_offset
;
416 if( GetPackedYuvOffsets( p_inpic
->format
.i_chroma
, &i_y_offset
,
417 &i_u_offset
, &i_v_offset
) != VLC_SUCCESS
)
420 uint8_t *yin
= p_inpic
->p
->p_pixels
+ i_y_offset
;
421 uint8_t *uin
= p_inpic
->p
->p_pixels
+ i_u_offset
;
422 uint8_t *vin
= p_inpic
->p
->p_pixels
+ i_v_offset
;
424 uint8_t *yout
= p_outpic
->p
->p_pixels
+ i_y_offset
;
425 uint8_t *uout
= p_outpic
->p
->p_pixels
+ i_u_offset
;
426 uint8_t *vout
= p_outpic
->p
->p_pixels
+ i_v_offset
;
428 const int i_in_pitch
= p_inpic
->p
->i_pitch
;
429 const int i_out_pitch
= p_outpic
->p
->i_pitch
;
430 const int i_visible_pitch
= p_inpic
->p
->i_visible_pitch
;
431 const int i_visible_lines
= p_inpic
->p
->i_visible_lines
;
433 const uint8_t *yend
= yin
+ i_visible_lines
* i_in_pitch
;
436 const uint8_t *ylend
= yin
+ i_visible_pitch
;
439 *uout
= crop( (*yin
* m
[3] + (*uin
-U
) * m
[4] + (*vin
-V
) * m
[5])
442 *vout
= crop( (*yin
* m
[6] + (*uin
-U
) * m
[7] + (*vin
-V
) * m
[8])
445 *yout
= crop( (*yin
* m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
449 *yout
= crop( (*yin
* m
[0] + (*uin
-U
) * m
[1] + (*vin
-V
) * m
[2])
456 yin
+= i_in_pitch
- i_visible_pitch
;
457 yout
+= i_out_pitch
- i_visible_pitch
;
458 uin
+= i_in_pitch
- i_visible_pitch
;
459 uout
+= i_out_pitch
- i_visible_pitch
;
460 vin
+= i_in_pitch
- i_visible_pitch
;
461 vout
+= i_out_pitch
- i_visible_pitch
;
465 static void get_red_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
466 int yp
, int up
, int vp
)
468 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
470 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
472 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
474 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
475 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
477 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
478 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
480 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
481 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
482 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
484 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
487 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
488 y2in
= y1in
+ i_in_pitch
;
489 y2out
= y1out
+ i_out_pitch
;
490 while( y1in
< y1end
)
497 *uout
++ = crop( (*y1in
* -11058 + (*vin
- V
) * -15504)
499 *vout
++ = crop( (*y1in
* 32768 + (*vin
- V
) * 45941)
501 *y1out
++ = crop( (*y1in
++ * 19595 + (*vin
- V
) * 27473)
503 *y1out
++ = crop( (*y1in
++ * 19595 + (*vin
- V
) * 27473)
505 *y2out
++ = crop( (*y2in
++ * 19594 + (*vin
- V
) * 27473)
507 *y2out
++ = crop( (*y2in
++ * 19594 + (*vin
++ - V
) * 27473)
510 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
511 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
512 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
513 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
514 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
518 static void get_green_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
519 int yp
, int up
, int vp
)
521 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
523 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
524 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
526 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
528 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
529 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
531 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
532 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
534 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
535 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
537 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
539 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
542 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
543 y2in
= y1in
+ i_in_pitch
;
544 y2out
= y1out
+ i_out_pitch
;
545 while( y1in
< y1end
)
552 *uout
++ = crop( (*y1in
* -21710 + (*uin
-U
) * 7471 + (*vin
-V
) * 15504)
554 *vout
++ = crop( (*y1in
* -27439 + (*uin
-U
) * 9443 + (*vin
-V
) * 19595)
556 *y1out
++ = crop( (*y1in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
558 *y1out
++ = crop( (*y1in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
560 *y2out
++ = crop( (*y2in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
562 *y2out
++ = crop( (*y2in
++ * 38470 + (*uin
++ - U
) * -13239 + (*vin
++ -V
) * -27473)
565 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
566 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
567 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
568 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
569 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
570 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
574 static void get_blue_from_yuv420( picture_t
*p_inpic
, picture_t
*p_outpic
,
575 int yp
, int up
, int vp
)
577 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
579 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
581 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
583 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
584 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
586 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
587 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
589 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
590 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
591 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
593 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
596 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
597 y2in
= y1in
+ i_in_pitch
;
598 y2out
= y1out
+ i_out_pitch
;
599 while( y1in
< y1end
)
606 *uout
++ = crop( (*y1in
* 32768 + (*uin
- U
) * 58065 )
608 *vout
++ = crop( (*y1in
* -5329 + (*uin
- U
) * -9443 )
610 *y1out
++ = crop( (*y1in
++ * 7471 + (*uin
- U
) * 13239 )
612 *y1out
++ = crop( (*y1in
++ * 7471 + (*uin
- U
) * 13239 )
614 *y2out
++ = crop( (*y2in
++ * 7471 + (*uin
- U
) * 13239 )
616 *y2out
++ = crop( (*y2in
++ * 7471 + (*uin
++ - U
) * 13239 )
619 y1in
+= 2*i_in_pitch
- i_visible_pitch
;
620 y1out
+= 2*i_out_pitch
- i_visible_pitch
;
621 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
622 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
623 vout
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
627 static void get_red_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
628 int yp
, int up
, int vp
)
630 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
631 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
633 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
634 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
635 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
637 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
638 const int i_out_pitch
= p_inpic
->p
[yp
].i_pitch
;
640 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
641 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
642 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
644 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
647 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
648 while( y1in
< y1end
)
655 *uout
++ = crop( (*y1in
* -11058 + (*vin
- V
) * -15504)
657 *vout
++ = crop( (*y1in
* 32768 + (*vin
- V
) * 45941)
659 *y1out
++ = crop( (*y1in
++ * 19595 + (*vin
- V
) * 27473)
661 *y1out
++ = crop( (*y1in
++ * 19595 + (*vin
++ - V
) * 27473)
664 y1in
+= i_in_pitch
- i_visible_pitch
;
665 y1out
+= i_out_pitch
- i_visible_pitch
;
666 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
667 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
668 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
672 static void get_green_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
673 int yp
, int up
, int vp
)
675 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
676 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
677 uint8_t *vin
= p_inpic
->p
[vp
].p_pixels
;
679 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
680 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
681 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
683 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
684 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
686 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
687 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
688 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
690 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
693 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
694 while( y1in
< y1end
)
701 *uout
++ = crop( (*y1in
* -21710 + (*uin
-U
) * 7471 + (*vin
-V
) * 15504)
703 *vout
++ = crop( (*y1in
* -27439 + (*uin
-U
) * 9443 + (*vin
-V
) * 19595)
705 *y1out
++ = crop( (*y1in
++ * 38470 + (*uin
-U
) * -13239 + (*vin
-V
) * -27473)
707 *y1out
++ = crop( (*y1in
++ * 38470 + (*uin
++-U
) * -13239 + (*vin
++-V
) * -27473)
710 y1in
+= i_in_pitch
- i_visible_pitch
;
711 y1out
+= i_out_pitch
- i_visible_pitch
;
712 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
713 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
714 vin
+= p_inpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
715 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
719 static void get_blue_from_yuv422( picture_t
*p_inpic
, picture_t
*p_outpic
,
720 int yp
, int up
, int vp
)
722 uint8_t *y1in
= p_inpic
->p
[yp
].p_pixels
;
723 uint8_t *uin
= p_inpic
->p
[up
].p_pixels
;
725 uint8_t *y1out
= p_outpic
->p
[yp
].p_pixels
;
726 uint8_t *uout
= p_outpic
->p
[up
].p_pixels
;
727 uint8_t *vout
= p_outpic
->p
[vp
].p_pixels
;
729 const int i_in_pitch
= p_inpic
->p
[yp
].i_pitch
;
730 const int i_out_pitch
= p_outpic
->p
[yp
].i_pitch
;
732 const int i_visible_pitch
= p_inpic
->p
[yp
].i_visible_pitch
;
733 const int i_visible_lines
= p_inpic
->p
[yp
].i_visible_lines
;
734 const int i_uv_visible_pitch
= p_inpic
->p
[up
].i_visible_pitch
;
736 const uint8_t *yend
= y1in
+ i_visible_lines
* i_in_pitch
;
739 const uint8_t *y1end
= y1in
+ i_visible_pitch
;
740 while( y1in
< y1end
)
747 *uout
++ = crop( (*y1in
* 32768 + (*uin
- U
) * 58065 )
749 *vout
++ = crop( (*y1in
* -5329 + (*uin
- U
) * -9443 )
751 *y1out
++ = crop( (*y1in
++ * 7471 + (*uin
- U
) * 13239 )
753 *y1out
++ = crop( (*y1in
++ * 7471 + (*uin
++ - U
) * 13239 )
756 y1in
+= i_in_pitch
- i_visible_pitch
;
757 y1out
+= i_out_pitch
- i_visible_pitch
;
758 uin
+= p_inpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
759 uout
+= p_outpic
->p
[up
].i_pitch
- i_uv_visible_pitch
;
760 vout
+= p_outpic
->p
[vp
].i_pitch
- i_uv_visible_pitch
;
764 static int ExtractCallback( vlc_object_t
*p_this
, char const *psz_var
,
765 vlc_value_t oldval
, vlc_value_t newval
,
769 filter_sys_t
*p_sys
= (filter_sys_t
*)p_data
;
771 vlc_mutex_lock( &p_sys
->lock
);
772 if( !strcmp( psz_var
, FILTER_PREFIX
"component" ) )
774 p_sys
->i_color
= newval
.i_int
;
775 /* Matrix won't be used for RED, GREEN or BLUE in planar formats */
776 make_projection_matrix( (filter_t
*)p_this
, p_sys
->i_color
,
777 p_sys
->projection_matrix
);
781 msg_Warn( p_this
, "Unknown callback command." );
783 vlc_mutex_unlock( &p_sys
->lock
);