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

📄 dvdnav.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            {                msg_Warn( p_demux, "cannot set title/chapter" );                return VLC_EGENERIC;            }            p_demux->info.i_update |=                INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_title = i;            p_demux->info.i_seekpoint = 0;            return VLC_SUCCESS;        case DEMUX_SET_SEEKPOINT:            i = (int)va_arg( args, int );            if( p_demux->info.i_title == 0 )            {                int i_ret;                /* Special case */                switch( i )                {                case 0:                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Escape );                    break;                case 1:                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Root );                    break;                case 2:                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Title );                    break;                case 3:                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Part );                    break;                case 4:                    i_ret = dvdnav_menu_call( p_sys->dvdnav,                                              DVD_MENU_Subpicture );                    break;                case 5:                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Audio );                    break;                case 6:                    i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Angle );                    break;                default:                    return VLC_EGENERIC;                }                if( i_ret != DVDNAV_STATUS_OK )                    return VLC_EGENERIC;            }            else if( dvdnav_part_play( p_sys->dvdnav, p_demux->info.i_title,                                       i + 1 ) != DVDNAV_STATUS_OK )            {                msg_Warn( p_demux, "cannot set title/chapter" );                return VLC_EGENERIC;            }            p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_seekpoint = i;            return VLC_SUCCESS;        case DEMUX_GET_PTS_DELAY:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = (int64_t)var_GetInteger( p_demux, "dvdnav-caching" ) *1000;            return VLC_SUCCESS;        case DEMUX_GET_META:        {            const char *title_name = NULL;            dvdnav_get_title_string(p_sys->dvdnav, &title_name);            if( (NULL != title_name) && ('\0' != title_name[0]) )            {                vlc_meta_t *p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );                vlc_meta_Set( p_meta, vlc_meta_Title, title_name );                return VLC_SUCCESS;            }            return VLC_EGENERIC;        }        /* TODO implement others */        default:            return VLC_EGENERIC;    }}static int ControlInternal( demux_t *p_demux, int i_query, ... ){    va_list args;    int     i_result;    va_start( args, i_query );    i_result = Control( p_demux, i_query, args );    va_end( args );    return i_result;}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    uint8_t buffer[DVD_VIDEO_LB_LEN];    uint8_t *packet = buffer;    int i_event;    int i_len;#if DVD_READ_CACHE    if( dvdnav_get_next_cache_block( p_sys->dvdnav, &packet, &i_event, &i_len )        == DVDNAV_STATUS_ERR )#else    if( dvdnav_get_next_block( p_sys->dvdnav, packet, &i_event, &i_len )        == DVDNAV_STATUS_ERR )#endif    {        msg_Warn( p_demux, "cannot get next block (%s)",                  dvdnav_err_to_string( p_sys->dvdnav ) );        if( p_demux->info.i_title == 0 )        {            msg_Dbg( p_demux, "jumping to first title" );            return ControlInternal( p_demux, DEMUX_SET_TITLE, 1 ) == VLC_SUCCESS ? 1 : -1;        }        return -1;    }    switch( i_event )    {    case DVDNAV_BLOCK_OK:   /* mpeg block */        DemuxBlock( p_demux, packet, i_len );        break;    case DVDNAV_NOP:    /* Nothing */        msg_Dbg( p_demux, "DVDNAV_NOP" );        break;    case DVDNAV_STILL_FRAME:    {        /* We send a dummy mpeg2 end of sequence to force still frame display */        static const uint8_t buffer[] = {            0x00, 0x00, 0x01, 0xe0, 0x00, 0x07,            0x80, 0x00, 0x00,            0x00, 0x00, 0x01, 0xB7,        };        DemuxBlock( p_demux, buffer, sizeof(buffer) );        /* */        dvdnav_still_event_t *event = (dvdnav_still_event_t*)packet;        vlc_mutex_lock( &p_sys->p_ev->lock );        if( !p_sys->p_ev->b_still )        {            msg_Dbg( p_demux, "DVDNAV_STILL_FRAME" );            msg_Dbg( p_demux, "     - length=0x%x", event->length );            p_sys->p_ev->b_still = true;            if( event->length == 0xff )            {                p_sys->p_ev->i_still_end = 0;            }            else            {                p_sys->p_ev->i_still_end = (int64_t)event->length *                    1000000 + mdate() + p_sys->p_input->i_pts_delay;            }        }        vlc_mutex_unlock( &p_sys->p_ev->lock );        msleep( 40000 );        break;    }    case DVDNAV_SPU_CLUT_CHANGE:    {        int i;        msg_Dbg( p_demux, "DVDNAV_SPU_CLUT_CHANGE" );        /* Update color lookup table (16 *uint32_t in packet) */        memcpy( p_sys->clut, packet, 16 * sizeof( uint32_t ) );        /* HACK to get the SPU tracks registered in the right order */        for( i = 0; i < 0x1f; i++ )        {            if( dvdnav_spu_stream_to_lang( p_sys->dvdnav, i ) != 0xffff )                ESNew( p_demux, 0xbd20 + i );        }        /* END HACK */        break;    }    case DVDNAV_SPU_STREAM_CHANGE:    {        dvdnav_spu_stream_change_event_t *event =            (dvdnav_spu_stream_change_event_t*)packet;        int i;        msg_Dbg( p_demux, "DVDNAV_SPU_STREAM_CHANGE" );        msg_Dbg( p_demux, "     - physical_wide=%d",                 event->physical_wide );        msg_Dbg( p_demux, "     - physical_letterbox=%d",                 event->physical_letterbox);        msg_Dbg( p_demux, "     - physical_pan_scan=%d",                 event->physical_pan_scan );        ESSubtitleUpdate( p_demux );        p_sys->b_spu_change = true;        /* HACK to get the SPU tracks registered in the right order */        for( i = 0; i < 0x1f; i++ )        {            if( dvdnav_spu_stream_to_lang( p_sys->dvdnav, i ) != 0xffff )                ESNew( p_demux, 0xbd20 + i );        }        /* END HACK */        break;    }    case DVDNAV_AUDIO_STREAM_CHANGE:    {        dvdnav_audio_stream_change_event_t *event =            (dvdnav_audio_stream_change_event_t*)packet;        msg_Dbg( p_demux, "DVDNAV_AUDIO_STREAM_CHANGE" );        msg_Dbg( p_demux, "     - physical=%d", event->physical );        /* TODO */        break;    }    case DVDNAV_VTS_CHANGE:    {        int32_t i_title = 0;        int32_t i_part  = 0;        int i;        dvdnav_vts_change_event_t *event = (dvdnav_vts_change_event_t*)packet;        msg_Dbg( p_demux, "DVDNAV_VTS_CHANGE" );        msg_Dbg( p_demux, "     - vtsN=%d", event->new_vtsN );        msg_Dbg( p_demux, "     - domain=%d", event->new_domain );        /* dvdnav_get_video_aspect / dvdnav_get_video_scale_permission */        /* TODO check if we always have VTS and CELL */        p_sys->i_aspect = dvdnav_get_video_aspect( p_sys->dvdnav );        /* reset PCR */        es_out_Control( p_demux->out, ES_OUT_RESET_PCR );        for( i = 0; i < PS_TK_COUNT; i++ )        {            ps_track_t *tk = &p_sys->tk[i];            if( tk->b_seen )            {                es_format_Clean( &tk->fmt );                if( tk->es ) es_out_Del( p_demux->out, tk->es );            }            tk->b_seen = false;        }        if( dvdnav_current_title_info( p_sys->dvdnav, &i_title,                                       &i_part ) == DVDNAV_STATUS_OK )        {            if( i_title >= 0 && i_title < p_sys->i_title &&                p_demux->info.i_title != i_title )            {                p_demux->info.i_update |= INPUT_UPDATE_TITLE;                p_demux->info.i_title = i_title;            }        }        break;    }    case DVDNAV_CELL_CHANGE:    {        int32_t i_title = 0;        int32_t i_part  = 0;        dvdnav_cell_change_event_t *event =            (dvdnav_cell_change_event_t*)packet;        msg_Dbg( p_demux, "DVDNAV_CELL_CHANGE" );        msg_Dbg( p_demux, "     - cellN=%d", event->cellN );        msg_Dbg( p_demux, "     - pgN=%d", event->pgN );        msg_Dbg( p_demux, "     - cell_length=%"PRId64, event->cell_length );        msg_Dbg( p_demux, "     - pg_length=%"PRId64, event->pg_length );        msg_Dbg( p_demux, "     - pgc_length=%"PRId64, event->pgc_length );        msg_Dbg( p_demux, "     - cell_start=%"PRId64, event->cell_start );        msg_Dbg( p_demux, "     - pg_start=%"PRId64, event->pg_start );        /* Store the lenght in time of the current PGC */        p_sys->i_pgc_length = event->pgc_length / 90 * 1000;        /* FIXME is it correct or there is better way to know chapter change */        if( dvdnav_current_title_info( p_sys->dvdnav, &i_title,                                       &i_part ) == DVDNAV_STATUS_OK )        {            if( i_title >= 0 && i_title < p_sys->i_title &&                i_part >= 1 && i_part <= p_sys->title[i_title]->i_seekpoint &&                p_demux->info.i_seekpoint != i_part - 1 )            {                p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;                p_demux->info.i_seekpoint = i_part - 1;            }        }        break;    }    case DVDNAV_NAV_PACKET:    {#ifdef DVDNAV_DEBUG        msg_Dbg( p_demux, "DVDNAV_NAV_PACKET" );#endif        /* A lot of thing to do here :         *  - handle packet         *  - fetch pts (for time display)         *  - ...         */        DemuxBlock( p_demux, packet, i_len );        if( p_sys->b_spu_change )        {            ButtonUpdate( p_demux, false );            p_sys->b_spu_change = false;        }        break;    }    case DVDNAV_STOP:   /* EOF */        msg_Dbg( p_demux, "DVDNAV_STOP" );#if DVD_READ_CACHE        dvdnav_free_cache_block( p_sys->dvdnav, packet );#endif        return 0;    case DVDNAV_HIGHLIGHT:    {        dvdnav_highlight_event_t *event = (dvdnav_highlight_event_t*)packet;        msg_Dbg( p_demux, "DVDNAV_HIGHLIGHT" );        msg_Dbg( p_demux, "     - display=%d", event->display );        msg_Dbg( p_demux, "     - buttonN=%d", event->buttonN );        ButtonUpdate( p_demux, false );        break;    }    case DVDNAV_HOP_CHANNEL:        msg_Dbg( p_demux, "DVDNAV_HOP_CHANNEL" );        /* We should try to flush all our internal buffer */        break;    case DVDNAV_WAIT:        msg_Dbg( p_demux, "DVDNAV_WAIT" );        /* reset PCR */        es_out_Control( p_demux->out, ES_OUT_RESET_PCR );        dvdnav_wait_skip( p_sys->dvdnav );        break;    default:        msg_Warn( p_demux, "Unknown event (0x%x)", i_event );        break;    }#if DVD_READ_CACHE    dvdnav_free_cache_block( p_sys->dvdnav, packet );#endif    return 1;}/* Get a 2 char code * FIXME: partiallyy duplicated from src/input/es_out.c */static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var ){    const iso639_lang_t *pl;    char *psz_lang;    char *p;    psz_lang = var_CreateGetString( p_demux, psz_var );    if( !psz_lang )        return strdup(LANGUAGE_DEFAULT);    /* XXX: we will use only the first value     * (and ignore other ones in case of a list) */    if( ( p = strchr( psz_lang, ',' ) ) )        *p = '\0';    for( pl = p_languages; pl->psz_iso639_1 != NULL; pl++ )    {        if( *psz_lang == '\0' )            continue;        if( !strcasecmp( pl->psz_eng_name, psz_lang ) ||            !strcasecmp( pl->psz_native_name, psz_lang ) ||            !strcasecmp( pl->psz_iso639_1, psz_lang ) ||            !strcasecmp( pl->psz_iso639_2T, psz_lang ) ||            !strcasecmp( pl->psz_iso639_2B, psz_lang ) )            break;    }    free( psz_lang );    if( pl->psz_iso639_1 != NULL )        return strdup( pl->psz_iso639_1 );    return strdup(LANGUAGE_DEFAULT);}static void DemuxTitles( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    input_title_t *t;    seekpoint_t *s;    int32_t i_titles;    int i;    /* Menu */    t = vlc_input_title_New();    t->b_menu = true;    t->psz_name = strdup( "DVD Menu" );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Resume" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Root" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Title" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Chapter" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Subtitle" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Audio" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    s = vlc_seekpoint_New();    s->psz_name = strdup( "Angle" );    TAB_APPEND( t->i_seekpoint, t->seekpoint, s );    TAB_APPEND( p_sys->i_title, p_sys->title, t );    /* Find out number of titles/chapters */    dvdnav_get_number_of_titles( p_sys->dvdnav, &i_titles );    for( i = 1; i <= i_titles; i++ )    {        int32_t i_chapters = 0;        int j;        dvdnav_get_number_of_parts( p_sys->dvdnav, i, &i_chapters );        t = vlc_input_title_New();        for( j = 0; j < __MAX( i_chapters, 1 ); j++ )        {            s = vlc_seekpoint_New();            TAB_APPEND( t->i_seekpoint, t->seekpoint, s );        }        TAB_APPEND( p_sys->i_title, p_sys->title, t );    }}/***************************************************************************** * Update functions: *****************************************************************************/static void ButtonUpdate( demux_t *p_demux, bool b_mode ){    demux_sys_t *p_sys = p_demux->p_sys;    vlc_value_t val;    int32_t i_title, i_part;    dvdnav_current_title_info( p_sys->dvdnav, &i_title, &i_part );    if( var_Get( p_sys->p_input, "highlight-mutex", &val ) == VLC_SUCCESS )    {        vlc_mutex_t *p_mutex = val.p_address;        dvdnav_highlight_area_t hl;        int32_t i_button;        bool    b_button_ok;        if( dvdnav_get_current_highlight( p_sys->dvdnav, &i_button )            != DVDNAV_STATUS_OK )        {            msg_Err( p_demux, "dvdnav_get_current_highlight failed" );            return;        }        b_button_ok = false;        if( i_button > 0 && i_title ==  0 )        {            pci_t *pci = dvdnav_get_current_nav_pci( p_sys->dvdnav );            b_button_ok = dvdnav_get_highlight_area( pci, i_button, b_mode, &hl ) == DVDNAV_STATUS_OK;        }

⌨️ 快捷键说明

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