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

📄 mkv.cpp

📁 uclinux 下的vlc播放器源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }    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;    vlc_bool_t      b_moved;    vlc_bool_t      b_clicked;    vlc_bool_t      b_key;} event_thread_t;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( &demuxer, &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];        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<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 int 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;    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, VLC_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_Warn( p_demux, "cannot find any cluster, damaged file ?" );        // reset the stream reading to the first cluster of the segment used        p_stream->p_in->setFilePointer( p_segment->cluster->GetElementPosition() );    }    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 = (DIR *)utf8_opendir(s_path.c_str());            if (p_src_dir != NULL)            {                const 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                            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                            stream_t *p_file_stream = stream_UrlNew( p_demux, s_filename.c_str());                            if ( p_file_stream != NULL )                            {                                vlc_stream_io_callback *p_file_io = new vlc_stream_io_callback( p_file_stream, VLC_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                            {                                msg_Dbg( p_demux, "the file '%s' cannot be opened", s_filename.c_str() );                            }                        }                    }                    LocaleFree (psz_file);                }                vlc_closedir_wrapper( 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;error:    delete p_sys;    return VLC_EGENERIC;}/***************************************************************************** * Close: frees unused data *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys   = p_demux->p_sys;    delete p_sys;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t        *p_sys = p_demux->p_sys;    int64_t     *pi64;    double      *pf, f;    int         i_skp;    size_t      i_idx;    vlc_meta_t **pp_meta;    switch( i_query )    {        case DEMUX_GET_META:            pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );            *pp_meta = vlc_meta_Duplicate( p_sys->meta );            return VLC_SUCCESS;        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->f_duration > 0.0 )            {                *pi64 = (int64_t)(p_sys->f_duration * 1000);                return VLC_SUCCESS;            }            return VLC_EGENERIC;        case DEMUX_GET_POSITION:            pf = (double*)va_arg( args, double * );            if ( p_sys->f_duration > 0.0 )                *pf = (double)(p_sys->i_pts >= p_sys->i_start_pts ? p_sys->i_pts : p_sys->i_start_pts ) / (1000.0 * p_sys->f_duration);            return VLC_SUCCESS;        case DEMUX_SET_POSITION:            f = (double)va_arg( args, double );            Seek( p_demux, -1, f, NULL );            return VLC_SUCCESS;

⌨️ 快捷键说明

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