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

📄 video_output.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        psz_end = strchr( p_vout->psz_filter_chain, ':' );        if( psz_end )            psz_plugin = strndup( p_vout->psz_filter_chain,                                  psz_end - p_vout->psz_filter_chain );        else psz_plugin = strdup( p_vout->psz_filter_chain );    }    /* Create the vout thread */    p_vout->p_module = module_Need( p_vout,        ( p_vout->psz_filter_chain && *p_vout->psz_filter_chain ) ?        "video filter" : "video output", psz_plugin, 0 );    if( psz_plugin ) free( psz_plugin );    if( p_vout->p_module == NULL )    {        msg_Err( p_vout, "no suitable vout module" );        vlc_object_detach( p_vout );        vlc_object_destroy( p_vout );        return NULL;    }    /* Create a few object variables for interface interaction */    var_Create( p_vout, "deinterlace", VLC_VAR_STRING | VLC_VAR_HASCHOICE );    text.psz_string = _("Deinterlace");    var_Change( p_vout, "deinterlace", VLC_VAR_SETTEXT, &text, NULL );    val.psz_string = ""; text.psz_string = _("Disable");    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    val.psz_string = "discard"; text.psz_string = _("Discard");    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    val.psz_string = "blend"; text.psz_string = _("Blend");    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    val.psz_string = "mean"; text.psz_string = _("Mean");    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    val.psz_string = "bob"; text.psz_string = _("Bob");    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    val.psz_string = "linear"; text.psz_string = _("Linear");    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    val.psz_string = "x"; text.psz_string = "X";    var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );    if( var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS )    {        var_Set( p_vout, "deinterlace", val );        if( val.psz_string ) free( val.psz_string );    }    var_AddCallback( p_vout, "deinterlace", DeinterlaceCallback, NULL );    var_Create( p_vout, "vout-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    text.psz_string = _("Filters");    var_Change( p_vout, "vout-filter", VLC_VAR_SETTEXT, &text, NULL );    var_AddCallback( p_vout, "vout-filter", FilterCallback, NULL );    /* Calculate delay created by internal caching */    p_input_thread = (input_thread_t *)vlc_object_find( p_vout,                                           VLC_OBJECT_INPUT, FIND_ANYWHERE );    if( p_input_thread )    {        p_vout->i_pts_delay = p_input_thread->i_pts_delay;        vlc_object_release( p_input_thread );    }    else    {        p_vout->i_pts_delay = DEFAULT_PTS_DELAY;    }    if( vlc_thread_create( p_vout, "video output", RunThread,                           VLC_THREAD_PRIORITY_OUTPUT, VLC_TRUE ) )    {        msg_Err( p_vout, "out of memory" );        module_Unneed( p_vout, p_vout->p_module );        vlc_object_detach( p_vout );        vlc_object_destroy( p_vout );        return NULL;    }    if( p_vout->b_error )    {        msg_Err( p_vout, "video output creation failed" );        /* Make sure the thread is destroyed */        p_vout->b_die = VLC_TRUE;        vlc_thread_join( p_vout );        vlc_object_detach( p_vout );        vlc_object_destroy( p_vout );        return NULL;    }    return p_vout;}/***************************************************************************** * vout_Destroy: destroys a previously created video output ***************************************************************************** * Destroy a terminated thread. * The function will request a destruction of the specified thread. If pi_error * is NULL, it will return once the thread is destroyed. Else, it will be * update using one of the THREAD_* constants. *****************************************************************************/void vout_Destroy( vout_thread_t *p_vout ){    vlc_object_t *p_playlist;    /* Request thread destruction */    p_vout->b_die = VLC_TRUE;    vlc_thread_join( p_vout );    var_Destroy( p_vout, "intf-change" );    p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,                                  FIND_ANYWHERE );    if( p_vout->psz_filter_chain ) free( p_vout->psz_filter_chain );    /* Free structure */    vlc_object_destroy( p_vout );    /* This is a dirty hack for mostly Linux, where there is no way to get the GUI       back if you closed it while playing video. This is solved in Mac OS X,       where we have this novelty called menubar, that will always allow you access       to the applications main functionality. They should try that on linux sometime */    /* If it was the last vout, tell the interface to show up */    if( p_playlist != NULL )    {#ifndef __APPLE__        vout_thread_t *p_another_vout = vlc_object_find( p_playlist,                                            VLC_OBJECT_VOUT, FIND_ANYWHERE );        if( p_another_vout == NULL )        {            vlc_value_t val;            val.b_bool = VLC_TRUE;            var_Set( p_playlist, "intf-show", val );        }        else        {            vlc_object_release( p_another_vout );        }#endif        vlc_object_release( p_playlist );    }}/***************************************************************************** * InitThread: initialize video output thread ***************************************************************************** * This function is called from RunThread and performs the second step of the * initialization. It returns 0 on success. Note that the thread's flag are not * modified inside this function. *****************************************************************************/static int InitThread( vout_thread_t *p_vout ){    int i, i_aspect_x, i_aspect_y;    vlc_mutex_lock( &p_vout->change_lock );#ifdef STATS    p_vout->c_loops = 0;#endif    /* Initialize output method, it allocates direct buffers for us */    if( p_vout->pf_init( p_vout ) )    {        vlc_mutex_unlock( &p_vout->change_lock );        return VLC_EGENERIC;    }    if( !I_OUTPUTPICTURES )    {        msg_Err( p_vout, "plugin was unable to allocate at least "                         "one direct buffer" );        p_vout->pf_end( p_vout );        vlc_mutex_unlock( &p_vout->change_lock );        return VLC_EGENERIC;    }    if( I_OUTPUTPICTURES > VOUT_MAX_PICTURES )    {        msg_Err( p_vout, "plugin allocated too many direct buffers, "                         "our internal buffers must have overflown." );        p_vout->pf_end( p_vout );        vlc_mutex_unlock( &p_vout->change_lock );        return VLC_EGENERIC;    }    msg_Dbg( p_vout, "got %i direct buffer(s)", I_OUTPUTPICTURES );    AspectRatio( p_vout->fmt_render.i_aspect, &i_aspect_x, &i_aspect_y );    msg_Dbg( p_vout, "picture in %ix%i (%i,%i,%ix%i), "             "chroma %4.4s, ar %i:%i, sar %i:%i",             p_vout->fmt_render.i_width, p_vout->fmt_render.i_height,             p_vout->fmt_render.i_x_offset, p_vout->fmt_render.i_y_offset,             p_vout->fmt_render.i_visible_width,             p_vout->fmt_render.i_visible_height,             (char*)&p_vout->fmt_render.i_chroma,             i_aspect_x, i_aspect_y,             p_vout->fmt_render.i_sar_num, p_vout->fmt_render.i_sar_den );    AspectRatio( p_vout->fmt_in.i_aspect, &i_aspect_x, &i_aspect_y );    msg_Dbg( p_vout, "picture user %ix%i (%i,%i,%ix%i), "             "chroma %4.4s, ar %i:%i, sar %i:%i",             p_vout->fmt_in.i_width, p_vout->fmt_in.i_height,             p_vout->fmt_in.i_x_offset, p_vout->fmt_in.i_y_offset,             p_vout->fmt_in.i_visible_width,             p_vout->fmt_in.i_visible_height,             (char*)&p_vout->fmt_in.i_chroma,             i_aspect_x, i_aspect_y,             p_vout->fmt_in.i_sar_num, p_vout->fmt_in.i_sar_den );    if( !p_vout->fmt_out.i_width || !p_vout->fmt_out.i_height )    {        p_vout->fmt_out.i_width = p_vout->fmt_out.i_visible_width =            p_vout->output.i_width;        p_vout->fmt_out.i_height = p_vout->fmt_out.i_visible_height =            p_vout->output.i_height;        p_vout->fmt_out.i_x_offset =  p_vout->fmt_out.i_y_offset = 0;        p_vout->fmt_out.i_aspect = p_vout->output.i_aspect;        p_vout->fmt_out.i_chroma = p_vout->output.i_chroma;    }    if( !p_vout->fmt_out.i_sar_num || !p_vout->fmt_out.i_sar_num )    {        p_vout->fmt_out.i_sar_num = p_vout->fmt_out.i_aspect *            p_vout->fmt_out.i_height;        p_vout->fmt_out.i_sar_den = VOUT_ASPECT_FACTOR *            p_vout->fmt_out.i_width;    }    vlc_ureduce( &p_vout->fmt_out.i_sar_num, &p_vout->fmt_out.i_sar_den,                 p_vout->fmt_out.i_sar_num, p_vout->fmt_out.i_sar_den, 0 );    AspectRatio( p_vout->fmt_out.i_aspect, &i_aspect_x, &i_aspect_y );    msg_Dbg( p_vout, "picture out %ix%i (%i,%i,%ix%i), "             "chroma %4.4s, ar %i:%i, sar %i:%i",             p_vout->fmt_out.i_width, p_vout->fmt_out.i_height,             p_vout->fmt_out.i_x_offset, p_vout->fmt_out.i_y_offset,             p_vout->fmt_out.i_visible_width,             p_vout->fmt_out.i_visible_height,             (char*)&p_vout->fmt_out.i_chroma,             i_aspect_x, i_aspect_y,             p_vout->fmt_out.i_sar_num, p_vout->fmt_out.i_sar_den );    /* Calculate shifts from system-updated masks */    MaskToShift( &p_vout->output.i_lrshift, &p_vout->output.i_rrshift,                 p_vout->output.i_rmask );    MaskToShift( &p_vout->output.i_lgshift, &p_vout->output.i_rgshift,                 p_vout->output.i_gmask );    MaskToShift( &p_vout->output.i_lbshift, &p_vout->output.i_rbshift,                 p_vout->output.i_bmask );    /* Check whether we managed to create direct buffers similar to     * the render buffers, ie same size and chroma */    if( ( p_vout->output.i_width == p_vout->render.i_width )     && ( p_vout->output.i_height == p_vout->render.i_height )     && ( vout_ChromaCmp( p_vout->output.i_chroma, p_vout->render.i_chroma ) ) )    {        /* Cool ! We have direct buffers, we can ask the decoder to         * directly decode into them ! Map the first render buffers to         * the first direct buffers, but keep the first direct buffer         * for memcpy operations */        p_vout->b_direct = 1;        for( i = 1; i < VOUT_MAX_PICTURES; i++ )        {            if( p_vout->p_picture[ i ].i_type != DIRECT_PICTURE &&                I_RENDERPICTURES >= VOUT_MIN_DIRECT_PICTURES - 1 &&                p_vout->p_picture[ i - 1 ].i_type == DIRECT_PICTURE )            {                /* We have enough direct buffers so there's no need to                 * try to use system memory buffers. */                break;            }            PP_RENDERPICTURE[ I_RENDERPICTURES ] = &p_vout->p_picture[ i ];            I_RENDERPICTURES++;        }        msg_Dbg( p_vout, "direct render, mapping "                 "render pictures 0-%i to system pictures 1-%i",                 VOUT_MAX_PICTURES - 2, VOUT_MAX_PICTURES - 1 );    }    else    {        /* Rats... Something is wrong here, we could not find an output         * plugin able to directly render what we decode. See if we can         * find a chroma plugin to do the conversion */        p_vout->b_direct = 0;        /* Choose the best module */        p_vout->chroma.p_module = module_Need( p_vout, "chroma", NULL, 0 );        if( p_vout->chroma.p_module == NULL )        {            msg_Err( p_vout, "no chroma module for %4.4s to %4.4s",                     (char*)&p_vout->render.i_chroma,                     (char*)&p_vout->output.i_chroma );            p_vout->pf_end( p_vout );            vlc_mutex_unlock( &p_vout->change_lock );            return VLC_EGENERIC;        }        msg_Dbg( p_vout, "indirect render, mapping "                 "render pictures 0-%i to system pictures %i-%i",                 VOUT_MAX_PICTURES - 1, I_OUTPUTPICTURES,                 I_OUTPUTPICTURES + VOUT_MAX_PICTURES - 1 );        /* Append render buffers after the direct buffers */        for( i = I_OUTPUTPICTURES; i < 2 * VOUT_MAX_PICTURES; i++ )        {            PP_RENDERPICTURE[ I_RENDERPICTURES ] = &p_vout->p_picture[ i ];            I_RENDERPICTURES++;            /* Check if we have enough render pictures */            if( I_RENDERPICTURES == VOUT_MAX_PICTURES )                break;        }    }    /* Link pictures back to their heap */    for( i = 0 ; i < I_RENDERPICTURES ; i++ )    {        PP_RENDERPICTURE[ i ]->p_heap = &p_vout->render;    }    for( i = 0 ; i < I_OUTPUTPICTURES ; i++ )    {        PP_OUTPUTPICTURE[ i ]->p_heap = &p_vout->output;    }/* XXX XXX mark thread ready */    return VLC_SUCCESS;}/***************************************************************************** * RunThread: video output thread ***************************************************************************** * Video output thread. This function does only returns when the thread is * terminated. It handles the pictures arriving in the video heap and the * display device events. *****************************************************************************/static void RunThread( vout_thread_t *p_vout){    int             i_index;                                /* index in heap */    int             i_idle_loops = 0;  /* loops without displaying a picture */    mtime_t         current_date;                            /* current date */    mtime_t         display_date;                            /* display date */    picture_t *     p_picture;                            /* picture pointer */    picture_t *     p_last_picture = NULL;                   /* last picture */    picture_t *     p_directbuffer;              /* direct buffer to display */

⌨️ 快捷键说明

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