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

📄 dvdnav.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        if( b_button_ok )        {            int i;            for( i = 0; i < 4; i++ )            {                uint32_t i_yuv = p_sys->clut[(hl.palette>>(16+i*4))&0x0f];                uint8_t i_alpha = ( (hl.palette>>(i*4))&0x0f ) * 0xff / 0xf;                p_sys->palette[i][0] = (i_yuv >> 16) & 0xff;                p_sys->palette[i][1] = (i_yuv >> 0) & 0xff;                p_sys->palette[i][2] = (i_yuv >> 8) & 0xff;                p_sys->palette[i][3] = i_alpha;            }            vlc_mutex_lock( p_mutex );            val.i_int = hl.sx; var_Set( p_sys->p_input, "x-start", val );            val.i_int = hl.ex; var_Set( p_sys->p_input, "x-end", val );            val.i_int = hl.sy; var_Set( p_sys->p_input, "y-start", val );            val.i_int = hl.ey; var_Set( p_sys->p_input, "y-end", val );            val.p_address = (void *)p_sys->palette;            var_Set( p_sys->p_input, "menu-palette", val );            val.b_bool = true; var_Set( p_sys->p_input, "highlight", val );            vlc_mutex_unlock( p_mutex );            msg_Dbg( p_demux, "buttonUpdate %d", i_button );        }        else        {            msg_Dbg( p_demux, "buttonUpdate not done b=%d t=%d",                     i_button, i_title );            /* Show all */            vlc_mutex_lock( p_mutex );            val.b_bool = false;            var_Set( p_sys->p_input, "highlight", val );            vlc_mutex_unlock( p_mutex );        }    }}static void ESSubtitleUpdate( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    int         i_spu = dvdnav_get_active_spu_stream( p_sys->dvdnav );    int32_t i_title, i_part;    ButtonUpdate( p_demux, false );    dvdnav_current_title_info( p_sys->dvdnav, &i_title, &i_part );    if( i_title > 0 ) return;    if( i_spu >= 0 && i_spu <= 0x1f )    {        ps_track_t *tk = &p_sys->tk[PS_ID_TO_TK(0xbd20 + i_spu)];        ESNew( p_demux, 0xbd20 + i_spu );        /* be sure to unselect it (reset) */        es_out_Control( p_demux->out, ES_OUT_SET_ES_STATE, tk->es,                        (bool)false );        /* now select it */        es_out_Control( p_demux->out, ES_OUT_SET_ES, tk->es );    }    else    {        for( i_spu = 0; i_spu <= 0x1F; i_spu++ )        {            ps_track_t *tk = &p_sys->tk[PS_ID_TO_TK(0xbd20 + i_spu)];            if( tk->b_seen )            {                es_out_Control( p_demux->out, ES_OUT_SET_ES_STATE, tk->es,                                (bool)false );            }        }    }}/***************************************************************************** * DemuxBlock: demux a given block *****************************************************************************/static int DemuxBlock( demux_t *p_demux, const uint8_t *pkt, int i_pkt ){    demux_sys_t *p_sys = p_demux->p_sys;    const uint8_t     *p = pkt;    while( p < &pkt[i_pkt] )    {        int i_size = ps_pkt_size( p, &pkt[i_pkt] - p );        block_t *p_pkt;        if( i_size <= 0 )        {            break;        }        /* Create a block */        p_pkt = block_New( p_demux, i_size );        memcpy( p_pkt->p_buffer, p, i_size);        /* Parse it and send it */        switch( 0x100 | p[3] )        {        case 0x1b9:        case 0x1bb:        case 0x1bc:#ifdef DVDNAV_DEBUG            if( p[3] == 0xbc )            {                msg_Warn( p_demux, "received a PSM packet" );            }            else if( p[3] == 0xbb )            {                msg_Warn( p_demux, "received a SYSTEM packet" );            }#endif            block_Release( p_pkt );            break;        case 0x1ba:        {            int64_t i_scr;            int i_mux_rate;            if( !ps_pkt_parse_pack( p_pkt, &i_scr, &i_mux_rate ) )            {                es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_scr );                if( i_mux_rate > 0 ) p_sys->i_mux_rate = i_mux_rate;            }            block_Release( p_pkt );            break;        }        default:        {            int i_id = ps_pkt_id( p_pkt );            if( i_id >= 0xc0 )            {                ps_track_t *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];                if( !tk->b_seen )                {                    ESNew( p_demux, i_id );                }                if( tk->b_seen && tk->es &&                    !ps_pkt_parse_pes( p_pkt, tk->i_skip ) )                {                    es_out_Send( p_demux->out, tk->es, p_pkt );                }                else                {                    block_Release( p_pkt );                }            }            else            {                block_Release( p_pkt );            }            break;        }        }        p += i_size;    }    return VLC_SUCCESS;}/***************************************************************************** * ESNew: register a new elementary stream *****************************************************************************/static void ESNew( demux_t *p_demux, int i_id ){    demux_sys_t *p_sys = p_demux->p_sys;    ps_track_t  *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];    bool  b_select = false;    if( tk->b_seen ) return;    if( ps_track_fill( tk, 0, i_id ) )    {        msg_Warn( p_demux, "unknown codec for id=0x%x", i_id );        return;    }    /* Add a new ES */    if( tk->fmt.i_cat == VIDEO_ES )    {        switch( p_sys->i_aspect )        {        case 1: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR; break;        case 2: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 4 / 3; break;        case 3: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 16 / 9; break;        case 4: tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * 221 / 10; break;        default:            tk->fmt.video.i_aspect = 0;            break;        }        b_select = true;    }    else if( tk->fmt.i_cat == AUDIO_ES )    {        int i_audio = -1;        /* find the audio number PLEASE find another way */        if( (i_id&0xbdf8) == 0xbd88 )       /* dts */        {            i_audio = i_id&0x07;        }        else if( (i_id&0xbdf0) == 0xbd80 )  /* a52 */        {            i_audio = i_id&0xf;        }        else if( (i_id&0xbdf0) == 0xbda0 )  /* lpcm */        {            i_audio = i_id&0x1f;        }        else if( ( i_id&0xe0 ) == 0xc0 )    /* mpga */        {            i_audio = i_id&0x1f;        }        if( i_audio >= 0 )        {            int i_lang = dvdnav_audio_stream_to_lang( p_sys->dvdnav, i_audio );            if( i_lang != 0xffff )            {                tk->fmt.psz_language = malloc( 3 );                tk->fmt.psz_language[0] = (i_lang >> 8)&0xff;                tk->fmt.psz_language[1] = (i_lang     )&0xff;                tk->fmt.psz_language[2] = 0;            }            if( dvdnav_get_active_audio_stream( p_sys->dvdnav ) == i_audio )            {                b_select = true;            }        }    }    else if( tk->fmt.i_cat == SPU_ES )    {        int32_t i_title, i_part;        int i_lang = dvdnav_spu_stream_to_lang( p_sys->dvdnav, i_id&0x1f );        if( i_lang != 0xffff )        {            tk->fmt.psz_language = malloc( 3 );            tk->fmt.psz_language[0] = (i_lang >> 8)&0xff;            tk->fmt.psz_language[1] = (i_lang     )&0xff;            tk->fmt.psz_language[2] = 0;        }        /* Palette */        tk->fmt.subs.spu.palette[0] = 0xBeef;        memcpy( &tk->fmt.subs.spu.palette[1], p_sys->clut,                16 * sizeof( uint32_t ) );        /* We select only when we are not in the menu */        dvdnav_current_title_info( p_sys->dvdnav, &i_title, &i_part );        if( i_title > 0 &&            dvdnav_get_active_spu_stream( p_sys->dvdnav ) == (i_id&0x1f) )        {            b_select = true;        }    }    tk->es = es_out_Add( p_demux->out, &tk->fmt );    if( b_select )    {        es_out_Control( p_demux->out, ES_OUT_SET_ES, tk->es );    }    tk->b_seen = true;    if( tk->fmt.i_cat == VIDEO_ES ) ButtonUpdate( p_demux, false );}/***************************************************************************** * Event handler code *****************************************************************************/static int  EventMouse( vlc_object_t *, char const *,                        vlc_value_t, vlc_value_t, void * );static int  EventKey  ( vlc_object_t *, char const *,                        vlc_value_t, vlc_value_t, void * );static void* EventThread( vlc_object_t *p_this ){    event_thread_t *p_ev = (event_thread_t*)p_this;    demux_sys_t    *p_sys = p_ev->p_demux->p_sys;    vlc_object_t   *p_vout = NULL;    vlc_mutex_init( &p_ev->lock );    p_ev->b_moved   = false;    p_ev->b_clicked = false;    p_ev->i_key_action = 0;    p_ev->b_still   = false;    /* catch all key event */    var_AddCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev );    /* main loop */    while( vlc_object_alive (p_ev) )    {        bool b_activated = false;        /* KEY part */        if( p_ev->i_key_action != 0 )        {            pci_t *pci = dvdnav_get_current_nav_pci( p_sys->dvdnav );            vlc_mutex_lock( &p_ev->lock );            switch( p_ev->i_key_action )            {            case ACTIONID_NAV_LEFT:                dvdnav_left_button_select( p_sys->dvdnav, pci );                break;            case ACTIONID_NAV_RIGHT:                dvdnav_right_button_select( p_sys->dvdnav, pci );                break;            case ACTIONID_NAV_UP:                dvdnav_upper_button_select( p_sys->dvdnav, pci );                break;            case ACTIONID_NAV_DOWN:                dvdnav_lower_button_select( p_sys->dvdnav, pci );                break;            case ACTIONID_NAV_ACTIVATE:                b_activated = true;                ButtonUpdate( p_ev->p_demux, true );                dvdnav_button_activate( p_sys->dvdnav, pci );                break;            default:                break;            }            p_ev->i_key_action = 0;            vlc_mutex_unlock( &p_ev->lock );        }        /* VOUT part */        if( p_vout && ( p_ev->b_moved || p_ev->b_clicked ) )        {            pci_t *pci = dvdnav_get_current_nav_pci( p_sys->dvdnav );            vlc_value_t valx, valy;            vlc_mutex_lock( &p_ev->lock );            var_Get( p_vout, "mouse-x", &valx );            var_Get( p_vout, "mouse-y", &valy );            if( p_ev->b_moved )            {                dvdnav_mouse_select( p_sys->dvdnav, pci, valx.i_int,                                     valy.i_int );            }            if( p_ev->b_clicked )            {                b_activated = true;                ButtonUpdate( p_ev->p_demux, true );                dvdnav_mouse_activate( p_sys->dvdnav, pci, valx.i_int,                                       valy.i_int );            }            p_ev->b_moved = false;            p_ev->b_clicked = false;            vlc_mutex_unlock( &p_ev->lock );        }        if( p_vout && !vlc_object_alive (p_vout) )        {            var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev );            var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev );            vlc_object_release( p_vout );            p_vout = NULL;        }        if( p_vout == NULL )        {            p_vout = vlc_object_find( p_sys->p_input, VLC_OBJECT_VOUT,                                      FIND_CHILD );            if( p_vout)            {                var_AddCallback( p_vout, "mouse-moved", EventMouse, p_ev );                var_AddCallback( p_vout, "mouse-clicked", EventMouse, p_ev );            }        }        /* Still part */        vlc_mutex_lock( &p_ev->lock );        if( p_ev->b_still )        {            if( /* b_activated || // This breaks menus */                ( p_ev->i_still_end > 0 && p_ev->i_still_end < mdate() ))            {                p_ev->b_still = false;                dvdnav_still_skip( p_sys->dvdnav );            }        }        vlc_mutex_unlock( &p_ev->lock );        /* Wait a bit */        msleep( 10000 );    }    /* Release callback */    if( p_vout )    {        var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev );        var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev );        vlc_object_release( p_vout );    }    var_DelCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev );    vlc_mutex_destroy( &p_ev->lock );    return NULL;}static int EventMouse( vlc_object_t *p_this, char const *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    (void)p_this;    (void)oldval;    (void)newval;    (void)p_data;    event_thread_t *p_ev = p_data;    vlc_mutex_lock( &p_ev->lock );    if( psz_var[6] == 'c' )        p_ev->b_clicked = true;    else if( psz_var[6] == 'm' )        p_ev->b_moved = true;    vlc_mutex_unlock( &p_ev->lock );    return VLC_SUCCESS;}static int EventKey( vlc_object_t *p_this, char const *psz_var,                     vlc_value_t oldval, vlc_value_t newval, void *p_data ){    (void)p_this;    (void)psz_var;    (void)oldval;    event_thread_t *p_ev = p_data;    vlc_mutex_lock( &p_ev->lock );    p_ev->i_key_action = newval.i_int;    vlc_mutex_unlock( &p_ev->lock );    return VLC_SUCCESS;}/***************************************************************************** * ProbeDVD: very weak probing that avoids going too often into a dvdnav_open() *****************************************************************************/static int ProbeDVD( demux_t *p_demux, char *psz_name ){    (void)p_demux;#ifdef HAVE_SYS_STAT_H    struct stat stat_info;    uint8_t pi_anchor[2];    uint16_t i_tag_id = 0;    int i_fd, i_ret;    if( !*psz_name )    {        /* Triggers libdvdcss autodetection */        return VLC_SUCCESS;    }    if( utf8_stat( psz_name, &stat_info ) || !S_ISREG( stat_info.st_mode ) )    {        /* Let dvdnav_open() do the probing */        return VLC_SUCCESS;    }    if( (i_fd = open( psz_name, O_RDONLY )) == -1 )    {        /* Let dvdnav_open() do the probing */        return VLC_SUCCESS;    }    /* Try to find the anchor (2 bytes at LBA 256) */    i_ret = VLC_SUCCESS;    if( lseek( i_fd, 256 * DVD_VIDEO_LB_LEN, SEEK_SET ) == -1 )    {        i_ret = VLC_EGENERIC;    }    if( read( i_fd, pi_anchor, 2 ) == 2 )    {        i_tag_id = GetWLE(pi_anchor);        if( i_tag_id != 2 ) i_ret = VLC_EGENERIC; /* Not an anchor */    }    else    {        i_ret = VLC_EGENERIC;    }    close( i_fd );    return i_ret;#else    return VLC_SUCCESS;#endif}

⌨️ 快捷键说明

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