2 /*****************************************************************************
3 * EbmlParser for the matroska demuxer
4 *****************************************************************************
5 * Copyright (C) 2003-2004 the VideoLAN team
8 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * Steve Lhomme <steve.lhomme@free.fr>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 #include "Ebml_parser.hpp"
27 #include "stream_io_callback.hpp"
29 /*****************************************************************************
31 *****************************************************************************/
32 EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux ) :
39 mi_remain_size[0] = el_start->GetSize();
40 memset( m_el, 0, 6 * sizeof( *m_el ) );
42 mb_dummy = var_InheritBool( p_demux, "mkv-use-dummy" );
45 EbmlParser::~EbmlParser( void )
54 for( int i = 1; i <= mi_level; i++ )
64 EbmlElement* EbmlParser::UnGet( uint64 i_block_pos, uint64 i_cluster_pos )
66 if ( mi_user_level > mi_level )
68 while ( mi_user_level != mi_level )
70 delete m_el[mi_user_level];
71 m_el[mi_user_level] = NULL;
76 /* Avoid data skip in BlockGet */
77 delete m_el[mi_level];
78 m_el[mi_level] = NULL;
82 if ( m_el[1] && m_el[1]->GetElementPosition() == i_cluster_pos )
84 m_es->I_O().setFilePointer( i_block_pos, seek_beginning );
89 // seek to the previous Cluster
90 m_es->I_O().setFilePointer( i_cluster_pos, seek_beginning );
95 delete m_el[mi_level];
96 m_el[mi_level] = NULL;
102 void EbmlParser::Up( void )
104 if( mi_user_level == mi_level )
106 fprintf( stderr,"MKV/Ebml Parser: Up cannot escape itself\n" );
112 void EbmlParser::Down( void )
118 void EbmlParser::Keep( void )
123 int EbmlParser::GetLevel( void ) const
125 return mi_user_level;
128 void EbmlParser::Reset( demux_t *p_demux )
130 while ( mi_level > 0)
132 delete m_el[mi_level];
133 m_el[mi_level] = NULL;
136 mi_user_level = mi_level = 1;
137 // a little faster and cleaner
138 m_es->I_O().setFilePointer( static_cast<KaxSegment*>(m_el[0])->GetGlobalPosition(0) );
139 mb_dummy = var_InheritBool( p_demux, "mkv-use-dummy" );
142 EbmlElement *EbmlParser::Get( void )
146 if( mi_user_level != mi_level )
152 EbmlElement *ret = m_got;
160 m_el[mi_level]->SkipData( *m_es, EBML_CONTEXT(m_el[mi_level]) );
163 if( MKV_IS_ID( m_el[mi_level], KaxBlockVirtual ) )
164 static_cast<KaxBlockVirtualWorkaround*>(m_el[mi_level])->Fix();
165 delete m_el[mi_level];
169 vlc_stream_io_callback & io_stream = (vlc_stream_io_callback &) m_es->I_O();
170 uint64 i_size = io_stream.toRead();
171 m_el[mi_level] = m_es->FindNextElement( EBML_CONTEXT(m_el[mi_level - 1]),
172 i_ulev, i_size, mb_dummy, 1 );
173 // mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
184 delete m_el[mi_level - 1];
185 m_got = m_el[mi_level -1] = m_el[mi_level];
186 m_el[mi_level] = NULL;
193 else if( m_el[mi_level] == NULL )
195 fprintf( stderr,"MKV/Ebml Parser: m_el[mi_level] == NULL\n" );
198 return m_el[mi_level];
201 bool EbmlParser::IsTopPresent( EbmlElement *el ) const
203 for( int i = 0; i < mi_level; i++ )
205 if( m_el[i] && m_el[i] == el )