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

📄 mkv.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {        if ( i_current_edition >= 0 && size_t(i_current_edition) < p_editions->size() )            return (*p_editions)[i_current_edition];        return NULL;    }    matroska_segment_c * Segment() const    {        if ( linked_segments.size() == 0 || i_current_segment >= linked_segments.size() )            return NULL;        return linked_segments[i_current_segment];    }    inline chapter_item_c *CurrentChapter() {        return psz_current_chapter;    }    bool SelectNext()    {        if ( i_current_segment < linked_segments.size()-1 )        {            i_current_segment++;            return true;        }        return false;    }    bool FindUID( KaxSegmentUID & uid ) const    {        for ( size_t i=0; i<linked_uids.size(); i++ )        {            if ( linked_uids[i] == uid )                return true;        }        return false;    }    bool UpdateCurrentToChapter( demux_t & demux );    void PrepareChapters( );    chapter_item_c *BrowseCodecPrivate( unsigned int codec_id,                                        bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),                                        const void *p_cookie,                                        size_t i_cookie_size );    chapter_item_c *FindChapter( int64_t i_find_uid );    std::vector<chapter_edition_c*>  *p_editions;    int                              i_sys_title;protected:    std::vector<matroska_segment_c*> linked_segments;    std::vector<KaxSegmentUID>       linked_uids;    size_t                           i_current_segment;    int                              i_current_edition;    chapter_item_c                   *psz_current_chapter;    void                             AppendUID( const EbmlBinary * UID );};class matroska_stream_c{public:    matroska_stream_c( demux_sys_t & demuxer )        :p_in(NULL)        ,p_es(NULL)        ,sys(demuxer)    {}    virtual ~matroska_stream_c()    {        delete p_in;        delete p_es;    }    IOCallback         *p_in;    EbmlStream         *p_es;    std::vector<matroska_segment_c*> segments;    demux_sys_t                      & sys;};typedef struct{    VLC_COMMON_MEMBERS    demux_t        *p_demux;    vlc_mutex_t     lock;    bool            b_moved;    bool            b_clicked;    int             i_key_action;} event_thread_t;class attachment_c{public:    attachment_c()        :p_data(NULL)        ,i_size(0)    {}    virtual ~attachment_c()    {        free( p_data );    }    std::string    psz_file_name;    std::string    psz_mime_type;    void          *p_data;    int            i_size;};class demux_sys_t{public:    demux_sys_t( demux_t & demux )        :demuxer(demux)        ,i_pts(0)        ,i_start_pts(0)        ,i_chapter_time(0)        ,meta(NULL)        ,i_current_title(0)        ,p_current_segment(NULL)        ,dvd_interpretor( *this )        ,f_duration(-1.0)        ,b_ui_hooked(false)        ,p_input(NULL)        ,b_pci_packet_set(false)        ,p_ev(NULL)    {        vlc_mutex_init( &lock_demuxer );    }    virtual ~demux_sys_t()    {        StopUiThread();        size_t i;        for ( i=0; i<streams.size(); i++ )            delete streams[i];        for ( i=0; i<opened_segments.size(); i++ )            delete opened_segments[i];        for ( i=0; i<used_segments.size(); i++ )            delete used_segments[i];        for ( i=0; i<stored_attachments.size(); i++ )            delete stored_attachments[i];        if( meta ) vlc_meta_Delete( meta );        while( titles.size() )        { vlc_input_title_Delete( titles.back() ); titles.pop_back();}        vlc_mutex_destroy( &lock_demuxer );    }    /* current data */    demux_t                 & demuxer;    mtime_t                 i_pts;    mtime_t                 i_start_pts;    mtime_t                 i_chapter_time;    vlc_meta_t              *meta;    std::vector<input_title_t*>      titles; // matroska editions    size_t                           i_current_title;    std::vector<matroska_stream_c*>  streams;    std::vector<attachment_c*>       stored_attachments;    std::vector<matroska_segment_c*> opened_segments;    std::vector<virtual_segment_c*>  used_segments;    virtual_segment_c                *p_current_segment;    dvd_command_interpretor_c        dvd_interpretor;    /* duration of the stream */    float                   f_duration;    matroska_segment_c *FindSegment( const EbmlBinary & uid ) const;    chapter_item_c *BrowseCodecPrivate( unsigned int codec_id,                                        bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),                                        const void *p_cookie,                                        size_t i_cookie_size,                                        virtual_segment_c * & p_segment_found );    chapter_item_c *FindChapter( int64_t i_find_uid, virtual_segment_c * & p_segment_found );    void PreloadFamily( const matroska_segment_c & of_segment );    void PreloadLinked( matroska_segment_c *p_segment );    bool PreparePlayback( virtual_segment_c *p_new_segment );    matroska_stream_c *AnalyseAllSegmentsFound( demux_t *p_demux, EbmlStream *p_estream, bool b_initial = false );    void JumpTo( virtual_segment_c & p_segment, chapter_item_c * p_chapter );    void StartUiThread();    void StopUiThread();    bool b_ui_hooked;    inline void SwapButtons();    /* for spu variables */    input_thread_t *p_input;    pci_t          pci_packet;    bool           b_pci_packet_set;    uint8_t        palette[4][4];    vlc_mutex_t    lock_demuxer;    /* event */    event_thread_t *p_ev;    static void * EventThread( vlc_object_t *p_this );    static int EventMouse( vlc_object_t *p_this, char const *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *p_data );    static int EventKey( vlc_object_t *p_this, char const *psz_var,                     vlc_value_t oldval, vlc_value_t newval, void *p_data );protected:    virtual_segment_c *VirtualFromSegments( matroska_segment_c *p_segment ) const;    bool IsUsedSegment( matroska_segment_c &p_segment ) const;};static int  Demux  ( demux_t * );static int  Control( demux_t *, int, va_list );static void Seek   ( demux_t *, mtime_t i_date, double f_percent, chapter_item_c *psz_chapter );#define MKV_IS_ID( el, C ) ( EbmlId( (*el) ) == C::ClassInfos.GlobalId )static inline char * ToUTF8( const UTFstring &u ){    return strdup( u.GetUTF8().c_str() );}/***************************************************************************** * Open: initializes matroska demux structures *****************************************************************************/static int Open( vlc_object_t * p_this ){    demux_t            *p_demux = (demux_t*)p_this;    demux_sys_t        *p_sys;    matroska_stream_c  *p_stream;    matroska_segment_c *p_segment;    const uint8_t      *p_peek;    std::string         s_path, s_filename;    vlc_stream_io_callback *p_io_callback;    EbmlStream         *p_io_stream;    /* peek the begining */    if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;    /* is a valid file */    if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||        p_peek[2] != 0xdf || p_peek[3] != 0xa3 ) return VLC_EGENERIC;    /* Set the demux function */    p_demux->pf_demux   = Demux;    p_demux->pf_control = Control;    p_demux->p_sys      = p_sys = new demux_sys_t( *p_demux );    p_io_callback = new vlc_stream_io_callback( p_demux->s, false );    p_io_stream = new EbmlStream( *p_io_callback );    if( p_io_stream == NULL )    {        msg_Err( p_demux, "failed to create EbmlStream" );        delete p_io_callback;        delete p_sys;        return VLC_EGENERIC;    }    p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_io_stream, true );    if( p_stream == NULL )    {        msg_Err( p_demux, "cannot find KaxSegment" );        goto error;    }    p_sys->streams.push_back( p_stream );    p_stream->p_in = p_io_callback;    p_stream->p_es = p_io_stream;    for (size_t i=0; i<p_stream->segments.size(); i++)    {        p_stream->segments[i]->Preload();    }    p_segment = p_stream->segments[0];    if( p_segment->cluster == NULL )    {        msg_Err( p_demux, "cannot find any cluster, damaged file ?" );        goto error;    }    if (config_GetInt( p_demux, "mkv-preload-local-dir" ))    {        /* get the files from the same dir from the same family (based on p_demux->psz_path) */        if (p_demux->psz_path[0] != '\0' && !strcmp(p_demux->psz_access, ""))        {            // assume it's a regular file            // get the directory path            s_path = p_demux->psz_path;            if (s_path.at(s_path.length() - 1) == DIRECTORY_SEPARATOR)            {                s_path = s_path.substr(0,s_path.length()-1);            }            else            {                if (s_path.find_last_of(DIRECTORY_SEPARATOR) > 0)                {                    s_path = s_path.substr(0,s_path.find_last_of(DIRECTORY_SEPARATOR));                }            }            DIR *p_src_dir = utf8_opendir(s_path.c_str());            if (p_src_dir != NULL)            {                char *psz_file;                while ((psz_file = utf8_readdir(p_src_dir)) != NULL)                {                    if (strlen(psz_file) > 4)                    {                        s_filename = s_path + DIRECTORY_SEPARATOR + psz_file;#ifdef WIN32                        if (!strcasecmp(s_filename.c_str(), p_demux->psz_path))#else                        if (!s_filename.compare(p_demux->psz_path))#endif                        {                            free (psz_file);                            continue; // don't reuse the original opened file                        }#if defined(__GNUC__) && (__GNUC__ < 3)                        if (!s_filename.compare("mkv", s_filename.length() - 3, 3) ||                            !s_filename.compare("mka", s_filename.length() - 3, 3))#else                        if (!s_filename.compare(s_filename.length() - 3, 3, "mkv") ||                            !s_filename.compare(s_filename.length() - 3, 3, "mka"))#endif                        {                            // test wether this file belongs to our family                            const uint8_t *p_peek;                            bool          file_ok = false;                            stream_t      *p_file_stream = stream_UrlNew(                                                            p_demux,                                                            s_filename.c_str());                            /* peek the begining */                            if( p_file_stream &&                                stream_Peek( p_file_stream, &p_peek, 4 ) >= 4                                && p_peek[0] == 0x1a && p_peek[1] == 0x45 &&                                p_peek[2] == 0xdf && p_peek[3] == 0xa3 ) file_ok = true;                            if ( file_ok )                            {                                vlc_stream_io_callback *p_file_io = new vlc_stream_io_callback( p_file_stream, true );                                EbmlStream *p_estream = new EbmlStream(*p_file_io);                                p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_estream );                                if ( p_stream == NULL )                                {                                    msg_Dbg( p_demux, "the file '%s' will not be used", s_filename.c_str() );                                    delete p_estream;                                    delete p_file_io;                                }                                else                                {                                    p_stream->p_in = p_file_io;                                    p_stream->p_es = p_estream;                                    p_sys->streams.push_back( p_stream );                                }                            }                            else                            {                                if( p_file_stream ) {                                    stream_Delete( p_file_stream );                                }                                msg_Dbg( p_demux, "the file '%s' cannot be opened", s_filename.c_str() );                            }                        }                    }                    free (psz_file);                }                closedir( p_src_dir );            }        }        p_sys->PreloadFamily( *p_segment );    }    p_sys->PreloadLinked( p_segment );    if ( !p_sys->PreparePlayback( NULL ) )    {        msg_Err( p_demux, "cannot use the segment" );        goto error;    }    p_sys->StartUiThread();     return VLC_SUCCESS;

⌨️ 快捷键说明

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