예제 #1
0
picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_resource_t *p_resource )
{
    video_format_t fmt = *p_fmt;

    /* It is needed to be sure all information are filled */
    video_format_Setup( &fmt, p_fmt->i_chroma,
                              p_fmt->i_width, p_fmt->i_height,
                              p_fmt->i_sar_num, p_fmt->i_sar_den );
    if( p_fmt->i_x_offset < p_fmt->i_width &&
        p_fmt->i_y_offset < p_fmt->i_height &&
        p_fmt->i_visible_width  > 0 && p_fmt->i_x_offset + p_fmt->i_visible_width  <= p_fmt->i_width &&
        p_fmt->i_visible_height > 0 && p_fmt->i_y_offset + p_fmt->i_visible_height <= p_fmt->i_height )
        video_format_CopyCrop( &fmt, p_fmt );

    /* */
    picture_t *p_picture = calloc( 1, sizeof(*p_picture) );
    if( !p_picture )
        return NULL;

    if( p_resource )
    {
        if( picture_Setup( p_picture, fmt.i_chroma, fmt.i_width, fmt.i_height,
                           fmt.i_sar_num, fmt.i_sar_den ) )
        {
            free( p_picture );
            return NULL;
        }
        p_picture->p_sys = p_resource->p_sys;

        for( int i = 0; i < p_picture->i_planes; i++ )
        {
            p_picture->p[i].p_pixels = p_resource->p[i].p_pixels;
            p_picture->p[i].i_lines  = p_resource->p[i].i_lines;
            p_picture->p[i].i_pitch  = p_resource->p[i].i_pitch;
        }
    }
    else
    {
        if( vout_AllocatePicture( p_picture,
                                  fmt.i_chroma, fmt.i_width, fmt.i_height,
                                  fmt.i_sar_num, fmt.i_sar_den ) )
        {
            free( p_picture );
            return NULL;
        }
    }
    /* */
    p_picture->format = fmt;
    p_picture->i_refcount = 1;
    p_picture->pf_release = PictureReleaseCallback;

    return p_picture;
}
예제 #2
0
/*****************************************************************************
 * Init: initialize video thread
 *****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
    int i_index;
    picture_t *p_pic;

    /* Initialize the output structure */
    p_vout->output.i_chroma = p_vout->render.i_chroma;
    p_vout->output.pf_setpalette = NULL;
    p_vout->output.i_width = p_vout->render.i_width;
    p_vout->output.i_height = p_vout->render.i_height;
    p_vout->output.i_aspect = p_vout->output.i_width
                               * VOUT_ASPECT_FACTOR / p_vout->output.i_height;

    p_vout->output.i_rmask = 0xff0000;
    p_vout->output.i_gmask = 0x00ff00;
    p_vout->output.i_bmask = 0x0000ff;

    /* Try to initialize 1 direct buffer */
    p_pic = NULL;

    /* Find an empty picture slot */
    for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
    {
        if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
        {
            p_pic = p_vout->p_picture + i_index;
            break;
        }
    }

    /* Allocate the picture */
    if( p_pic == NULL )
    {
        return VLC_EGENERIC;
    }

    vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma,
                          p_vout->output.i_width, p_vout->output.i_height,
                          p_vout->output.i_aspect );

    if( p_pic->i_planes == 0 )
    {
        return VLC_EGENERIC;
    }

    p_pic->i_status = DESTROYED_PICTURE;
    p_pic->i_type   = DIRECT_PICTURE;

    PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
    I_OUTPUTPICTURES++;
    return VLC_SUCCESS;
}
예제 #3
0
파일: logo.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * LoadPNG: loads the PNG logo into memory
 *****************************************************************************/
static picture_t *LoadPNG( vlc_object_t *p_this )
{
    picture_t *p_pic;
    char *psz_filename;
    vlc_value_t val;
    FILE *file;
    int i, j, i_trans;
    vlc_bool_t b_alpha = VLC_TRUE;

    png_uint_32 i_width, i_height;
    int i_color_type, i_interlace_type, i_compression_type, i_filter_type;
    int i_bit_depth;
    png_bytep *p_row_pointers;
    png_structp p_png;
    png_infop p_info, p_end_info;

    var_Create( p_this, "logo-file", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
    var_Get( p_this, "logo-file", &val );
    psz_filename = val.psz_string;
    if( !psz_filename || !*psz_filename )
    {
        msg_Err( p_this, "logo file not specified" );
        return 0;
    }

    if( !(file = fopen( psz_filename , "rb" )) )
    {
        msg_Err( p_this, "logo file (%s) not found", psz_filename );
        free( psz_filename );
        return 0;
    }
    free( psz_filename );

    p_png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
    p_info = png_create_info_struct( p_png );
    p_end_info = png_create_info_struct( p_png );
    png_init_io( p_png, file );
    png_read_info( p_png, p_info );
    png_get_IHDR( p_png, p_info, &i_width, &i_height,
                  &i_bit_depth, &i_color_type, &i_interlace_type,
                  &i_compression_type, &i_filter_type);

    if( i_color_type == PNG_COLOR_TYPE_PALETTE )
        png_set_palette_to_rgb( p_png );

    if( i_color_type == PNG_COLOR_TYPE_GRAY ||
        i_color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
          png_set_gray_to_rgb( p_png );

    if( png_get_valid( p_png, p_info, PNG_INFO_tRNS ) )
    {
        png_set_tRNS_to_alpha( p_png );
    }
    else if( !(i_color_type & PNG_COLOR_MASK_ALPHA) )
    {
        b_alpha = VLC_FALSE;
    }

    p_row_pointers = malloc( sizeof(png_bytep) * i_height );
    for( i = 0; i < (int)i_height; i++ )
        p_row_pointers[i] = malloc( 4 * ( i_bit_depth + 7 ) / 8 * i_width );

    png_read_image( p_png, p_row_pointers );
    png_read_end( p_png, p_end_info );

    fclose( file );
    png_destroy_read_struct( &p_png, &p_info, &p_end_info );

    /* Convert to YUVA */
    p_pic = malloc( sizeof(picture_t) );
    if( vout_AllocatePicture( p_this, p_pic, VLC_FOURCC('Y','U','V','A'),
                              i_width, i_height, VOUT_ASPECT_FACTOR ) !=
        VLC_SUCCESS )
    {
        for( i = 0; i < (int)i_height; i++ ) free( p_row_pointers[i] );
        free( p_row_pointers );
        return 0;
    }

    var_Create(p_this, "logo-transparency", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT);
    var_Get( p_this, "logo-transparency", &val );
    i_trans = __MAX( __MIN( val.i_int, 255 ), 0 );

    for( j = 0; j < (int)i_height ; j++ )
    {
        uint8_t *p = (uint8_t *)p_row_pointers[j];

        for( i = 0; i < (int)i_width ; i++ )
        {
            int i_offset = i + j * p_pic->p[Y_PLANE].i_pitch;

            p_pic->p[Y_PLANE].p_pixels[i_offset] =
                (p[0] * 257L + p[1] * 504 + p[2] * 98)/1000 + 16;
            p_pic->p[U_PLANE].p_pixels[i_offset] =
                (p[2] * 439L - p[0] * 148 - p[1] * 291)/1000 + 128;
            p_pic->p[V_PLANE].p_pixels[i_offset] =
                (p[0] * 439L - p[1] * 368 - p[2] * 71)/1000 + 128;
            p_pic->p[A_PLANE].p_pixels[i_offset] =
                b_alpha ? (p[3] * i_trans) / 255 : i_trans;

            p += (b_alpha ? 4 : 3);
        }
    }

    for( i = 0; i < (int)i_height; i++ ) free( p_row_pointers[i] );
    free( p_row_pointers );
    return p_pic;
}
예제 #4
0
/*****************************************************************************
 * Init: initialize video thread
 *****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
    int i_index;
    picture_t *p_pic;
    vlc_value_t val;
    char* psz_chroma;
    int i_chroma;
    int i_width;
    int i_height;
    int i_datasize;

    i_width  = config_GetInt( p_vout, "snapshot-width" );
    i_height = config_GetInt( p_vout, "snapshot-height" );

    psz_chroma = config_GetPsz( p_vout, "snapshot-chroma" );
    if( psz_chroma )
    {
        if( strlen( psz_chroma ) < 4 )
        {
            msg_Err( p_vout, "snapshot-chroma should be 4 characters long" );
            return VLC_EGENERIC;
        }
        i_chroma = VLC_FOURCC( psz_chroma[0], psz_chroma[1],
                               psz_chroma[2], psz_chroma[3] );
        free( psz_chroma );
    }
    else
    {
        msg_Err( p_vout, "Cannot find chroma information." );
        return VLC_EGENERIC;
    }

    I_OUTPUTPICTURES = 0;

    /* Initialize the output structure */
    p_vout->output.i_chroma = i_chroma;
    p_vout->output.pf_setpalette = NULL;
    p_vout->output.i_width = i_width;
    p_vout->output.i_height = i_height;
    p_vout->output.i_aspect = p_vout->output.i_width
                               * VOUT_ASPECT_FACTOR / p_vout->output.i_height;


    /* Define the bitmasks */
    switch( i_chroma )
    {
      case VLC_FOURCC( 'R','V','1','5' ):
        p_vout->output.i_rmask = 0x001f;
        p_vout->output.i_gmask = 0x03e0;
        p_vout->output.i_bmask = 0x7c00;
        break;

      case VLC_FOURCC( 'R','V','1','6' ):
        p_vout->output.i_rmask = 0x001f;
        p_vout->output.i_gmask = 0x07e0;
        p_vout->output.i_bmask = 0xf800;
        break;

      case VLC_FOURCC( 'R','V','2','4' ):
        p_vout->output.i_rmask = 0xff0000;
        p_vout->output.i_gmask = 0x00ff00;
        p_vout->output.i_bmask = 0x0000ff;
        break;

      case VLC_FOURCC( 'R','V','3','2' ):
        p_vout->output.i_rmask = 0xff0000;
        p_vout->output.i_gmask = 0x00ff00;
        p_vout->output.i_bmask = 0x0000ff;
        break;
    }

    /* Try to initialize 1 direct buffer */
    p_pic = NULL;

    /* Find an empty picture slot */
    for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
    {
        if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
        {
            p_pic = p_vout->p_picture + i_index;
            break;
        }
    }

    /* Allocate the picture */
    if( p_pic == NULL )
    {
        return VLC_SUCCESS;
    }

    vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma,
                          p_vout->output.i_width, p_vout->output.i_height,
                          p_vout->output.i_aspect );

    if( p_pic->i_planes == 0 )
    {
        return VLC_EGENERIC;
    }

    p_pic->i_status = DESTROYED_PICTURE;
    p_pic->i_type   = DIRECT_PICTURE;

    PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;

    I_OUTPUTPICTURES++;


    /* Get datasize and set variables */
    i_datasize = i_width * i_height * p_pic->p->i_pixel_pitch;

    p_vout->p_sys->i_datasize = i_datasize;
    p_vout->p_sys->i_index = 0;
    p_vout->p_sys->i_size = config_GetInt( p_vout, "snapshot-cache-size" );

    if( p_vout->p_sys->i_size < 2 )
    {
        msg_Err( p_vout, "snapshot-cache-size must be at least 1." );
        return VLC_EGENERIC;
    }

    p_vout->p_sys->p_list = malloc( p_vout->p_sys->i_size * sizeof( snapshot_t * ) );

    if( p_vout->p_sys->p_list == NULL )
        return VLC_ENOMEM;

    /* Initialize the structures for the circular buffer */
    for( i_index = 0; i_index < p_vout->p_sys->i_size; i_index++ )
    {
        snapshot_t *p_snapshot = malloc( sizeof( snapshot_t ) );

        if( p_snapshot == NULL )
            return VLC_ENOMEM;

        p_snapshot->i_width = i_width;
        p_snapshot->i_height = i_height;
        p_snapshot->i_datasize = i_datasize;
        p_snapshot->date = 0;
        p_snapshot->p_data = ( char* ) malloc( i_datasize );
        if( p_snapshot->p_data == NULL )
            return VLC_ENOMEM;
        p_vout->p_sys->p_list[i_index] = p_snapshot;
    }

    val.i_int = i_width;
    var_Set( p_vout, "snapshot-width", val );
    val.i_int = i_height;
    var_Set( p_vout, "snapshot-height", val );
    val.i_int = i_datasize;
    var_Set( p_vout, "snapshot-datasize", val );

    val.i_int = p_vout->p_sys->i_size;
    var_Set( p_vout, "snapshot-cache-size", val );

    val.p_address = p_vout->p_sys->p_list;
    var_Set( p_vout, "snapshot-list-pointer", val );

    /* Get the p_input pointer (to access video times) */
    p_vout->p_sys->p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
                                              FIND_PARENT );

    if( !p_vout->p_sys->p_input )
        return VLC_ENOOBJ;

    if( var_Create( p_vout->p_sys->p_input, "snapshot-id", VLC_VAR_INTEGER ) )
    {
        msg_Err( p_vout, "Cannot create snapshot-id variable in p_input (%d).",
                 p_vout->p_sys->p_input->i_object_id );
        return VLC_EGENERIC;
    }

    /* Register the snapshot vout module at the input level */
    val.i_int = p_vout->i_object_id;

    if( var_Set( p_vout->p_sys->p_input, "snapshot-id", val ) )
    {
        msg_Err( p_vout, "Cannot register snapshot-id in p_input (%d).",
                 p_vout->p_sys->p_input->i_object_id );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
예제 #5
0
/*****************************************************************************
 * Init: initialize dummy video thread output method
 *****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
    int i_index, i_chroma;
    char *psz_chroma;
    picture_t *p_pic;
    vlc_bool_t b_chroma = 0;

    psz_chroma = config_GetPsz( p_vout, "dummy-chroma" );
    if( psz_chroma )
    {
        if( strlen( psz_chroma ) >= 4 )
        {
            i_chroma = VLC_FOURCC( psz_chroma[0], psz_chroma[1],
                                   psz_chroma[2], psz_chroma[3] );
            b_chroma = 1;
        }

        free( psz_chroma );
    }

    I_OUTPUTPICTURES = 0;

    /* Initialize the output structure */
    if( b_chroma )
    {
        msg_Dbg( p_vout, "forcing chroma 0x%.8x (%4.4s)",
                         i_chroma, (char*)&i_chroma );
        p_vout->output.i_chroma = i_chroma;
        if ( i_chroma == VLC_FOURCC( 'R', 'G', 'B', '2' ) )
        {
            p_vout->output.pf_setpalette = SetPalette;
        }
        p_vout->output.i_width  = p_vout->render.i_width;
        p_vout->output.i_height = p_vout->render.i_height;
        p_vout->output.i_aspect = p_vout->render.i_aspect;
    }
    else
    {
        /* Use same chroma as input */
        p_vout->output.i_chroma = p_vout->render.i_chroma;
        p_vout->output.i_rmask  = p_vout->render.i_rmask;
        p_vout->output.i_gmask  = p_vout->render.i_gmask;
        p_vout->output.i_bmask  = p_vout->render.i_bmask;
        p_vout->output.i_width  = p_vout->render.i_width;
        p_vout->output.i_height = p_vout->render.i_height;
        p_vout->output.i_aspect = p_vout->render.i_aspect;
    }

    /* Try to initialize DUMMY_MAX_DIRECTBUFFERS direct buffers */
    while( I_OUTPUTPICTURES < DUMMY_MAX_DIRECTBUFFERS )
    {
        p_pic = NULL;

        /* Find an empty picture slot */
        for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
        {
            if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
            {
                p_pic = p_vout->p_picture + i_index;
                break;
            }
        }

        /* Allocate the picture */
        if( p_pic == NULL )
        {
            break;
        }

        vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma,
                              p_vout->output.i_width, p_vout->output.i_height,
                              p_vout->output.i_aspect );

        if( p_pic->i_planes == 0 )
        {
            break;
        }

        p_pic->i_status = DESTROYED_PICTURE;
        p_pic->i_type   = DIRECT_PICTURE;

        PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;

        I_OUTPUTPICTURES++;
    }

    return( 0 );
}