2014-08-03 19:13:24 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
* Copyright ( C ) 2005 - 2014 , Anthony Minessale II < anthm @ freeswitch . org >
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
* Seven Du < dujinfang @ gmail . com >
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
*
* switch_core_video . c - - Core Video
*
*/
# include <switch.h>
SWITCH_DECLARE ( switch_image_t * ) switch_img_alloc ( switch_image_t * img ,
switch_img_fmt_t fmt ,
unsigned int d_w ,
unsigned int d_h ,
unsigned int align )
{
return ( switch_image_t * ) vpx_img_alloc ( ( vpx_image_t * ) img , ( vpx_img_fmt_t ) fmt , d_w , d_h , align ) ;
}
SWITCH_DECLARE ( switch_image_t * ) switch_img_wrap ( switch_image_t * img ,
switch_img_fmt_t fmt ,
unsigned int d_w ,
unsigned int d_h ,
unsigned int align ,
unsigned char * img_data )
{
return ( switch_image_t * ) vpx_img_wrap ( ( vpx_image_t * ) img , ( vpx_img_fmt_t ) fmt , d_w , d_h , align , img_data ) ;
}
SWITCH_DECLARE ( int ) switch_img_set_rect ( switch_image_t * img ,
unsigned int x ,
unsigned int y ,
unsigned int w ,
unsigned int h )
{
return vpx_img_set_rect ( ( vpx_image_t * ) img , x , y , w , h ) ;
}
SWITCH_DECLARE ( void ) switch_img_flip ( switch_image_t * img )
{
vpx_img_flip ( ( vpx_image_t * ) img ) ;
}
2014-11-25 21:01:52 +00:00
SWITCH_DECLARE ( void ) switch_img_free ( switch_image_t * * img )
2014-08-03 19:13:24 +00:00
{
2014-11-25 21:01:52 +00:00
if ( img & & * img ) {
vpx_img_free ( ( vpx_image_t * ) * img ) ;
2015-01-29 00:42:17 +00:00
* img = NULL ;
2014-11-25 21:01:52 +00:00
}
2014-08-03 19:13:24 +00:00
}
2015-02-08 01:23:47 +00:00
# ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
# endif
2015-02-05 02:23:17 +00:00
// simple implementation to patch a small img to a big IMG at position x,y
SWITCH_DECLARE ( void ) switch_img_patch ( switch_image_t * IMG , switch_image_t * img , int x , int y )
{
2015-02-08 01:23:47 +00:00
int i , len ;
2015-02-05 02:23:17 +00:00
switch_assert ( img - > fmt = = SWITCH_IMG_FMT_I420 ) ;
switch_assert ( IMG - > fmt = = SWITCH_IMG_FMT_I420 ) ;
2015-02-08 01:23:47 +00:00
len = MIN ( img - > d_w , IMG - > d_w - x ) ;
if ( len < = 0 ) return ;
2015-02-05 02:23:17 +00:00
2015-02-08 01:23:47 +00:00
for ( i = y ; i < ( y + img - > d_h ) & & i < IMG - > d_h ; i + + ) {
memcpy ( IMG - > planes [ SWITCH_PLANE_Y ] + IMG - > stride [ SWITCH_PLANE_Y ] * i + x , img - > planes [ SWITCH_PLANE_Y ] + img - > stride [ SWITCH_PLANE_Y ] * ( i - y ) , len ) ;
2015-02-05 02:23:17 +00:00
}
2015-02-08 01:23:47 +00:00
len / = 2 ;
2015-02-05 02:23:17 +00:00
2015-02-08 01:23:47 +00:00
for ( i = y ; i < ( y + img - > d_h ) & & i < IMG - > d_h ; i + = 2 ) {
memcpy ( IMG - > planes [ SWITCH_PLANE_U ] + IMG - > stride [ SWITCH_PLANE_U ] * i / 2 + x / 2 , img - > planes [ SWITCH_PLANE_U ] + img - > stride [ SWITCH_PLANE_U ] * ( i - y ) / 2 , len ) ;
memcpy ( IMG - > planes [ SWITCH_PLANE_V ] + IMG - > stride [ SWITCH_PLANE_V ] * i / 2 + x / 2 , img - > planes [ SWITCH_PLANE_V ] + img - > stride [ SWITCH_PLANE_V ] * ( i - y ) / 2 , len ) ;
}
}
2015-02-05 02:23:17 +00:00
2015-01-17 17:32:17 +00:00
SWITCH_DECLARE ( void ) switch_img_copy ( switch_image_t * img , switch_image_t * * new_img )
{
2015-02-05 02:23:17 +00:00
int i = 0 ;
2015-01-28 03:14:51 +00:00
2015-01-17 17:32:17 +00:00
switch_assert ( img ) ;
2015-01-28 00:21:19 +00:00
switch_assert ( new_img ) ;
2015-01-17 17:32:17 +00:00
if ( ! img - > fmt = = SWITCH_IMG_FMT_I420 ) return ;
2015-01-28 00:21:19 +00:00
if ( * new_img ! = NULL ) {
if ( img - > d_w ! = ( * new_img ) - > d_w | | img - > d_h ! = ( * new_img ) - > d_w ) {
switch_img_free ( new_img ) ;
}
2015-01-17 17:32:17 +00:00
}
if ( * new_img = = NULL ) {
2015-01-28 01:58:05 +00:00
* new_img = switch_img_alloc ( NULL , SWITCH_IMG_FMT_I420 , img - > d_w , img - > d_h , 1 ) ;
2015-01-17 17:32:17 +00:00
}
2015-01-28 08:41:36 +00:00
2015-01-17 17:32:17 +00:00
switch_assert ( * new_img ) ;
2015-01-28 01:58:05 +00:00
2015-01-28 08:41:36 +00:00
for ( i = 0 ; i < ( * new_img ) - > h ; i + + ) {
memcpy ( ( * new_img ) - > planes [ SWITCH_PLANE_Y ] + ( * new_img ) - > stride [ SWITCH_PLANE_Y ] * i , img - > planes [ SWITCH_PLANE_Y ] + img - > stride [ SWITCH_PLANE_Y ] * i , img - > d_w ) ;
}
for ( i = 0 ; i < ( * new_img ) - > h / 2 ; i + + ) {
2015-01-28 16:52:21 +00:00
memcpy ( ( * new_img ) - > planes [ SWITCH_PLANE_U ] + ( * new_img ) - > stride [ SWITCH_PLANE_U ] * i , img - > planes [ SWITCH_PLANE_U ] + img - > stride [ SWITCH_PLANE_U ] * i , img - > d_w / 2 ) ;
memcpy ( ( * new_img ) - > planes [ SWITCH_PLANE_V ] + ( * new_img ) - > stride [ SWITCH_PLANE_V ] * i , img - > planes [ SWITCH_PLANE_V ] + img - > stride [ SWITCH_PLANE_V ] * i , img - > d_w / 2 ) ;
2015-01-28 01:58:05 +00:00
}
2015-02-05 02:23:17 +00:00
2015-01-17 17:32:17 +00:00
}
2015-02-10 03:30:31 +00:00
SWITCH_DECLARE ( switch_image_t * ) switch_img_copy_rect ( switch_image_t * img , int x , int y , int w , int h )
{
switch_image_t * new_img = NULL ;
int i = 0 ;
int len ;
switch_assert ( img ) ;
switch_assert ( x > = 0 & & y > = 0 & & w > = 0 & & h > = 0 ) ;
if ( ! img - > fmt = = SWITCH_IMG_FMT_I420 ) return NULL ;
new_img = switch_img_alloc ( NULL , SWITCH_IMG_FMT_I420 , w , h , 1 ) ;
if ( new_img = = NULL ) return NULL ;
len = MIN ( img - > d_w - x , w ) ;
if ( len < = 0 ) return NULL ;
for ( i = 0 ; i < ( img - > d_h - y ) & & i < h ; i + + ) {
memcpy ( new_img - > planes [ SWITCH_PLANE_Y ] + new_img - > stride [ SWITCH_PLANE_Y ] * i , img - > planes [ SWITCH_PLANE_Y ] + img - > stride [ SWITCH_PLANE_Y ] * ( y + i ) + x , len ) ;
}
len / = 2 ;
for ( i = 0 ; i < ( img - > d_h - y ) & & i < h ; i + = 2 ) {
memcpy ( new_img - > planes [ SWITCH_PLANE_U ] + new_img - > stride [ SWITCH_PLANE_U ] * i / 2 , img - > planes [ SWITCH_PLANE_U ] + img - > stride [ SWITCH_PLANE_U ] * ( y + i ) / 2 + x / 2 , len ) ;
memcpy ( new_img - > planes [ SWITCH_PLANE_V ] + new_img - > stride [ SWITCH_PLANE_V ] * i / 2 , img - > planes [ SWITCH_PLANE_V ] + img - > stride [ SWITCH_PLANE_V ] * ( y + i ) / 2 + x / 2 , len ) ;
}
return new_img ;
}
2015-02-11 06:57:02 +00:00
SWITCH_DECLARE ( void ) switch_img_draw_pixel ( switch_image_t * img , int x , int y , switch_yuv_color_t color )
2015-02-10 03:30:31 +00:00
{
if ( x < 0 | | y < 0 | | x > = img - > d_w | | y > = img - > d_h ) return ;
img - > planes [ SWITCH_PLANE_Y ] [ y * img - > stride [ SWITCH_PLANE_Y ] + x ] = color . y ;
if ( ( ( x & 0x1 ) = = 0 ) & & ( ( y & 0x1 ) = = 0 ) ) { // only draw on even position
img - > planes [ SWITCH_PLANE_U ] [ y / 2 * img - > stride [ SWITCH_PLANE_U ] + x / 2 ] = color . u ;
img - > planes [ SWITCH_PLANE_V ] [ y / 2 * img - > stride [ SWITCH_PLANE_V ] + x / 2 ] = color . v ;
}
}
2015-02-06 17:41:15 +00:00
2015-02-11 06:57:02 +00:00
SWITCH_DECLARE ( void ) switch_img_fill ( switch_image_t * img , int x , int y , int w , int h , switch_yuv_color_t color )
{
int len , i ;
if ( x < 0 | | y < 0 | | x > = img - > d_w | | y > = img - > d_h ) return ;
len = MIN ( w , img - > d_w - x ) ;
if ( len < = 0 ) return ;
for ( i = y ; i < ( y + h ) & & i < img - > d_h ; i + + ) {
memset ( img - > planes [ SWITCH_PLANE_Y ] + img - > stride [ SWITCH_PLANE_Y ] * i + x , color . y , len ) ;
}
len / = 2 ;
for ( i = y ; i < ( y + h ) & & i < img - > d_h ; i + = 2 ) {
memset ( img - > planes [ SWITCH_PLANE_U ] + img - > stride [ SWITCH_PLANE_U ] * i / 2 + x / 2 , color . u , len ) ;
memset ( img - > planes [ SWITCH_PLANE_V ] + img - > stride [ SWITCH_PLANE_V ] * i / 2 + x / 2 , color . v , len ) ;
}
}
2015-02-06 17:41:15 +00:00
static uint8_t scv_art [ 14 ] [ 16 ] = {
{ 0x00 , 0x7E , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x7E , 0x00 } ,
{ 0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x00 } ,
{ 0x00 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x7E , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x7E , 0x00 } ,
{ 0x00 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x7E , 0x00 } ,
{ 0x00 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x00 } ,
{ 0x00 , 0x7E , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x7E , 0x00 } ,
{ 0x00 , 0x7E , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x7E , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x7E , 0x00 } ,
{ 0x00 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x00 } ,
{ 0x00 , 0x7E , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x7E , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x7E , 0x00 } ,
{ 0x00 , 0x7E , 0x42 , 0x42 , 0x42 , 0x42 , 0x42 , 0x7E , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x7E , 0x00 } ,
{ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x20 , 0x00 , 0x00 , 0x00 } , /*.*/
{ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x20 , 0x00 , 0x00 , 0x00 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /*:*/
{ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x7E , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /*-*/
{ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* */
} ;
static void scv_tag ( void * buffer , int w , int x , int y , uint8_t n )
{
int i = 0 , j = 0 ;
uint8_t * p = buffer ;
if ( n < 0 | | n > 13 ) return ;
for ( i = 0 ; i < 8 ; i + + ) {
for ( j = 0 ; j < 16 ; j + + ) {
* ( p + ( y + j ) * w + ( x + i ) ) = ( scv_art [ n ] [ j ] & 0x80 > > i ) ? 0xFF : 0x00 ;
}
}
}
SWITCH_DECLARE ( void ) switch_img_add_text ( void * buffer , int w , int x , int y , char * s )
{
while ( * s ) {
int index ;
if ( x > w - 8 ) break ;
switch ( * s ) {
case ' . ' : index = 10 ; break ;
case ' : ' : index = 11 ; break ;
case ' - ' : index = 12 ; break ;
case ' ' : index = 13 ; break ;
default :
index = * s - 0x30 ;
}
scv_tag ( buffer , w , x , y , index ) ;
x + = 8 ;
s + + ;
}
}
2015-02-10 03:30:31 +00:00
SWITCH_DECLARE ( void ) switch_color_set ( switch_yuv_color_t * color , char * color_str )
{
uint8_t y = 134 ;
uint8_t u = 128 ;
uint8_t v = 124 ;
if ( color_str ! = NULL & & strlen ( color_str ) = = 7 ) {
uint8_t red , green , blue ;
char str [ 7 ] ;
color_str + + ;
strncpy ( str , color_str , 6 ) ;
red = ( str [ 0 ] > = ' A ' ? ( str [ 0 ] - ' A ' + 10 ) * 16 : ( str [ 0 ] - ' 0 ' ) * 16 ) + ( str [ 1 ] > = ' A ' ? ( str [ 1 ] - ' A ' + 10 ) : ( str [ 0 ] - ' 0 ' ) ) ;
green = ( str [ 2 ] > = ' A ' ? ( str [ 2 ] - ' A ' + 10 ) * 16 : ( str [ 2 ] - ' 0 ' ) * 16 ) + ( str [ 3 ] > = ' A ' ? ( str [ 3 ] - ' A ' + 10 ) : ( str [ 0 ] - ' 0 ' ) ) ;
blue = ( str [ 4 ] > = ' A ' ? ( str [ 4 ] - ' A ' + 10 ) * 16 : ( str [ 4 ] - ' 0 ' ) * 16 ) + ( str [ 5 ] > = ' A ' ? ( str [ 5 ] - ' A ' + 10 ) : ( str [ 0 ] - ' 0 ' ) ) ;
y = ( uint8_t ) ( ( ( red * 4897 ) > > 14 ) + ( ( green * 9611 ) > > 14 ) + ( ( blue * 1876 ) > > 14 ) ) ;
u = ( uint8_t ) ( - ( ( red * 2766 ) > > 14 ) - ( ( 5426 * green ) > > 14 ) + blue / 2 + 128 ) ;
v = ( uint8_t ) ( red / 2 - ( ( 6855 * green ) > > 14 ) - ( ( blue * 1337 ) > > 14 ) + 128 ) ;
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "set color, red = %u, green = %u, blue = %u, y = %u, u = %u, v = %u\n", red, green, blue, y, u, v);
}
color - > y = y ;
color - > u = u ;
color - > v = v ;
}
2015-02-06 17:41:15 +00:00
2014-08-03 19:13:24 +00:00
/* For Emacs:
* Local Variables :
* mode : c
* indent - tabs - mode : t
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 noet :
*/