⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_output.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * video_output.c : video output thread * * This module describes the programming interface for video output threads. * It includes functions allowing to open a new thread, send pictures to a * thread, and destroy a previously oppened video output thread. ***************************************************************************** * Copyright (C) 2000-2007 the VideoLAN team * $Id: f54ec25fa1e35cadff4904450529563cdd6eed99 $ * * Authors: Vincent Seguin <seguin@via.ecp.fr> *          Gildas Bazin <gbazin@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU 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 <vlc_common.h>#include <stdlib.h>                                                /* free() */#include <string.h>#ifdef HAVE_SYS_TIMES_H#   include <sys/times.h>#endif#include <vlc_vout.h>#include <vlc_filter.h>#include <vlc_osd.h>#if defined( __APPLE__ )/* Include darwin_specific.h here if needed */#endif/** FIXME This is quite ugly but needed while we don't have counters * helpers */#include "input/input_internal.h"#include "modules/modules.h"#include <assert.h>#include "vout_pictures.h"/***************************************************************************** * Local prototypes *****************************************************************************/static int      InitThread        ( vout_thread_t * );static void*    RunThread         ( vlc_object_t *  );static void     ErrorThread       ( vout_thread_t * );static void     CleanThread       ( vout_thread_t * );static void     EndThread         ( vout_thread_t * );static void     AspectRatio       ( int, int *, int * );static void VideoFormatImportRgb( video_format_t *, const picture_heap_t * );static void PictureHeapFixRgb( picture_heap_t * );static void     vout_Destructor   ( vlc_object_t * p_this );/* Object variables callbacks */static int DeinterlaceCallback( vlc_object_t *, char const *,                                vlc_value_t, vlc_value_t, void * );static int FilterCallback( vlc_object_t *, char const *,                           vlc_value_t, vlc_value_t, void * );static int VideoFilter2Callback( vlc_object_t *, char const *,                                 vlc_value_t, vlc_value_t, void * );/* From vout_intf.c */int vout_Snapshot( vout_thread_t *, picture_t * );/* Display media title in OSD */static void DisplayTitleOnOSD( vout_thread_t *p_vout );/* */static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture );/***************************************************************************** * Video Filter2 functions *****************************************************************************/static picture_t *video_new_buffer_filter( filter_t *p_filter ){    vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner;    picture_t *p_picture = vout_CreatePicture( p_vout, 0, 0, 0 );    p_picture->i_status = READY_PICTURE;    return p_picture;}static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic ){    vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner;    DropPicture( p_vout, p_pic );}static int video_filter_buffer_allocation_init( filter_t *p_filter, void *p_data ){    p_filter->pf_vout_buffer_new = video_new_buffer_filter;    p_filter->pf_vout_buffer_del = video_del_buffer_filter;    p_filter->p_owner = p_data; /* p_vout */    return VLC_SUCCESS;}/***************************************************************************** * vout_Request: find a video output thread, create one, or destroy one. ***************************************************************************** * This function looks for a video output thread matching the current * properties. If not found, it spawns a new one. *****************************************************************************/vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,                               video_format_t *p_fmt ){    const bool b_vout_provided = p_vout != NULL;    if( !p_fmt )    {        /* Video output is no longer used.         * TODO: support for reusing video outputs with proper _thread-safe_         * reference handling. */        if( p_vout )            vout_CloseAndRelease( p_vout );        return NULL;    }    /* If a video output was provided, lock it, otherwise look for one. */    if( p_vout )    {        vlc_object_yield( p_vout );    }    /* TODO: find a suitable unused video output */    /* If we now have a video output, check it has the right properties */    if( p_vout )    {        char *psz_filter_chain;        vlc_value_t val;        vlc_mutex_lock( &p_vout->change_lock );        /* We don't directly check for the "vout-filter" variable for obvious         * performance reasons. */        if( p_vout->b_filter_change )        {            var_Get( p_vout, "vout-filter", &val );            psz_filter_chain = val.psz_string;            if( psz_filter_chain && !*psz_filter_chain )            {                free( psz_filter_chain );                psz_filter_chain = NULL;            }            if( p_vout->psz_filter_chain && !*p_vout->psz_filter_chain )            {                free( p_vout->psz_filter_chain );                p_vout->psz_filter_chain = NULL;            }            if( !psz_filter_chain && !p_vout->psz_filter_chain )            {                p_vout->b_filter_change = false;            }            free( psz_filter_chain );        }        if( p_vout->fmt_render.i_chroma != p_fmt->i_chroma ||            p_vout->fmt_render.i_width != p_fmt->i_width ||            p_vout->fmt_render.i_height != p_fmt->i_height ||            p_vout->b_filter_change )        {            vlc_mutex_unlock( &p_vout->change_lock );            /* We are not interested in this format, close this vout */            vout_CloseAndRelease( p_vout );            vlc_object_release( p_vout );            p_vout = NULL;        }        else        {            /* This video output is cool! Hijack it. */            if( p_vout->fmt_render.i_aspect != p_fmt->i_aspect )            {                /* Correct aspect ratio on change                 * FIXME factorize this code with other aspect ration related code */                unsigned int i_sar_num;                unsigned int i_sar_den;                unsigned int i_aspect;                i_aspect = p_fmt->i_aspect;                vlc_ureduce( &i_sar_num, &i_sar_den,                             p_fmt->i_sar_num, p_fmt->i_sar_den, 50000 );#if 0                /* What's that, it does not seems to be used correcly everywhere                 * beside the previous p_vout->fmt_render.i_aspect != p_fmt->i_aspect                 * should be fixed to use it too then */                if( p_vout->i_par_num > 0 && p_vout->i_par_den > 0 )                {                    i_sar_num *= p_vout->i_par_den;                    i_sar_den *= p_vout->i_par_num;                    i_aspect = i_aspect * p_vout->i_par_den / p_vout->i_par_num;                }#endif                if( i_sar_num > 0 && i_sar_den > 0 && i_aspect > 0 )                {                    p_vout->fmt_in.i_sar_num = i_sar_num;                    p_vout->fmt_in.i_sar_den = i_sar_den;                    p_vout->fmt_in.i_aspect  = i_aspect;                    p_vout->fmt_render.i_sar_num = i_sar_num;                    p_vout->fmt_render.i_sar_den = i_sar_den;                    p_vout->fmt_render.i_aspect  = i_aspect;                    p_vout->render.i_aspect   = i_aspect;                    p_vout->i_changes |= VOUT_ASPECT_CHANGE;                }            }            vlc_mutex_unlock( &p_vout->change_lock );            vlc_object_release( p_vout );        }        if( p_vout )        {            msg_Dbg( p_this, "reusing provided vout" );            spu_Attach( p_vout->p_spu, p_this, true );            vlc_object_detach( p_vout );            vlc_object_attach( p_vout, p_this );            /* Display title if we are not using the vout given to vout_Request.             * XXX for now b_vout_provided is always true at this stage */            if( p_vout->b_title_show && !b_vout_provided )                DisplayTitleOnOSD( p_vout );        }    }    if( !p_vout )    {        msg_Dbg( p_this, "no usable vout present, spawning one" );        p_vout = vout_Create( p_this, p_fmt );    }    return p_vout;}/***************************************************************************** * vout_Create: creates a new video output thread ***************************************************************************** * This function creates a new video output thread, and returns a pointer * to its description. On error, it returns NULL. *****************************************************************************/vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ){    vout_thread_t  * p_vout;                            /* thread descriptor */    input_thread_t * p_input_thread;    int              i_index;                               /* loop variable */    vlc_value_t      val, text;    unsigned int i_width = p_fmt->i_width;    unsigned int i_height = p_fmt->i_height;    vlc_fourcc_t i_chroma = p_fmt->i_chroma;    unsigned int i_aspect = p_fmt->i_aspect;    config_chain_t *p_cfg;    char *psz_parser;    char *psz_name;    if( i_width <= 0 || i_height <= 0 || i_aspect <= 0 )        return NULL;    vlc_ureduce( &p_fmt->i_sar_num, &p_fmt->i_sar_den,                 p_fmt->i_sar_num, p_fmt->i_sar_den, 50000 );    if( p_fmt->i_sar_num <= 0 || p_fmt->i_sar_den <= 0 )        return NULL;    /* Allocate descriptor */    static const char typename[] = "video output";    p_vout = vlc_custom_create( p_parent, sizeof( *p_vout ), VLC_OBJECT_VOUT,                                typename );    if( p_vout == NULL )        return NULL;    /* Initialize pictures - translation tables and functions     * will be initialized later in InitThread */    for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES + 1; i_index++)    {        p_vout->p_picture[i_index].pf_lock = NULL;        p_vout->p_picture[i_index].pf_unlock = NULL;        p_vout->p_picture[i_index].i_status = FREE_PICTURE;        p_vout->p_picture[i_index].i_type   = EMPTY_PICTURE;        p_vout->p_picture[i_index].b_slow   = 0;    }    /* No images in the heap */    p_vout->i_heap_size = 0;    /* Initialize the rendering heap */    I_RENDERPICTURES = 0;    p_vout->fmt_render        = *p_fmt;   /* FIXME palette */    p_vout->fmt_in            = *p_fmt;   /* FIXME palette */    p_vout->render.i_width    = i_width;    p_vout->render.i_height   = i_height;    p_vout->render.i_chroma   = i_chroma;    p_vout->render.i_aspect   = i_aspect;    p_vout->render.i_rmask    = p_fmt->i_rmask;    p_vout->render.i_gmask    = p_fmt->i_gmask;    p_vout->render.i_bmask    = p_fmt->i_bmask;    p_vout->render.i_last_used_pic = -1;    p_vout->render.b_allow_modify_pics = 1;    /* Zero the output heap */    I_OUTPUTPICTURES = 0;    p_vout->output.i_width    = 0;    p_vout->output.i_height   = 0;    p_vout->output.i_chroma   = 0;    p_vout->output.i_aspect   = 0;    p_vout->output.i_rmask    = 0;    p_vout->output.i_gmask    = 0;    p_vout->output.i_bmask    = 0;    /* Initialize misc stuff */    p_vout->i_changes    = 0;    p_vout->f_gamma      = 0;    p_vout->b_grayscale  = 0;    p_vout->b_info       = 0;    p_vout->b_interface  = 0;    p_vout->b_scale      = 1;    p_vout->b_fullscreen = 0;    p_vout->i_alignment  = 0;    p_vout->render_time  = 10;    p_vout->c_fps_samples = 0;    p_vout->b_filter_change = 0;    p_vout->pf_control = NULL;    p_vout->p_window = NULL;    p_vout->i_par_num = p_vout->i_par_den = 1;    /* Initialize locks */    vlc_mutex_init( &p_vout->picture_lock );    vlc_mutex_init( &p_vout->change_lock );    vlc_mutex_init( &p_vout->vfilter_lock );    /* Mouse coordinates */    var_Create( p_vout, "mouse-x", VLC_VAR_INTEGER );    var_Create( p_vout, "mouse-y", VLC_VAR_INTEGER );    var_Create( p_vout, "mouse-button-down", VLC_VAR_INTEGER );    var_Create( p_vout, "mouse-moved", VLC_VAR_BOOL );    var_Create( p_vout, "mouse-clicked", VLC_VAR_INTEGER );    /* Initialize subpicture unit */    p_vout->p_spu = spu_Create( p_vout );    spu_Attach( p_vout->p_spu, p_parent, true );    /* Attach the new object now so we can use var inheritance below */    vlc_object_attach( p_vout, p_parent );    spu_Init( p_vout->p_spu );    /* Take care of some "interface/control" related initialisations */    vout_IntfInit( p_vout );    /* If the parent is not a VOUT object, that means we are at the start of     * the video output pipe */    if( p_parent->i_object_type != VLC_OBJECT_VOUT )    {        /* Look for the default filter configuration */        p_vout->psz_filter_chain =            var_CreateGetStringCommand( p_vout, "vout-filter" );        /* Apply video filter2 objects on the first vout */        p_vout->psz_vf2 =            var_CreateGetStringCommand( p_vout, "video-filter" );    }    else    {        /* continue the parent's filter chain */        char *psz_tmp;        /* Ugly hack to jump to our configuration chain */        p_vout->psz_filter_chain            = ((vout_thread_t *)p_parent)->psz_filter_chain;        p_vout->psz_filter_chain

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -