Example #1
0
/* Internal video allocator functions */
static picture_t *VideoBufferNew( filter_t *p_filter )
{
    const video_format_t *p_fmt = &p_filter->fmt_out.video;

    picture_t *p_picture = picture_New( p_fmt->i_chroma,
                                        p_fmt->i_width, p_fmt->i_height,
                                        p_fmt->i_aspect );
    if( !p_picture )
        msg_Err( p_filter, "Failed to allocate picture" );
    return p_picture;
}
Example #2
0
static picture_t *video_new_buffer( vlc_object_t *p_this,
                                    decoder_owner_sys_t *p_sys,
                                    es_format_t *fmt_out )
{
    if( fmt_out->video.i_width != p_sys->video.i_width ||
        fmt_out->video.i_height != p_sys->video.i_height ||
        fmt_out->video.i_chroma != p_sys->video.i_chroma ||
        fmt_out->video.i_aspect != p_sys->video.i_aspect )
    {
        if( !fmt_out->video.i_sar_num ||
            !fmt_out->video.i_sar_den )
        {
            fmt_out->video.i_sar_num =
                fmt_out->video.i_aspect * fmt_out->video.i_height;

            fmt_out->video.i_sar_den =
                VOUT_ASPECT_FACTOR * fmt_out->video.i_width;
        }

        vlc_ureduce( &fmt_out->video.i_sar_num,
                     &fmt_out->video.i_sar_den,
                     fmt_out->video.i_sar_num,
                     fmt_out->video.i_sar_den, 0 );

        if( !fmt_out->video.i_visible_width ||
            !fmt_out->video.i_visible_height )
        {
            fmt_out->video.i_visible_width = fmt_out->video.i_width;
            fmt_out->video.i_visible_height = fmt_out->video.i_height;
        }

        fmt_out->video.i_chroma = fmt_out->i_codec;
        p_sys->video = fmt_out->video;
    }

    /* */
    fmt_out->video.i_chroma = fmt_out->i_codec;

    return picture_New( fmt_out->video.i_chroma,
                        fmt_out->video.i_width,
                        fmt_out->video.i_height,
                        fmt_out->video.i_aspect );
}
/*****************************************************************************
 * Command functions
 *****************************************************************************/
static int exec_DataSharedMem( filter_t *p_filter,
                               const commandparams_t *p_params,
                               commandparams_t *p_results )
{
#if defined(HAVE_SYS_SHM_H)
    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
    struct shmid_ds shminfo;
    overlay_t *p_ovl;
    size_t i_size;

    VLC_UNUSED(p_results);

    p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
    if( p_ovl == NULL )
    {
        msg_Err( p_filter, "Invalid overlay: %d", p_params->i_id );
        return VLC_EGENERIC;
    }

    if( shmctl( p_params->i_shmid, IPC_STAT, &shminfo ) == -1 )
    {
        msg_Err( p_filter, "Unable to access shared memory" );
        return VLC_EGENERIC;
    }
    i_size = shminfo.shm_segsz;

    if( p_params->fourcc == VLC_CODEC_TEXT )
    {
        char *p_data;

        if( (p_params->i_height != 1) || (p_params->i_width < 1) )
        {
            msg_Err( p_filter,
                     "Invalid width and/or height. when specifying text height "
                     "must be 1 and width the number of bytes in the string, "
                     "including the null terminator" );
            return VLC_EGENERIC;
        }

        if( (size_t)p_params->i_width > i_size )
        {
            msg_Err( p_filter,
                     "Insufficient data in shared memory. need %d, got %zu",
                     p_params->i_width, i_size );
            return VLC_EGENERIC;
        }

        p_ovl->data.p_text = malloc( p_params->i_width );
        if( p_ovl->data.p_text == NULL )
        {
            msg_Err( p_filter, "Unable to allocate string storage" );
            return VLC_ENOMEM;
        }

        video_format_Setup( &p_ovl->format, VLC_CODEC_TEXT,
                            0, 0, 0, 1 );

        p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
        if( p_data == NULL )
        {
            msg_Err( p_filter, "Unable to attach to shared memory" );
            free( p_ovl->data.p_text );
            p_ovl->data.p_text = NULL;
            return VLC_ENOMEM;
        }
        memcpy( p_ovl->data.p_text, p_data, p_params->i_width );

        shmdt( p_data );
    }
    else
    {
        uint8_t *p_data, *p_in;
        size_t i_neededsize = 0;

        p_ovl->data.p_pic = picture_New( p_params->fourcc,
                                         p_params->i_width, p_params->i_height,
                                         1, 1 );
        if( p_ovl->data.p_pic == NULL )
            return VLC_ENOMEM;

        p_ovl->format = p_ovl->data.p_pic->format;

        for( size_t i_plane = 0; i_plane < (size_t)p_ovl->data.p_pic->i_planes;
             ++i_plane )
        {
            i_neededsize += p_ovl->data.p_pic->p[i_plane].i_visible_lines *
                            p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
        }

        if( i_neededsize > i_size )
        {
            msg_Err( p_filter,
                     "Insufficient data in shared memory. need %zu, got %zu",
                     i_neededsize, i_size );
            picture_Release( p_ovl->data.p_pic );
            p_ovl->data.p_pic = NULL;
            return VLC_EGENERIC;
        }

        p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
        if( p_data == NULL )
        {
            msg_Err( p_filter, "Unable to attach to shared memory" );
            picture_Release( p_ovl->data.p_pic );
            p_ovl->data.p_pic = NULL;
            return VLC_ENOMEM;
        }

        p_in = p_data;
        for( size_t i_plane = 0; i_plane < (size_t)p_ovl->data.p_pic->i_planes;
             ++i_plane )
        {
            uint8_t *p_out = p_ovl->data.p_pic->p[i_plane].p_pixels;
            for( size_t i_line = 0;
                 i_line < (size_t)p_ovl->data.p_pic->p[i_plane].i_visible_lines;
                 ++i_line )
            {
                memcpy( p_out, p_in,
                            p_ovl->data.p_pic->p[i_plane].i_visible_pitch );
                p_out += p_ovl->data.p_pic->p[i_plane].i_pitch;
                p_in += p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
            }
        }
        shmdt( p_data );
    }
    p_sys->b_updated = p_ovl->b_active;

    return VLC_SUCCESS;
#else
    VLC_UNUSED(p_params);
    VLC_UNUSED(p_results);

    msg_Err( p_filter, "system doesn't support shared memory" );
    return VLC_EGENERIC;
#endif
}
Example #4
0
File: swscale.c Project: Tilka/vlc
static int Init( filter_t *p_filter )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    const video_format_t *p_fmti = &p_filter->fmt_in.video;
    video_format_t       *p_fmto = &p_filter->fmt_out.video;

    if( IsFmtSimilar( p_fmti, &p_sys->fmt_in ) &&
        IsFmtSimilar( p_fmto, &p_sys->fmt_out ) &&
        p_sys->ctx )
    {
        return VLC_SUCCESS;
    }
    Clean( p_filter );

    /* Init with new parameters */
    ScalerConfiguration cfg;
    if( GetParameters( &cfg, p_fmti, p_fmto, p_sys->i_sws_flags ) )
    {
        msg_Err( p_filter, "format not supported" );
        return VLC_EGENERIC;
    }
    if( p_fmti->i_width <= 0 || p_fmto->i_width <= 0 )
    {
        msg_Err( p_filter, "0 width not supported" );
        return VLC_EGENERIC;
    }

    /* swscale does not like too small width */
    p_sys->i_extend_factor = 1;
    while( __MIN( p_fmti->i_width, p_fmto->i_width ) * p_sys->i_extend_factor < MINIMUM_WIDTH)
        p_sys->i_extend_factor++;

    const unsigned i_fmti_width = p_fmti->i_width * p_sys->i_extend_factor;
    const unsigned i_fmto_width = p_fmto->i_width * p_sys->i_extend_factor;
    for( int n = 0; n < (cfg.b_has_a ? 2 : 1); n++ )
    {
        const int i_fmti = n == 0 ? cfg.i_fmti : PIX_FMT_GRAY8;
        const int i_fmto = n == 0 ? cfg.i_fmto : PIX_FMT_GRAY8;
        struct SwsContext *ctx;

        ctx = sws_getContext( i_fmti_width, p_fmti->i_height, i_fmti,
                              i_fmto_width, p_fmto->i_height, i_fmto,
                              cfg.i_sws_flags | p_sys->i_cpu_mask,
                              p_sys->p_src_filter, p_sys->p_dst_filter, 0 );
        if( n == 0 )
            p_sys->ctx = ctx;
        else
            p_sys->ctxA = ctx;
    }
    if( p_sys->ctxA )
    {
        p_sys->p_src_a = picture_New( VLC_CODEC_GREY, i_fmti_width, p_fmti->i_height, 0, 1 );
        p_sys->p_dst_a = picture_New( VLC_CODEC_GREY, i_fmto_width, p_fmto->i_height, 0, 1 );
    }
    if( p_sys->i_extend_factor != 1 )
    {
        p_sys->p_src_e = picture_New( p_fmti->i_chroma, i_fmti_width, p_fmti->i_height, 0, 1 );
        p_sys->p_dst_e = picture_New( p_fmto->i_chroma, i_fmto_width, p_fmto->i_height, 0, 1 );

        if( p_sys->p_src_e )
            memset( p_sys->p_src_e->p[0].p_pixels, 0, p_sys->p_src_e->p[0].i_pitch * p_sys->p_src_e->p[0].i_lines );
        if( p_sys->p_dst_e )
            memset( p_sys->p_dst_e->p[0].p_pixels, 0, p_sys->p_dst_e->p[0].i_pitch * p_sys->p_dst_e->p[0].i_lines );
    }

    if( !p_sys->ctx ||
        ( cfg.b_has_a && ( !p_sys->ctxA || !p_sys->p_src_a || !p_sys->p_dst_a ) ) ||
        ( p_sys->i_extend_factor != 1 && ( !p_sys->p_src_e || !p_sys->p_dst_e ) ) )
    {
        msg_Err( p_filter, "could not init SwScaler and/or allocate memory" );
        Clean( p_filter );
        return VLC_EGENERIC;
    }

    p_sys->b_add_a = cfg.b_add_a;
    p_sys->b_copy = cfg.b_copy;
    p_sys->fmt_in  = *p_fmti;
    p_sys->fmt_out = *p_fmto;
    p_sys->b_swap_uvi = cfg.b_swap_uvi;
    p_sys->b_swap_uvo = cfg.b_swap_uvo;

    video_format_ScaleCropAr( p_fmto, p_fmti );
#if 0
    msg_Dbg( p_filter, "%ix%i chroma: %4.4s -> %ix%i chroma: %4.4s extend by %d",
             p_fmti->i_width, p_fmti->i_height, (char *)&p_fmti->i_chroma,
             p_fmto->i_width, p_fmto->i_height, (char *)&p_fmto->i_chroma,
             p_sys->i_extend_factor );
#endif
    return VLC_SUCCESS;
}
Example #5
0
/*****************************************************************************
 * LoadImage: creates and returns the bar graph image
 *****************************************************************************/
static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
{
    VLC_UNUSED(p_this);
    picture_t *p_pic;
    int i,j;
    int i_width = 0;
    int i_line;
    int moinsTrois, moinsCinq, moinsSept, moinsDix, moinsVingt;

    if (nbChannels == 0) {
        i_width = 20;
    } else {
        i_width = 2 * nbChannels * barWidth + 10;
    }

    moinsTrois = 0.71*scale + 20;
    moinsCinq = 0.56*scale + 20;
    moinsSept = 0.45*scale + 20;
    moinsDix = 0.32*scale + 20;
    moinsVingt = 0.1*scale + 20;

    p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, 1, 1);

    // blacken the whole picture
    for( i = 0 ; i < p_pic->i_planes ; i++ )
    {
        memset( p_pic->p[i].p_pixels, 0x00,
                p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
    }

    // side bar
    for ( i_line = 20; i_line < scale+20; i_line++ ) {

#define DrawPointsBlack(a,b) {\
        for (i=a; i<b; i++) {\
            *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0x00; \
            *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128; \
            *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128; \
            *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
        }\
    }
#define DrawPointsWhite(a,b) {\
        for (i=a; i<b; i++) {\
            *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = 0xFF;\
            *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = 128;\
            *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = 128;\
            *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = 0xFF; \
        }\
    }

        // vertical line
        DrawPointsBlack(20,22);
        DrawPointsWhite(22,24);

        // -3dB
        if (i_line == moinsTrois - 2) {
            // 3
            DrawPointsBlack(16,19);
        }
        if (i_line == moinsTrois - 1) {
            // 3
            DrawPointsBlack(18,19);
            // limit
            DrawPointsWhite(24,27);
        }
        if (i_line == moinsTrois) {
            // 3
            DrawPointsBlack(16,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsTrois + 1) {
            // 3
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsTrois + 2) {
            // 3
            DrawPointsBlack(16,19);
        }

        // -5dB
        if (i_line == moinsCinq - 2) {
            // 5
            DrawPointsBlack(16,19);
        }
        if (i_line == moinsCinq - 1) {
            // 5
            DrawPointsBlack(18,19);
            // limit
            DrawPointsWhite(24,27);
        }
        if (i_line == moinsCinq) {
            // 5
            DrawPointsBlack(16,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsCinq + 1) {
            // 5
            DrawPointsBlack(16,17);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsCinq + 2) {
            // 5
            DrawPointsBlack(16,19);
        }

        // -7dB
        if (i_line == moinsSept - 2) {
            // 7
            DrawPointsBlack(18,19);
        }
        if (i_line == moinsSept - 1) {
            // 7
            DrawPointsBlack(18,19);
            // limit
            DrawPointsWhite(24,27);
        }
        if (i_line == moinsSept) {
            // 7
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsSept + 1) {
            // 7
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsSept + 2) {
            // 7
            DrawPointsBlack(16,19);
        }


        // -10dB
        if (i_line == moinsDix - 2) {
            // 1
            DrawPointsBlack(14,15);
            // 0
            DrawPointsBlack(16,19);
        }
        if (i_line == moinsDix - 1) {
            // 1
            DrawPointsBlack(14,15);
            // 0
            DrawPointsBlack(16,17);
            DrawPointsBlack(18,19);
            // limit
            DrawPointsWhite(24,27);
        }
        if (i_line == moinsDix) {
            // 1
            DrawPointsBlack(14,15);
            // 0
            DrawPointsBlack(16,17);
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsDix + 1) {
            // 1
            DrawPointsBlack(14,15);
            // 0
            DrawPointsBlack(16,17);
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsDix + 2) {
            // 1
            DrawPointsBlack(14,15);
            // 0
            DrawPointsBlack(16,19);
        }

        // -20dB
        if (i_line == moinsVingt - 2) {
            // 2
            DrawPointsBlack(12,15);
            // 0
            DrawPointsBlack(16,19);
        }
        if (i_line == moinsVingt - 1) {
            // 2
            DrawPointsBlack(12,13);
            // 0
            DrawPointsBlack(16,17);
            DrawPointsBlack(18,19);
            // limit
            DrawPointsWhite(24,27);
        }
        if (i_line == moinsVingt) {
            // 2
            DrawPointsBlack(12,15);
            // 0
            DrawPointsBlack(16,17);
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsVingt + 1) {
            // 2
            DrawPointsBlack(14,15);
            // 0
            DrawPointsBlack(16,17);
            DrawPointsBlack(18,19);
            // limit
            DrawPointsBlack(24,27);
        }
        if (i_line == moinsVingt + 2) {
            // 2
            DrawPointsBlack(12,15);
            // 0
            DrawPointsBlack(16,19);
        }


    }

    // draw the bars and channel indicators
    for (i=0; i<nbChannels; i++) {
        for( j = barWidth+20 ; j < 2*barWidth+20; j++)
        {
            // channel indicators
            for ( i_line = 12; i_line < 18; i_line++ ) {
                // white
                *(p_pic->p[0].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[0].i_pitch +
                    ( (2*i*barWidth)+j ) ) = 255;
                *(p_pic->p[1].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[1].i_pitch +
                    ( (2*i*barWidth)+j ) ) = 128;
                *(p_pic->p[2].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[2].i_pitch +
                    ( (2*i*barWidth)+j ) ) = 128;
                *(p_pic->p[3].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[3].i_pitch +
                    ( (2*i*barWidth)+j )) = 0xFF;
            }
            // bars
            for( i_line = 20; i_line < i_values[i]+20; i_line++ )
            {
                if (i_line < moinsDix) { // green if < -10 dB
                    *(p_pic->p[0].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[0].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 150;
                    *(p_pic->p[1].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[1].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 44;
                    *(p_pic->p[2].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[2].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 21;
                    *(p_pic->p[3].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[3].i_pitch +
                        ( (2*i*barWidth)+j )) = 0xFF;
                } else if (i_line < moinsTrois) { // yellow if > -10dB and < -3dB
                    *(p_pic->p[0].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[0].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 226;
                    *(p_pic->p[1].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[1].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 1;
                    *(p_pic->p[2].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[2].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 148;
                    *(p_pic->p[3].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[3].i_pitch +
                        ( (2*i*barWidth)+j )) = 0xFF;
                } else { // red if > -3 dB
                    *(p_pic->p[0].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[0].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 76;
                    *(p_pic->p[1].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[1].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 85;
                    *(p_pic->p[2].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[2].i_pitch +
                        ( (2*i*barWidth)+j ) ) = 0xFF;
                    *(p_pic->p[3].p_pixels +
                        (scale + 30 - i_line - 1) *
                        p_pic->p[3].i_pitch +
                        ( (2*i*barWidth)+j )) = 0xFF;
                }
            }
        }
    }



    if (alarm) {// draw the alarm square
        // bottom
        for ( i_line = 0; i_line < 10; i_line++ ) {
            for (i=0; i<i_width+20; i++) {
                *(p_pic->p[0].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[0].i_pitch + i ) = 76;
                *(p_pic->p[1].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[1].i_pitch + i ) = 85;
                *(p_pic->p[2].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[2].i_pitch + i ) = 0xFF;
                *(p_pic->p[3].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[3].i_pitch + i ) = 0xFF;
            }
        }
        // top
        for ( i_line = scale+21; i_line < scale+30; i_line++ ) {
            for (i=0; i<i_width+20; i++) {
                *(p_pic->p[0].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[0].i_pitch + i ) = 76;
                *(p_pic->p[1].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[1].i_pitch + i ) = 85;
                *(p_pic->p[2].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[2].i_pitch + i ) = 0xFF;
                *(p_pic->p[3].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[3].i_pitch + i ) = 0xFF;
            }
        }
        // sides
        for ( i_line = 9; i_line < scale+21; i_line++ ) {
            for (i=0; i<10; i++) {
                *(p_pic->p[0].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[0].i_pitch + i ) = 76;
                *(p_pic->p[1].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[1].i_pitch + i ) = 85;
                *(p_pic->p[2].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[2].i_pitch + i ) = 0xFF;
                *(p_pic->p[3].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[3].i_pitch + i ) = 0xFF;
            }
            for (i=i_width+11; i<i_width+20; i++) {
                *(p_pic->p[0].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[0].i_pitch + i ) = 76;
                *(p_pic->p[1].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[1].i_pitch + i ) = 85;
                *(p_pic->p[2].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[2].i_pitch + i ) = 0xFF;
                *(p_pic->p[3].p_pixels +
                    (scale + 30 - i_line - 1) *
                    p_pic->p[3].i_pitch + i ) = 0xFF;
            }
        }
    }


    return p_pic;
}
Example #6
0
static void* vnc_worker_thread( void *obj )
{
    filter_t* p_filter = (filter_t*)obj;
    filter_sys_t *p_sys = p_filter->p_sys;
    vlc_thread_t update_thread;
    int canc = vlc_savecancel ();

    msg_Dbg( p_filter, "VNC worker thread started" );

    int fd = vnc_connect( p_filter );
    if( fd == -1 )
    {
        msg_Err( p_filter, "Error occurred while handshaking VNC host" );
        return NULL;
    }

    /* Create an empty picture for VNC the data */
    picture_t *pic =  picture_New( VLC_CODEC_YUVA, p_sys->i_vnc_width,
                                   p_sys->i_vnc_height, 1, 1 );
    if( likely(pic != NULL) )
    {
        vlc_mutex_lock( &p_sys->lock );
        p_sys->i_socket = fd;
        p_sys->p_pic = pic;
        vlc_mutex_unlock( &p_sys->lock );
    }
    else
    {
        net_Close( fd );
        return NULL;
    }

    write_update_request( p_filter, false );

    /* create the update request thread */
    bool polling = var_InheritBool( p_filter, RMTOSD_CFG "vnc-polling" );
    if( polling
     && vlc_clone( &update_thread, update_request_thread,
                   p_filter, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot spawn VNC update request thread" );
        polling = false;
    }

    vlc_cleanup_push( polling ? update_thread_cleanup : dummy_cleanup,
                      &update_thread );

    /* connection is initialized, now read and handle server messages */
    for( ;; )
    {
        rfbServerToClientMsg msg;
        int i_msgSize;

        memset( &msg, 0, sizeof(msg) );
        vlc_restorecancel (canc);

        if( !read_exact(p_filter, fd, &msg, 1 ) )
        {
            msg_Err( p_filter, "Error while waiting for next server message");
            break;
        }
        switch (msg.type)
        {
        case rfbFramebufferUpdate:
            i_msgSize = sz_rfbFramebufferUpdateMsg;
            break;
        case rfbSetColourMapEntries:
            i_msgSize = sz_rfbSetColourMapEntriesMsg;
            break;
        case rfbBell:
            i_msgSize = sz_rfbBellMsg;
            break;
        case rfbServerCutText:
            i_msgSize = sz_rfbServerCutTextMsg;
            break;
        case rfbReSizeFrameBuffer:
            i_msgSize = sz_rfbReSizeFrameBufferMsg;
            break;
        default:
            i_msgSize = 0;
            msg_Err( p_filter, "Invalid message %u received", msg.type );
            break;
        }

        if( i_msgSize <= 0 )
            break;

        if( --i_msgSize > 0 )
        {
            if ( !read_exact( p_filter, fd, ((char *)&msg) + 1, i_msgSize ) )
            {
                msg_Err( p_filter, "Error while reading message of type %u",
                         msg.type );
                break;
            }
        }

        canc = vlc_savecancel ();
        process_server_message( p_filter, &msg);
    }

    vlc_cleanup_pop();
    if( polling )
        update_thread_cleanup( &update_thread );

    msg_Dbg( p_filter, "VNC message reader thread ended" );
    vlc_restorecancel (canc);
    return NULL;
}
Example #7
0
static int Init( filter_t *p_filter )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    const video_format_t *p_fmti = &p_filter->fmt_in.video;
    video_format_t       *p_fmto = &p_filter->fmt_out.video;

    if( p_fmti->orientation != p_fmto->orientation )
        return VLC_EGENERIC;

    if( video_format_IsSimilar( p_fmti, &p_sys->fmt_in ) &&
        video_format_IsSimilar( p_fmto, &p_sys->fmt_out ) &&
        p_sys->ctx )
    {
        return VLC_SUCCESS;
    }

    Clean( p_filter );

    /* Init with new parameters */
    ScalerConfiguration cfg;
    if( GetParameters( &cfg, p_fmti, p_fmto, p_sys->i_sws_flags ) )
    {
        msg_Err( p_filter, "format not supported" );
        return VLC_EGENERIC;
    }
    if( p_fmti->i_visible_width <= 0 || p_fmti->i_visible_height <= 0 ||
        p_fmto->i_visible_width <= 0 || p_fmto->i_visible_height <= 0 )
    {
        msg_Err( p_filter, "invalid scaling: %ix%i -> %ix%i",
                 p_fmti->i_visible_width, p_fmti->i_visible_height,
                 p_fmto->i_visible_width, p_fmto->i_visible_height);
        return VLC_EGENERIC;
    }

    p_sys->desc_in = vlc_fourcc_GetChromaDescription( p_fmti->i_chroma );
    p_sys->desc_out = vlc_fourcc_GetChromaDescription( p_fmto->i_chroma );
    if( p_sys->desc_in == NULL || p_sys->desc_out == NULL )
        return VLC_EGENERIC;

    /* swscale does not like too small width */
    p_sys->i_extend_factor = 1;
    while( __MIN( p_fmti->i_visible_width, p_fmto->i_visible_width ) * p_sys->i_extend_factor < MINIMUM_WIDTH)
        p_sys->i_extend_factor++;

    const unsigned i_fmti_visible_width = p_fmti->i_visible_width * p_sys->i_extend_factor;
    const unsigned i_fmto_visible_width = p_fmto->i_visible_width * p_sys->i_extend_factor;
    for( int n = 0; n < (cfg.b_has_a ? 2 : 1); n++ )
    {
        const int i_fmti = n == 0 ? cfg.i_fmti : PIX_FMT_GRAY8;
        const int i_fmto = n == 0 ? cfg.i_fmto : PIX_FMT_GRAY8;
        struct SwsContext *ctx;

        ctx = sws_getContext( i_fmti_visible_width, p_fmti->i_visible_height, i_fmti,
                              i_fmto_visible_width, p_fmto->i_visible_height, i_fmto,
                              cfg.i_sws_flags | p_sys->i_cpu_mask,
                              p_sys->p_src_filter, p_sys->p_dst_filter, 0 );
        if( n == 0 )
            p_sys->ctx = ctx;
        else
            p_sys->ctxA = ctx;
    }
    if( p_sys->ctxA )
    {
        p_sys->p_src_a = picture_New( VLC_CODEC_GREY, i_fmti_visible_width, p_fmti->i_visible_height, 0, 1 );
        p_sys->p_dst_a = picture_New( VLC_CODEC_GREY, i_fmto_visible_width, p_fmto->i_visible_height, 0, 1 );
    }
    if( p_sys->i_extend_factor != 1 )
    {
        p_sys->p_src_e = picture_New( p_fmti->i_chroma, i_fmti_visible_width, p_fmti->i_visible_height, 0, 1 );
        p_sys->p_dst_e = picture_New( p_fmto->i_chroma, i_fmto_visible_width, p_fmto->i_visible_height, 0, 1 );

        if( p_sys->p_src_e )
            memset( p_sys->p_src_e->p[0].p_pixels, 0, p_sys->p_src_e->p[0].i_pitch * p_sys->p_src_e->p[0].i_lines );
        if( p_sys->p_dst_e )
            memset( p_sys->p_dst_e->p[0].p_pixels, 0, p_sys->p_dst_e->p[0].i_pitch * p_sys->p_dst_e->p[0].i_lines );
    }

    if( !p_sys->ctx ||
        ( cfg.b_has_a && ( !p_sys->ctxA || !p_sys->p_src_a || !p_sys->p_dst_a ) ) ||
        ( p_sys->i_extend_factor != 1 && ( !p_sys->p_src_e || !p_sys->p_dst_e ) ) )
    {
        msg_Err( p_filter, "could not init SwScaler and/or allocate memory" );
        Clean( p_filter );
        return VLC_EGENERIC;
    }

    if (p_filter->b_allow_fmt_out_change)
    {
        /*
         * If the transformation is not homothetic we must modify the
         * aspect ratio of the output format in order to have the
         * output picture displayed correctly and not stretched
         * horizontally or vertically.
         * WARNING: this is a hack, ideally this should not be needed
         * and the vout should update its video format instead.
         */
        unsigned i_sar_num = p_fmti->i_sar_num * p_fmti->i_visible_width;
        unsigned i_sar_den = p_fmti->i_sar_den * p_fmto->i_visible_width;
        vlc_ureduce(&i_sar_num, &i_sar_den, i_sar_num, i_sar_den, 65536);
        i_sar_num *= p_fmto->i_visible_height;
        i_sar_den *= p_fmti->i_visible_height;
        vlc_ureduce(&i_sar_num, &i_sar_den, i_sar_num, i_sar_den, 65536);
        p_fmto->i_sar_num = i_sar_num;
        p_fmto->i_sar_den = i_sar_den;
    }

    p_sys->b_add_a = cfg.b_add_a;
    p_sys->b_copy = cfg.b_copy;
    p_sys->fmt_in  = *p_fmti;
    p_sys->fmt_out = *p_fmto;
    p_sys->b_swap_uvi = cfg.b_swap_uvi;
    p_sys->b_swap_uvo = cfg.b_swap_uvo;

#if 0
    msg_Dbg( p_filter, "%ix%i (%ix%i) chroma: %4.4s -> %ix%i (%ix%i) chroma: %4.4s extend by %d",
             p_fmti->i_visible_width, p_fmti->i_visible_height, p_fmti->i_width, p_fmti->i_height, (char *)&p_fmti->i_chroma,
             p_fmto->i_visible_width, p_fmto->i_visible_height, p_fmto->i_width, p_fmto->i_height, (char *)&p_fmto->i_chroma,
             p_sys->i_extend_factor );
#endif
    return VLC_SUCCESS;
}
static void* vnc_worker_thread( void *obj )
{
    filter_t* p_filter = (filter_t*)obj;
    filter_sys_t *p_sys = p_filter->p_sys;
    vlc_thread_t update_request_thread_handle;
    int canc = vlc_savecancel ();

    msg_Dbg( p_filter, "VNC worker thread started" );

    if( !open_vnc_connection ( p_filter ) )
    {
        msg_Err( p_filter, "Could not connect to vnc host" );
        goto exit;
    }

    if( !handshaking ( p_filter ) )
    {
        msg_Err( p_filter, "Error occured while handshaking vnc host" );
        goto exit;
    }

    p_sys->b_connection_active = true; /* to enable sending key
                                            * and mouse events to host */

    /* Create an empty picture for VNC the data */
    vlc_mutex_lock( &p_sys->lock );
    p_sys->p_pic = picture_New( VLC_CODEC_YUVA,
                                p_sys->i_vnc_width, p_sys->i_vnc_height, 1, 1 );
    if( !p_sys->p_pic )
    {
        vlc_mutex_unlock( &p_sys->lock );
        goto exit;
    }
	p_sys->i_vnc_pixels = p_sys->i_vnc_width * p_sys->i_vnc_height;

    vlc_mutex_unlock( &p_sys->lock );

    /* create the update request thread */
    if( vlc_clone( &update_request_thread_handle,
                   update_request_thread, p_filter,
                   VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot spawn vnc update request thread" );
        goto exit;
    }

    /* connection is initialized, now read and handle server messages */
    vlc_restorecancel (canc);
    for( ;; )
    {
        rfbServerToClientMsg msg;
        int i_msgSize;

        memset( &msg, 0, sizeof(msg) );

        if( !read_exact(p_filter, p_sys->i_socket, (char*)&msg, 1 ) )
        {
            msg_Err( p_filter, "Error while waiting for next server message");
            break;
        }
        switch (msg.type)
        {
        case rfbFramebufferUpdate:
            i_msgSize = sz_rfbFramebufferUpdateMsg;
            break;
        case rfbSetColourMapEntries:
            i_msgSize = sz_rfbSetColourMapEntriesMsg;
            break;
        case rfbBell:
            i_msgSize = sz_rfbBellMsg;
            break;
        case rfbServerCutText:
            i_msgSize = sz_rfbServerCutTextMsg;
            break;
        case rfbReSizeFrameBuffer:
            i_msgSize = sz_rfbReSizeFrameBufferMsg;
            break;
        default:
            i_msgSize = 0;
            msg_Err( p_filter, "Invalid message %u received", msg.type );
            break;
        }

        if( i_msgSize <= 0 )
            break;

        if( --i_msgSize > 0 )
        {
            if ( !read_exact( p_filter, p_sys->i_socket,
                              ((char*)&msg)+1, i_msgSize ) )
            {
                msg_Err( p_filter, "Error while reading message of type %u",
                         msg.type );
                break;
            }
        }

        canc = vlc_savecancel ();
        process_server_message( p_filter, &msg);
        vlc_restorecancel (canc);
    }
    canc = vlc_savecancel ();

    msg_Dbg( p_filter, "joining update_request_thread" );
    vlc_cancel( update_request_thread_handle );
    vlc_join( update_request_thread_handle, NULL );
    msg_Dbg( p_filter, "released update_request_thread" );

exit:

    vlc_mutex_lock( &p_sys->lock );
    p_sys->b_connection_active = false;

    if (p_sys->i_socket >= 0)
        net_Close(p_sys->i_socket);

    if( p_sys->p_pic )
        picture_Release( p_sys->p_pic );

    /* It will hide the subtitle */
    p_sys->b_continue = false;
    p_sys->b_need_update = true;
    vlc_mutex_unlock( &p_sys->lock );

    msg_Dbg( p_filter, "VNC message reader thread ended" );
    vlc_restorecancel (canc);
    return NULL;
}
Example #9
0
/*****************************************************************************
 * Draw: creates and returns the bar graph image
 *****************************************************************************/
static void Draw(BarGraph_t *b)
{
    int nbChannels = b->nbChannels;
    int scale      = b->scale;
    int barWidth   = b->barWidth;

    int w = 40;
    if (nbChannels > 0)
        w = 2 * nbChannels * barWidth + 30;
    int h = scale + 30;

    int level[6];
    for (int i = 0; i < 6; i++)
        level[i] = iec_scale(-(i+1) * 10) * scale + 20;

    if (b->p_pic)
        picture_Release(b->p_pic);
    b->p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), w, h, 1, 1);
    if (!b->p_pic)
        return;
    picture_t *p_pic = b->p_pic;
    plane_t *p = p_pic->p;

    for (int i = 0 ; i < p_pic->i_planes ; i++)
        memset(p[i].p_pixels, 0x00, p[i].i_visible_lines * p[i].i_pitch);

    Draw2VLines(p, scale, 20, black);
    Draw2VLines(p, scale, 22, white);

    static const uint8_t pixmap[6][5] = {
        { 0x17, 0x15, 0x15, 0x15, 0x17 },
        { 0x77, 0x45, 0x75, 0x15, 0x77 },
        { 0x77, 0x15, 0x75, 0x15, 0x77 },
        { 0x17, 0x15, 0x75, 0x55, 0x57 },
        { 0x77, 0x15, 0x75, 0x45, 0x77 },
        { 0x77, 0x55, 0x75, 0x45, 0x77 },
    };

    for (int i = 0; i < 6; i++) {
        DrawHLines(p, h - 1 - level[i] - 1, 24, white, 1, 3);
        DrawHLines(p, h - 1 - level[i],     24, black, 2, 3);
        DrawNumber(p, h, pixmap[i], level[i]);
    }

    int minus8  = iec_scale(- 8) * scale + 20;
    int minus18 = iec_scale(-18) * scale + 20;
    int *i_values  = b->i_values;
    const uint8_t *indicator_color = b->alarm ? bright_red : black;

    for (int i = 0; i < nbChannels; i++) {
        int pi = 30 + i * (5 + barWidth);

        DrawHLines(p, h - 20 - 1, pi, indicator_color, 8, barWidth);

        for (int line = 20; line < i_values[i] + 20; line++) {
            if (line < minus18)
                DrawHLines(p, h - line - 1, pi, bright_green, 1, barWidth);
            else if (line < minus8)
                DrawHLines(p, h - line - 1, pi, bright_yellow, 1, barWidth);
            else
                DrawHLines(p, h - line - 1, pi, bright_red, 1, barWidth);
        }

        for (int line = i_values[i] + 20; line < scale + 20; line++) {
            if (line < minus18)
                DrawHLines(p, h - line - 1, pi, green, 1, barWidth);
            else if (line < minus8)
                DrawHLines(p, h - line - 1, pi, yellow, 1, barWidth);
            else
                DrawHLines(p, h - line - 1, pi, red, 1, barWidth);
        }
    }
}
Example #10
0
static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
                 block_t *p_buffer )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;
    picture_t *p_pic;

    if ( (sout_stream_sys_t *)id != p_sys )
    {
        block_ChainRelease( p_buffer );
        return VLC_SUCCESS;
    }

    while ( (p_pic = p_sys->p_decoder->pf_decode_video( p_sys->p_decoder,
                                                        &p_buffer )) )
    {
        picture_t *p_new_pic;

        if( p_sys->i_height || p_sys->i_width )
        {
            video_format_t fmt_out, fmt_in;

            memset( &fmt_in, 0, sizeof(video_format_t) );
            memset( &fmt_out, 0, sizeof(video_format_t) );
            fmt_in = p_sys->p_decoder->fmt_out.video;


            if( p_sys->i_chroma )
                fmt_out.i_chroma = p_sys->i_chroma;
            else
                fmt_out.i_chroma = VLC_CODEC_I420;

            const unsigned i_fmt_in_aspect =
                (int64_t)VOUT_ASPECT_FACTOR *
                fmt_in.i_sar_num * fmt_in.i_width /
                (fmt_in.i_sar_den * fmt_in.i_height);
            if ( !p_sys->i_height )
            {
                fmt_out.i_width = p_sys->i_width;
                fmt_out.i_height = (p_sys->i_width * VOUT_ASPECT_FACTOR
                    * p_sys->i_sar_num / p_sys->i_sar_den / i_fmt_in_aspect)
                      & ~0x1;
            }
            else if ( !p_sys->i_width )
            {
                fmt_out.i_height = p_sys->i_height;
                fmt_out.i_width = (p_sys->i_height * i_fmt_in_aspect
                    * p_sys->i_sar_den / p_sys->i_sar_num / VOUT_ASPECT_FACTOR)
                      & ~0x1;
            }
            else
            {
                fmt_out.i_width = p_sys->i_width;
                fmt_out.i_height = p_sys->i_height;
            }
            fmt_out.i_visible_width = fmt_out.i_width;
            fmt_out.i_visible_height = fmt_out.i_height;

            p_new_pic = image_Convert( p_sys->p_image,
                                       p_pic, &fmt_in, &fmt_out );
            if( p_new_pic == NULL )
            {
                msg_Err( p_stream, "image conversion failed" );
                picture_Release( p_pic );
                continue;
            }
        }
        else
        {
            /* TODO: chroma conversion if needed */

            p_new_pic = picture_New( p_pic->format.i_chroma,
                                     p_pic->format.i_width, p_pic->format.i_height,
                                     p_sys->p_decoder->fmt_out.video.i_sar_num,
                                     p_sys->p_decoder->fmt_out.video.i_sar_den );
            if( !p_new_pic )
            {
                picture_Release( p_pic );
                msg_Err( p_stream, "image allocation failed" );
                continue;
            }

            picture_Copy( p_new_pic, p_pic );
        }
        picture_Release( p_pic );

        if( p_sys->p_vf2 )
            p_new_pic = filter_chain_VideoFilter( p_sys->p_vf2, p_new_pic );

        PushPicture( p_stream, p_new_pic );
    }

    return VLC_SUCCESS;
}
/*****************************************************************************
 * LoadImage: creates and returns the bar graph image
 *****************************************************************************/
static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth)
{
    VLC_UNUSED(p_this);
    picture_t *p_pic;
    int i, j, pi;
    int i_width = 0;
    int i_line;
    int minus8, minus10, minus18, minus20, minus30, minus40, minus50, minus60;

    if (nbChannels == 0) {
        i_width = 20;
    } else {
        i_width = 2 * nbChannels * barWidth + 10;
    }
    minus8  = iec_scale(-8)*scale + 20;
    minus10 = iec_scale(-10)*scale + 20;
    minus18 = iec_scale(-18)*scale + 20;
    minus20 = iec_scale(-20)*scale + 20;
    minus30 = iec_scale(-30)*scale + 20;
    minus40 = iec_scale(-40)*scale + 20;
    minus50 = iec_scale(-50)*scale + 20;
    minus60 = iec_scale(-60)*scale + 20;

    p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, 1, 1);


#define DrawLine(a,b,Y,U,V,A) \
        for (i=a; i<b; i++) {\
            *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = Y;\
            *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = U;\
            *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = V;\
            *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = A; \
        }
#define DrawLineBlack(a,b) DrawLine(a,b,0,128,128,0xFF)
#define DrawLineWhite(a,b) DrawLine(a,b,255,128,128,0xFF)

    // blacken the whole picture
    for( i = 0 ; i < p_pic->i_planes ; i++ )
    {
        memset( p_pic->p[i].p_pixels, 0x00,
                p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch );
    }


    // side bar
    for ( i_line = 20; i_line < scale+20; i_line++ ) {
        // vertical line
        DrawLineBlack(20,22);
        DrawLineWhite(22,24);

        // -10dB
        if (i_line == minus10 - 2) {
            // 1
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,19);
        }
        if (i_line == minus10 - 1) {
            // 1
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineWhite(24,27); //White
        }
        if (i_line == minus10) {
            // 1
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus10 + 1) {
            // 1
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus10 + 2) {
            // 1
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,19);
        }

        // -20dB
        if (i_line == minus20 - 2) {
            // 2
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }
        if (i_line == minus20 - 1) {
            // 2
            DrawLineBlack(12,13);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineWhite(24,27); //White
        }
        if (i_line == minus20) {
            // 2
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus20 + 1) {
            // 2
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus20 + 2) {
            // 2
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }

        // -30dB
        if (i_line == minus30 - 2) {
            // 3
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }
        if (i_line == minus30 - 1) {
            // 3
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineWhite(24,27); //White
        }
        if (i_line == minus30) {
            // 3
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus30 + 1) {
            // 3
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus30 + 2) {
            // 3
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }

        // -40dB
        if (i_line == minus40 - 2) {
            // 4
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,19);
        }
        if (i_line == minus40 - 1) {
            // 4
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineWhite(24,27); // white
        }
        if (i_line == minus40) {
            // 4
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus40 + 1) {
            // 4
            DrawLineBlack(12,13);
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus40 + 2) {
            // 4
            DrawLineBlack(12,13);
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,19);
        }

        // -50dB
        if (i_line == minus50 - 2) {
            // 5
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }
        if (i_line == minus50 - 1) {
            // 5
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineWhite(24,27); //White
        }
        if (i_line == minus50) {
            // 5
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus50 + 1) {
            // 5
            DrawLineBlack(12,13);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus50 + 2) {
            // 2
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }
        // -60dB
        if (i_line == minus60 - 2) {
            // 6
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }
        if (i_line == minus60 - 1) {
            // 6
            DrawLineBlack(12,13);
            DrawLineBlack(14,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineWhite(24,27); //White
        }
        if (i_line == minus60) {
            // 6
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus60 + 1) {
            // 6
            DrawLineBlack(12,13);
            // 0
            DrawLineBlack(16,17);
            DrawLineBlack(18,19);
            // limit
            DrawLineBlack(24,27);
        }
        if (i_line == minus60 + 2) {
            // 6
            DrawLineBlack(12,15);
            // 0
            DrawLineBlack(16,19);
        }
    }

#define drawPoint(offset,y,u,v,a)  \
                *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + offset ) = y; \
                *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + offset ) = u; \
                *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + offset ) = v; \
                *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + offset ) = a;


    // draw the bars and channel indicators
    for (i=0; i<nbChannels; i++) {
        pi =  25 + ((i+1)*5) + (i*barWidth) ;  // 25 separació amb indicador, 5 separació entre barres

        for( j = pi; j < pi + barWidth; j++)
        {
            // channel indicators
            for ( i_line = 12; i_line < 20; i_line++ ) {
                if( alarm ) {
                    drawPoint(j,76,85,0xFF,0xFF);  // red
                }
                else {
                    drawPoint(j,0,128,128,0xFF); // black             DrawLine(pi,pf,0xFF,128,128,0xFF);
                }
            }

            // bars
            for( i_line = 20; i_line < i_values[i]+20; i_line++ )
            {
                if (i_line < minus18) { // green if < -18 dB
                    drawPoint(j,150,44,21,0xFF);
                    //DrawLine(pi,pf,150,44,21,0xFF);
                } else if (i_line < minus8) { // yellow if > -18dB and < -8dB
                    drawPoint(j,226,1,148,0xFF);
                    //DrawLine(pi,pf,226,1,148,0xFF);
                } else { // red if > -8 dB
                    drawPoint(j,76,85,0xFF,0xFF);
                    //DrawLine(pi,pf,76,85,255,0xFF);
                }
            }
            // bars no signal
            for( ; i_line < scale+20; i_line++ )
            {
                if (i_line < minus18) { // green if < -18 dB
                    drawPoint(j,74,85,74,0xFF);
                    //DrawLine(pi,pf,74,85,74,0xFF);
                } else if (i_line < minus8) { // yellow if > -18dB and < -8dB
                    drawPoint(j,112,64,138,0xFF);
                    //DrawLine(pi,pf,112,64,138,0xFF);
                } else { // red if > -8 dB
                    drawPoint(j,37,106,191,0xFF);
                    //DrawLine(pi,pf,37,106,191,0xFF);
                }
            }
        }
    }

    return p_pic;
}