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

📄 video_output.c

📁 video linux conference
💻 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-2004 VideoLAN * $Id: video_output.c 11112 2005-05-22 16:18:46Z zorglub $ * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>                                                /* free() */#include <vlc/vlc.h>#ifdef HAVE_SYS_TIMES_H#   include <sys/times.h>#endif#include "vlc_video.h"#include "video_output.h"#include "vlc_spu.h"#include <vlc/input.h>                 /* for input_thread_t and i_pts_delay */#include "vlc_playlist.h"#if defined( SYS_DARWIN )#include "darwin_specific.h"#endif/***************************************************************************** * Local prototypes *****************************************************************************/static int      InitThread        ( vout_thread_t * );static void     RunThread         ( vout_thread_t * );static void     ErrorThread       ( vout_thread_t * );static void     EndThread         ( vout_thread_t * );static void     DestroyThread     ( vout_thread_t * );static void     AspectRatio       ( int, int *, int * );static int      BinaryLog         ( uint32_t );static void     MaskToShift       ( int *, int *, uint32_t );static void     InitWindowSize    ( vout_thread_t *, int *, int * );/* 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 * );/* From vout_intf.c */int vout_Snapshot( vout_thread_t *, picture_t * );/***************************************************************************** * 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 ){    if( !p_fmt )    {        /* Reattach video output to input before bailing out */        if( p_vout )        {            vlc_object_t *p_playlist;            p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,                                          FIND_ANYWHERE );            if( p_playlist )            {                spu_Attach( p_vout->p_spu, p_this, VLC_FALSE );                vlc_object_detach( p_vout );                vlc_object_attach( p_vout, p_playlist );                vlc_object_release( p_playlist );            }            else            {                msg_Dbg( p_this, "cannot find playlist, destroying vout" );                vlc_object_detach( p_vout );                vout_Destroy( p_vout );            }        }        return NULL;    }    /* If a video output was provided, lock it, otherwise look for one. */    if( p_vout )    {        vlc_object_yield( p_vout );    }    else    {        p_vout = vlc_object_find( p_this, VLC_OBJECT_VOUT, FIND_CHILD );        if( !p_vout )        {            playlist_t *p_playlist;            p_playlist = vlc_object_find( p_this,                                          VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );            if( p_playlist )            {                vlc_mutex_lock( &p_playlist->gc_lock );                p_vout = vlc_object_find( p_playlist,                                          VLC_OBJECT_VOUT, FIND_CHILD );                /* only first children of p_input for unused vout */                if( p_vout && p_vout->p_parent != p_playlist )                {                    vlc_object_release( p_vout );                    p_vout = NULL;                }                vlc_mutex_unlock( &p_playlist->gc_lock );                vlc_object_release( p_playlist );            }        }    }    /* If we now have a video output, check it has the right properties */    if( p_vout )    {        char *psz_filter_chain;        vlc_value_t val;        /* 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 = VLC_FALSE;            }            if( psz_filter_chain ) free( psz_filter_chain );        }        if( ( p_vout->fmt_render.i_width != p_fmt->i_width ) ||            ( p_vout->fmt_render.i_height != p_fmt->i_height ) ||            ( p_vout->fmt_render.i_chroma != p_fmt->i_chroma ) ||            ( p_vout->fmt_render.i_aspect != p_fmt->i_aspect                    && !p_vout->b_override_aspect ) ||            p_vout->b_filter_change )        {            /* We are not interested in this format, close this vout */            vlc_object_detach( p_vout );            vlc_object_release( p_vout );            vout_Destroy( p_vout );            p_vout = NULL;        }        else        {            /* This video output is cool! Hijack it. */            vlc_object_detach( p_vout );            spu_Attach( p_vout->p_spu, p_this, VLC_TRUE );            vlc_object_attach( p_vout, p_this );            vlc_object_release( 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 */    char           * psz_plugin;    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;    /* Allocate descriptor */    p_vout = vlc_object_create( p_parent, VLC_OBJECT_VOUT );    if( p_vout == NULL )    {        msg_Err( p_parent, "out of memory" );        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    = 0;    p_vout->render.i_gmask    = 0;    p_vout->render.i_bmask    = 0;    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 = 0;    p_vout->p_parent_intf = 0;    /* Initialize locks */    vlc_mutex_init( p_vout, &p_vout->picture_lock );    vlc_mutex_init( p_vout, &p_vout->change_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, VLC_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 );    p_vout->b_override_aspect = VLC_FALSE;    /* 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 )    {        var_Get( p_vout, "aspect-ratio", &val );        /* Check whether the user tried to override aspect ratio */        if( val.psz_string )        {            unsigned int i_new_aspect = i_aspect;            char *psz_parser = strchr( val.psz_string, ':' );            if( psz_parser )            {                *psz_parser++ = '\0';                i_new_aspect = atoi( val.psz_string ) * VOUT_ASPECT_FACTOR                                                      / atoi( psz_parser );            }            else            {                i_new_aspect = VOUT_ASPECT_FACTOR                                       * atof( val.psz_string );            }            free( val.psz_string );            if( i_new_aspect && i_new_aspect != i_aspect )            {                int i_aspect_x, i_aspect_y;                AspectRatio( i_new_aspect, &i_aspect_x, &i_aspect_y );                msg_Dbg( p_vout, "overriding source aspect ratio to %i:%i",                         i_aspect_x, i_aspect_y );                p_vout->render.i_aspect = i_new_aspect;                p_vout->b_override_aspect = VLC_TRUE;            }        }        /* Look for the default filter configuration */        var_Create( p_vout, "vout-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );        var_Get( p_vout, "vout-filter", &val );        p_vout->psz_filter_chain = val.psz_string;        if( p_vout->psz_filter_chain && *p_vout->psz_filter_chain &&            strchr( p_vout->psz_filter_chain, ',' ) &&            !strchr( p_vout->psz_filter_chain, ':') )        {            msg_Info( p_vout, "Warning: you are using a deprecated syntax for "                             "vout-filter." );            msg_Info( p_vout, "You must now use ':' as separator instead of "                             "','." );        }

⌨️ 快捷键说明

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