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

📄 video_output.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
 *****************************************************************************/static void EndThread( vout_thread_t *p_vout ){#ifdef STATS    {        struct tms cpu_usage;        times( &cpu_usage );        msg_Dbg( p_vout, "cpu usage (user: %d, system: %d)",                 cpu_usage.tms_utime, cpu_usage.tms_stime );    }#endif    /* FIXME does that function *really* need to be called inside the thread ? */    /* Destroy subpicture unit */    spu_Attach( p_vout->p_spu, VLC_OBJECT(p_vout), false );    spu_Destroy( p_vout->p_spu );    /* Destroy the video filters2 */    filter_chain_Delete( p_vout->p_vf2_chain );}/* Thread helpers */static picture_t *ChromaGetPicture( filter_t *p_filter ){    picture_t *p_pic = (picture_t *)p_filter->p_owner;    p_filter->p_owner = NULL;    return p_pic;}static int ChromaCreate( vout_thread_t *p_vout ){    static const char typename[] = "chroma";    filter_t *p_chroma;    /* Choose the best module */    p_chroma = p_vout->p_chroma =        vlc_custom_create( p_vout, sizeof(filter_t), VLC_OBJECT_GENERIC,                           typename );    vlc_object_attach( p_chroma, p_vout );    /* TODO: Set the fmt_in and fmt_out stuff here */    p_chroma->fmt_in.video = p_vout->fmt_render;    p_chroma->fmt_out.video = p_vout->fmt_out;    VideoFormatImportRgb( &p_chroma->fmt_in.video, &p_vout->render );    VideoFormatImportRgb( &p_chroma->fmt_out.video, &p_vout->output );    p_chroma->p_module = module_Need( p_chroma, "video filter2", NULL, 0 );    if( p_chroma->p_module == NULL )    {        msg_Err( p_vout, "no chroma module for %4.4s to %4.4s i=%dx%d o=%dx%d",                 (char*)&p_vout->render.i_chroma,                 (char*)&p_vout->output.i_chroma,                 p_chroma->fmt_in.video.i_width, p_chroma->fmt_in.video.i_height,                 p_chroma->fmt_out.video.i_width, p_chroma->fmt_out.video.i_height                 );        vlc_object_release( p_vout->p_chroma );        p_vout->p_chroma = NULL;        return VLC_EGENERIC;    }    p_chroma->pf_vout_buffer_new = ChromaGetPicture;    return VLC_SUCCESS;}static void ChromaDestroy( vout_thread_t *p_vout ){    assert( !p_vout->b_direct );    if( !p_vout->p_chroma )        return;    module_Unneed( p_vout->p_chroma, p_vout->p_chroma->p_module );    vlc_object_release( p_vout->p_chroma );    p_vout->p_chroma = NULL;}static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture ){    vlc_mutex_lock( &p_vout->picture_lock );    if( p_picture->i_refcount )    {        /* Pretend we displayed the picture, but don't destroy         * it since the decoder might still need it. */        p_picture->i_status = DISPLAYED_PICTURE;    }    else    {        /* Destroy the picture without displaying it */        p_picture->i_status = DESTROYED_PICTURE;        p_vout->i_heap_size--;    }    vlc_mutex_unlock( &p_vout->picture_lock );}/* following functions are local */static int ReduceHeight( int i_ratio ){    int i_dummy = VOUT_ASPECT_FACTOR;    int i_pgcd  = 1;    if( !i_ratio )    {        return i_pgcd;    }    /* VOUT_ASPECT_FACTOR is (2^7 * 3^3 * 5^3), we just check for 2, 3 and 5 */    while( !(i_ratio & 1) && !(i_dummy & 1) )    {        i_ratio >>= 1;        i_dummy >>= 1;        i_pgcd  <<= 1;    }    while( !(i_ratio % 3) && !(i_dummy % 3) )    {        i_ratio /= 3;        i_dummy /= 3;        i_pgcd  *= 3;    }    while( !(i_ratio % 5) && !(i_dummy % 5) )    {        i_ratio /= 5;        i_dummy /= 5;        i_pgcd  *= 5;    }    return i_pgcd;}static void AspectRatio( int i_aspect, int *i_aspect_x, int *i_aspect_y ){    unsigned int i_pgcd = ReduceHeight( i_aspect );    *i_aspect_x = i_aspect / i_pgcd;    *i_aspect_y = VOUT_ASPECT_FACTOR / i_pgcd;}/** * This function copies all RGB informations from a picture_heap_t into * a video_format_t */static void VideoFormatImportRgb( video_format_t *p_fmt, const picture_heap_t *p_heap ){    p_fmt->i_rmask = p_heap->i_rmask;    p_fmt->i_gmask = p_heap->i_gmask;    p_fmt->i_bmask = p_heap->i_bmask;    p_fmt->i_rrshift = p_heap->i_rrshift;    p_fmt->i_lrshift = p_heap->i_lrshift;    p_fmt->i_rgshift = p_heap->i_rgshift;    p_fmt->i_lgshift = p_heap->i_lgshift;    p_fmt->i_rbshift = p_heap->i_rbshift;    p_fmt->i_lbshift = p_heap->i_lbshift;}/** * This funtion copes all RGB informations from a video_format_t into * a picture_heap_t */static void VideoFormatExportRgb( const video_format_t *p_fmt, picture_heap_t *p_heap ){    p_heap->i_rmask = p_fmt->i_rmask;    p_heap->i_gmask = p_fmt->i_gmask;    p_heap->i_bmask = p_fmt->i_bmask;    p_heap->i_rrshift = p_fmt->i_rrshift;    p_heap->i_lrshift = p_fmt->i_lrshift;    p_heap->i_rgshift = p_fmt->i_rgshift;    p_heap->i_lgshift = p_fmt->i_lgshift;    p_heap->i_rbshift = p_fmt->i_rbshift;    p_heap->i_lbshift = p_fmt->i_lbshift;}/** * This function computes rgb shifts from masks */static void PictureHeapFixRgb( picture_heap_t *p_heap ){    video_format_t fmt;    /* */    fmt.i_chroma = p_heap->i_chroma;    VideoFormatImportRgb( &fmt, p_heap );    /* */    video_format_FixRgb( &fmt );    VideoFormatExportRgb( &fmt, p_heap );}/***************************************************************************** * Helper thread for object variables callbacks. * Only used to avoid deadlocks when using the video embedded mode. *****************************************************************************/typedef struct suxor_thread_t{    VLC_COMMON_MEMBERS    input_thread_t *p_input;} suxor_thread_t;static void* SuxorRestartVideoES( vlc_object_t * p_vlc_t ){    suxor_thread_t *p_this = (suxor_thread_t *) p_vlc_t;    /* Now restart current video stream */    int val = var_GetInteger( p_this->p_input, "video-es" );    if( val >= 0 )    {        var_SetInteger( p_this->p_input, "video-es", -VIDEO_ES );        var_SetInteger( p_this->p_input, "video-es", val );    }    vlc_object_release( p_this->p_input );    vlc_object_release( p_this );    return NULL;}/***************************************************************************** * object variables callbacks: a bunch of object variables are used by the * interfaces to interact with the vout. *****************************************************************************/static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    vout_thread_t *p_vout = (vout_thread_t *)p_this;    input_thread_t *p_input;    vlc_value_t val;    char *psz_mode = newval.psz_string;    char *psz_filter, *psz_deinterlace = NULL;    (void)psz_cmd; (void)oldval; (void)p_data;    var_Get( p_vout, "vout-filter", &val );    psz_filter = val.psz_string;    if( psz_filter ) psz_deinterlace = strstr( psz_filter, "deinterlace" );    if( !psz_mode || !*psz_mode )    {        if( psz_deinterlace )        {            char *psz_src = psz_deinterlace + sizeof("deinterlace") - 1;            if( psz_src[0] == ':' ) psz_src++;            memmove( psz_deinterlace, psz_src, strlen(psz_src) + 1 );        }    }    else if( !psz_deinterlace )    {        psz_filter = realloc( psz_filter, strlen( psz_filter ) +                              sizeof(":deinterlace") );        if( psz_filter && *psz_filter ) strcat( psz_filter, ":" );        strcat( psz_filter, "deinterlace" );    }    p_input = (input_thread_t *)vlc_object_find( p_this, VLC_OBJECT_INPUT,                                                 FIND_PARENT );    if( !p_input ) return VLC_EGENERIC;    if( psz_mode && *psz_mode )    {        /* Modify input as well because the vout might have to be restarted */        val.psz_string = psz_mode;        var_Create( p_input, "deinterlace-mode", VLC_VAR_STRING );        var_Set( p_input, "deinterlace-mode", val );    }    vlc_object_release( p_input );    val.b_bool = true;    var_Set( p_vout, "intf-change", val );    val.psz_string = psz_filter;    var_Set( p_vout, "vout-filter", val );    free( psz_filter );    return VLC_SUCCESS;}static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    vout_thread_t *p_vout = (vout_thread_t *)p_this;    input_thread_t *p_input;    vlc_value_t val;    (void)psz_cmd; (void)oldval; (void)p_data;    p_input = (input_thread_t *)vlc_object_find( p_this, VLC_OBJECT_INPUT,                                                 FIND_PARENT );    if (!p_input)    {        msg_Err( p_vout, "Input not found" );        return( VLC_EGENERIC );    }    val.b_bool = true;    var_Set( p_vout, "intf-change", val );    /* Modify input as well because the vout might have to be restarted */    val.psz_string = newval.psz_string;    var_Create( p_input, "vout-filter", VLC_VAR_STRING );    var_Set( p_input, "vout-filter", val );    /* Now restart current video stream */    var_Get( p_input, "video-es", &val );    if( val.i_int >= 0 )    {        static const char typename[] = "kludge";        suxor_thread_t *p_suxor =            vlc_custom_create( p_vout, sizeof(suxor_thread_t),                               VLC_OBJECT_GENERIC, typename );        p_suxor->p_input = p_input;        p_vout->b_filter_change = true;        vlc_object_yield( p_input );        vlc_thread_create( p_suxor, "suxor", SuxorRestartVideoES,                           VLC_THREAD_PRIORITY_LOW, false );    }    vlc_object_release( p_input );    return VLC_SUCCESS;}/***************************************************************************** * Video Filter2 stuff *****************************************************************************/static int VideoFilter2Callback( vlc_object_t *p_this, char const *psz_cmd,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    vout_thread_t *p_vout = (vout_thread_t *)p_this;    (void)psz_cmd; (void)oldval; (void)p_data;    vlc_mutex_lock( &p_vout->vfilter_lock );    p_vout->psz_vf2 = strdup( newval.psz_string );    vlc_mutex_unlock( &p_vout->vfilter_lock );    return VLC_SUCCESS;}static void DisplayTitleOnOSD( vout_thread_t *p_vout ){    input_thread_t *p_input;    mtime_t i_now, i_stop;    if( !config_GetInt( p_vout, "osd" ) ) return;    p_input = (input_thread_t *)vlc_object_find( p_vout,              VLC_OBJECT_INPUT, FIND_ANYWHERE );    if( p_input )    {        i_now = mdate();        i_stop = i_now + (mtime_t)(p_vout->i_title_timeout * 1000);        char *psz_nowplaying =            input_item_GetNowPlaying( input_GetItem( p_input ) );        char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) );        char *psz_name = input_item_GetTitle( input_GetItem( p_input ) );        if( EMPTY_STR( psz_name ) )        {            free( psz_name );            psz_name = input_item_GetName( input_GetItem( p_input ) );        }        if( !EMPTY_STR( psz_nowplaying ) )        {            vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,                                   psz_nowplaying, NULL,                                   p_vout->i_title_position,                                   30 + p_vout->fmt_in.i_width                                      - p_vout->fmt_in.i_visible_width                                      - p_vout->fmt_in.i_x_offset,                                   20 + p_vout->fmt_in.i_y_offset,                                   i_now, i_stop );        }        else if( !EMPTY_STR( psz_artist ) )        {            char *psz_string = NULL;            if( asprintf( &psz_string, "%s - %s", psz_name, psz_artist ) != -1 )            {                vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,                                       psz_string, NULL,                                       p_vout->i_title_position,                                       30 + p_vout->fmt_in.i_width                                          - p_vout->fmt_in.i_visible_width                                          - p_vout->fmt_in.i_x_offset,                                       20 + p_vout->fmt_in.i_y_offset,                                       i_now, i_stop );                free( psz_string );            }        }        else        {            vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,                                   psz_name, NULL,                                   p_vout->i_title_position,                                   30 + p_vout->fmt_in.i_width                                      - p_vout->fmt_in.i_visible_width                                      - p_vout->fmt_in.i_x_offset,                                   20 + p_vout->fmt_in.i_y_offset,                                   i_now, i_stop );        }        vlc_object_release( p_input );        free( psz_artist );        free( psz_name );        free( psz_nowplaying );    }}

⌨️ 快捷键说明

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