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

📄 video_output.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
 ***************************************************************************** * This function is called when the thread ends after a sucessful * initialization. It frees all resources allocated by InitThread. *****************************************************************************/static void EndThread( vout_thread_t *p_vout ){    int     i_index;                                        /* index in heap */#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    if( !p_vout->b_direct )    {        module_Unneed( p_vout, p_vout->chroma.p_module );    }    /* Destroy all remaining pictures */    for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES + 1; i_index++ )    {        if ( p_vout->p_picture[i_index].i_type == MEMORY_PICTURE )        {            free( p_vout->p_picture[i_index].p_data_orig );        }    }    /* Destroy subpicture unit */    spu_Attach( p_vout->p_spu, VLC_OBJECT(p_vout), VLC_FALSE );    spu_Destroy( p_vout->p_spu );    /* Destroy translation tables */    p_vout->pf_end( p_vout );    /* Release the change lock */    vlc_mutex_unlock( &p_vout->change_lock );}/***************************************************************************** * DestroyThread: thread destruction ***************************************************************************** * This function is called when the thread ends. It frees all ressources * allocated by CreateThread. Status is available at this stage. *****************************************************************************/static void DestroyThread( vout_thread_t *p_vout ){    /* Destroy the locks */    vlc_mutex_destroy( &p_vout->picture_lock );    vlc_mutex_destroy( &p_vout->change_lock );    /* Release the module */    if( p_vout && p_vout->p_module )    {        module_Unneed( p_vout, p_vout->p_module );    }}/* 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;}/***************************************************************************** * BinaryLog: computes the base 2 log of a binary value ***************************************************************************** * This functions is used by MaskToShift, to get a bit index from a binary * value. *****************************************************************************/static int BinaryLog( uint32_t i ){    int i_log = 0;    if( i == 0 ) return -31337;    if( i & 0xffff0000 ) i_log += 16;    if( i & 0xff00ff00 ) i_log += 8;    if( i & 0xf0f0f0f0 ) i_log += 4;    if( i & 0xcccccccc ) i_log += 2;    if( i & 0xaaaaaaaa ) i_log += 1;    return i_log;}/***************************************************************************** * MaskToShift: transform a color mask into right and left shifts ***************************************************************************** * This function is used for obtaining color shifts from masks. *****************************************************************************/static void MaskToShift( int *pi_left, int *pi_right, uint32_t i_mask ){    uint32_t i_low, i_high;            /* lower hand higher bits of the mask */    if( !i_mask )    {        *pi_left = *pi_right = 0;        return;    }    /* Get bits */    i_low =  i_mask & (- (int32_t)i_mask);          /* lower bit of the mask */    i_high = i_mask + i_low;                       /* higher bit of the mask */    /* Transform bits into an index */    i_low =  BinaryLog (i_low);    i_high = BinaryLog (i_high);    /* Update pointers and return */    *pi_left =   i_low;    *pi_right = (8 - i_high + i_low);}/***************************************************************************** * InitWindowSize: find the initial dimensions the video window should have. ***************************************************************************** * This function will check the "width", "height" and "zoom" config options and * will calculate the size that the video window should have. *****************************************************************************/static void InitWindowSize( vout_thread_t *p_vout, int *pi_width,                            int *pi_height ){    vlc_value_t val;    int i_width, i_height;    uint64_t ll_zoom;#define FP_FACTOR 1000                             /* our fixed point factor */    var_Get( p_vout, "align", &val );    p_vout->i_alignment = val.i_int;    var_Get( p_vout, "width", &val );    i_width = val.i_int;    var_Get( p_vout, "height", &val );    i_height = val.i_int;    var_Get( p_vout, "zoom", &val );    ll_zoom = (uint64_t)( FP_FACTOR * val.f_float );    if( i_width > 0 && i_height > 0)    {        *pi_width = (int)( i_width * ll_zoom / FP_FACTOR );        *pi_height = (int)( i_height * ll_zoom / FP_FACTOR );        return;    }    else if( i_width > 0 )    {        *pi_width = (int)( i_width * ll_zoom / FP_FACTOR );        *pi_height = (int)( i_width * ll_zoom * VOUT_ASPECT_FACTOR /                            p_vout->render.i_aspect / FP_FACTOR );        return;    }    else if( i_height > 0 )    {        *pi_height = (int)( i_height * ll_zoom / FP_FACTOR );        *pi_width = (int)( i_height * ll_zoom * p_vout->render.i_aspect /                           VOUT_ASPECT_FACTOR / FP_FACTOR );        return;    }    if( p_vout->render.i_height * p_vout->render.i_aspect        >= p_vout->render.i_width * VOUT_ASPECT_FACTOR )    {        *pi_width = (int)( p_vout->render.i_height * ll_zoom          * p_vout->render.i_aspect / VOUT_ASPECT_FACTOR / FP_FACTOR );        *pi_height = (int)( p_vout->render.i_height * ll_zoom / FP_FACTOR );    }    else    {        *pi_width = (int)( p_vout->render.i_width * ll_zoom / FP_FACTOR );        *pi_height = (int)( p_vout->render.i_width * ll_zoom          * VOUT_ASPECT_FACTOR / p_vout->render.i_aspect / FP_FACTOR );    }#undef FP_FACTOR}/***************************************************************************** * vout_VarCallback: generic callback for intf variables *****************************************************************************/int vout_VarCallback( vlc_object_t * p_this, const char * psz_variable,                      vlc_value_t old_value, vlc_value_t new_value,                      void * unused ){    vout_thread_t * p_vout = (vout_thread_t *)p_this;    vlc_value_t val;    val.b_bool = VLC_TRUE;    var_Set( p_vout, "intf-change", val );    return VLC_SUCCESS;}/***************************************************************************** * 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( suxor_thread_t *p_this ){    vlc_value_t val;    vlc_thread_ready( p_this );    /* Now restart current video stream */    var_Get( p_this->p_input, "video-es", &val );    if( val.i_int >= 0 )    {        vlc_value_t val_es;        val_es.i_int = -VIDEO_ES;        var_Set( p_this->p_input, "video-es", val_es );        var_Set( p_this->p_input, "video-es", val );    }    vlc_object_release( p_this->p_input );#ifdef WIN32    CloseHandle( p_this->thread_id );#endif    vlc_object_destroy( p_this );}/***************************************************************************** * 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;    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 = VLC_TRUE;    var_Set( p_vout, "intf-change", val );    val.psz_string = psz_filter;    var_Set( p_vout, "vout-filter", val );    if( psz_filter ) 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;    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 = VLC_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 )    {        suxor_thread_t *p_suxor =            vlc_object_create( p_vout, sizeof(suxor_thread_t) );        p_suxor->p_input = p_input;        p_vout->b_filter_change = VLC_TRUE;        vlc_object_yield( p_input );        vlc_thread_create( p_suxor, "suxor", SuxorRestartVideoES,                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE );    }    vlc_object_release( p_input );    return VLC_SUCCESS;}

⌨️ 快捷键说明

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