Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  video_widgets.c   Sprache: C

 

/*****************************************************************************
 * video_widgets.c : OSD widgets manipulation functions
 *****************************************************************************
 * Copyright (C) 2004-2010 VLC authors and VideoLAN
 *
 * Author: Yoann Peronneau <yoann@videolan.org>
 *         Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


/*****************************************************************************
 * Preamble
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>

#include <vlc_common.h>
#include <vlc_vout.h>
#include <vlc_vout_osd.h>

#include <vlc_filter.h>

#include "vout_spuregion_helper.h"

#define STYLE_EMPTY 0
#define STYLE_FILLED 1

#define RGB_BLUE        0x2badde
#define RGB_ORANGE      0xf48b00
#define RGB_FILL        RGB_ORANGE

#define COL_TRANSPARENT 0
#define COL_WHITE       1
#define COL_FILL        2
#define COL_FILL_SHADE  3

#define SET_PALETTE_COLOR(id, rgb, alpha) \
{\
    uint8_t color[4] = { HEX2YUV(rgb), alpha };\
    memcpy( &palette.palette[id], &color, 4 );\
}

/**
 * Draws a rectangle at the given position in the region.
 * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY).
 */

static void DrawRect(subpicture_region_t *r, int fill, uint8_t color,
                     int x1, int y1, int x2, int y2)
{
    uint8_t *p    = r->p_picture->p->p_pixels;
    int     pitch = r->p_picture->p->i_pitch;
    if( x1 > x2 || y1 > y2 )
        return;

    if (fill == STYLE_FILLED) {
        if(x1 == 0 && x2 + 1 == r->p_picture->p->i_visible_pitch) {
            memset(&p[pitch * y1], color, pitch * (y2 - y1 + 1));
        } else {
            for (int y = y1; y <= y2; y++)
                memset(&p[x1 + pitch * y], color, x2 - x1 + 1);
        }
    } else {
        DrawRect(r, STYLE_FILLED, color, x1, y1, x1, y2);
        DrawRect(r, STYLE_FILLED, color, x2, y1, x2, y2);
        DrawRect(r, STYLE_FILLED, color, x1, y1, x2, y1);
        DrawRect(r, STYLE_FILLED, color, x1, y2, x2, y2);
    }
}

/**
 * Draws a triangle at the given position in the region.
 * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY).
 */

static void DrawTriangle(subpicture_region_t *r, int fill, uint8_t color,
                         int x1, int y1, int x2, int y2)
{
    uint8_t *p    = r->p_picture->p->p_pixels;
    int     pitch = r->p_picture->p->i_pitch;
    const int mid = y1 + (y2 - y1) / 2;
    const bool b_swap = (x1 > x2);

    for (int y = y1; y <= mid; y++) {
        const int h = y - y1;
        if (fill == STYLE_FILLED) {
            const int w = b_swap ? __MAX(x1 - h, x2) : __MIN(x1 + h, x2);
            DrawRect(r, STYLE_FILLED, color,
                     (b_swap) ? w : x1, y, (b_swap) ? x1 : w, y);
            DrawRect(r, STYLE_FILLED, color,
                     (b_swap) ? w : x1, y2 - h, (b_swap) ? x1 : w, y2 - h);
        } else {
            p[x1 +                     pitch * y       ] = color;
            p[x1 + (b_swap ? -h : h) + pitch * y       ] = color;
            p[x1 +                     pitch * (y2 - h)] = color;
            p[x1 + (b_swap ? -h : h) + pitch * (y2 - h)] = color;
        }
    }
}

/**
 * Create a region with a white transparent picture.
 */

static subpicture_region_t *OSDRegion(int x, int y, int width, int height)
{
    if( unlikely( width == 0 || height == 0 ) )
        return NULL;

    video_palette_t palette;
    SET_PALETTE_COLOR(COL_WHITE,       0xffffff, STYLE_ALPHA_OPAQUE)
    SET_PALETTE_COLOR(COL_TRANSPARENT, 0xffffff, STYLE_ALPHA_TRANSPARENT)
    SET_PALETTE_COLOR(COL_FILL,        RGB_FILL, 0xA0)
    SET_PALETTE_COLOR(COL_FILL_SHADE,  RGB_FILL, 0x25)
    palette.i_entries = 4;

    video_format_t fmt;
    video_format_Init(&fmt, VLC_CODEC_YUVP);
    fmt.i_width          =
    fmt.i_visible_width  = width;
    fmt.i_height         =
    fmt.i_visible_height = height;
    fmt.i_sar_num        = 1;
    fmt.i_sar_den        = 1;
    fmt.p_palette        = &palette;

    subpicture_region_t *r = subpicture_region_New(&fmt);
    if (!r)
        return NULL;
    r->i_x = x;
    r->i_y = y;

    return r;
}

/**
 * Create the region for an OSD slider.
 * Types are: OSD_HOR_SLIDER and OSD_VERT_SLIDER.
 */

#define SLIDER_MARGIN_BASE 0.10
static subpicture_region_t *OSDSlider(vlc_osd_widget_type type, int position,
                                      const unsigned i_visible_width,
                                      const unsigned i_visible_height)
{
    const unsigned size = __MAX(i_visible_width, i_visible_height);
    const unsigned margin = size * SLIDER_MARGIN_BASE;
    const unsigned marginbottom = margin * 0.2;
    const unsigned marginright = margin * 0.5;
    unsigned i_padding = __MIN(1, size * 0.25); /* small sizes */

    unsigned x, y;
    unsigned width, height;
    if (type == OSD_HOR_SLIDER) {
        width  = __MAX(i_visible_width - 2 * margin, 1);
        height = __MAX(i_visible_height * 0.01,      1);
        x      = __MIN(margin, i_visible_width - width);
        y      = __MAX(i_visible_height - marginbottom, 0);
    } else {
        width  = __MAX(i_visible_width * 0.010,       1);
        height = __MAX(i_visible_height - 2 * margin, 1);
        x      = __MAX(i_visible_width - marginright, 0);
        y      = __MIN(margin, i_visible_height - height);
    }

    if( (width < 1 + 2 * i_padding) || (height < 1 + 2 * i_padding) )
        return NULL;

    subpicture_region_t *r = OSDRegion(x, y, width, height);
    if( !r)
        return NULL;

    int pos_x = i_padding;
    int pos_y, pos_xend;
    int pos_yend = height - 1 - i_padding;

    if (type == OSD_HOR_SLIDER ) {
        pos_y = i_padding;
        pos_xend = pos_x + (width - 2 * i_padding) * position / 100;
    } else {
        pos_y = height - (height - 2 * i_padding) * position / 100;
        pos_xend = width - 1 - i_padding;
    }

    /* one full fill is faster than drawing outline */
    DrawRect(r, STYLE_FILLED, COL_FILL_SHADE, 0, 0, width - 1, height - 1);
    DrawRect(r, STYLE_FILLED, COL_FILL, pos_x, pos_y, pos_xend, pos_yend);

    return r;
}

/**
 * Create the region for an OSD slider.
 * Types are: OSD_PLAY_ICON, OSD_PAUSE_ICON, OSD_SPEAKER_ICON, OSD_MUTE_ICON
 */

static subpicture_region_t *OSDIcon(vlc_osd_widget_type type,
                                    const unsigned i_visible_width,
                                    const unsigned i_visible_height)
{
    const unsigned int size_ratio = 20;
    const unsigned int margin_ratio = 14;

    const unsigned int size   = __MAX(i_visible_width, i_visible_height);
    if( size < size_ratio )
        return NULL;

    const unsigned int width  = size / size_ratio;
    const unsigned int height = width;
    const unsigned int margin = size / margin_ratio;
    const int x      = i_visible_width - margin - width;
    const int y      =                   margin;

    subpicture_region_t *r = OSDRegion(__MAX(x, 0),
                                       __MIN(y, (int)i_visible_height - (int)height),
                                       width, height);
    if (!r)
        return NULL;

    DrawRect(r, STYLE_FILLED, COL_TRANSPARENT, 0, 0, width - 1, height - 1);

    if (type == OSD_PAUSE_ICON) {
        int bar_width = width / 3;
        DrawRect(r, STYLE_FILLED, COL_WHITE, 0, 0, bar_width - 1, height -1);
        DrawRect(r, STYLE_FILLED, COL_WHITE, width - bar_width, 0, width - 1, height - 1);
    } else if (type == OSD_PLAY_ICON) {
        int mid   = height >> 1;
        int delta = (width - mid) >> 1;
        int y2    = ((height - 1) >> 1) * 2;
        DrawTriangle(r, STYLE_FILLED, COL_WHITE, delta, 0, width - delta, y2);
    } else {
        int mid   = height >> 1;
        int delta = (width - mid) >> 1;
        int y2    = ((height - 1) >> 1) * 2;
        DrawRect(r, STYLE_FILLED, COL_WHITE, delta, mid / 2, width - delta, height - 1 - mid / 2);
        DrawTriangle(r, STYLE_FILLED, COL_WHITE, width - delta, 0, delta, y2);
        if (type == OSD_MUTE_ICON) {
            for(unsigned y1 = 0; y1 < height; y1++)
                DrawRect(r, STYLE_FILLED, COL_FILL, y1, y1, __MIN(y1 + delta, width - 1), y1);
        }
    }
    return r;
}

typedef struct {
    vlc_osd_widget_type type;
    int value;
} osdwidget_spu_updater_sys_t;

static void OSDWidgetUpdate(subpicture_t *subpic,
                            const struct vlc_spu_updater_configuration *cfg)
{
    osdwidget_spu_updater_sys_t *sys = subpic->updater.sys;
    subpicture_region_t *p_region;

    vlc_spu_regions_Clear( &subpic->regions );

    subpic->i_original_picture_width  = cfg->current.display_width;
    subpic->i_original_picture_height = cfg->current.display_height;
    if (sys->type == OSD_HOR_SLIDER || sys->type == OSD_VERT_SLIDER)
        p_region = OSDSlider(sys->type, sys->value, cfg->current.display_width, cfg->current.display_height);
    else
        p_region = OSDIcon(sys->type, cfg->current.display_width, cfg->current.display_height);
    if (p_region)
    {
        p_region->b_absolute = true;
        p_region->b_in_window = true;
        vlc_spu_regions_push(&subpic->regions, p_region);
    }
}

static void OSDWidgetDestroy(subpicture_t *subpic)
{
    free(subpic->updater.sys);
}

static void OSDWidget(vout_thread_t *vout, int channel, vlc_osd_widget_type type, int position)
{
    if (!var_InheritBool(vout, "osd"))
        return;
    if (type == OSD_HOR_SLIDER || type == OSD_VERT_SLIDER)
        position = VLC_CLIP(position, 0, 100);

    osdwidget_spu_updater_sys_t *sys = malloc(sizeof(*sys));
    if (!sys)
        return;
    sys->type     = type;
    sys->value    = position;

    static const struct vlc_spu_updater_ops spu_ops =
    {
        .update   = OSDWidgetUpdate,
        .destroy  = OSDWidgetDestroy,
    };

    subpicture_updater_t updater = {
        .sys = sys,
        .ops = &spu_ops,
    };
    subpicture_t *subpic = subpicture_New(&updater);
    if (!subpic) {
        free(sys);
        return;
    }

    subpic->i_channel  = channel;
    subpic->i_start    = vlc_tick_now();
    subpic->i_stop     = subpic->i_start + VLC_TICK_FROM_MS(1200);
    subpic->b_ephemer  = true;
    subpic->b_fade     = true;

    vout_PutSubpicture(vout, subpic);
}

void vout_OSDSlider(vout_thread_t *vout, int channel, int position, vlc_osd_widget_type type)
{
    OSDWidget(vout, channel, type, position);
}

void vout_OSDIcon(vout_thread_t *vout, int channel, vlc_osd_widget_type type )
{
    OSDWidget(vout, channel, type, 0);
}

Messung
CHZG
839610093

¤ Dauer der Verarbeitung: 0.12 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104848
#Domains=416968