2 /*****************************************************************************
3 * mkv.cpp : 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 *****************************************************************************/
25 #include "Ebml_parser.hpp"
27 /*****************************************************************************
29 *****************************************************************************/
30 EbmlParser::EbmlParser( EbmlStream
*es
, EbmlElement
*el_start
, demux_t
*p_demux
)
37 mi_remain_size
[0] = el_start
->GetSize();
39 for( i
= 1; i
< 6; i
++ )
46 mb_dummy
= config_GetInt( p_demux
, "mkv-use-dummy" );
49 EbmlParser::~EbmlParser( void )
53 for( i
= 1; i
< mi_level
; i
++ )
63 EbmlElement
* EbmlParser::UnGet( uint64 i_block_pos
, uint64 i_cluster_pos
)
65 if ( mi_user_level
> mi_level
)
67 while ( mi_user_level
!= mi_level
)
69 delete m_el
[mi_user_level
];
70 m_el
[mi_user_level
] = NULL
;
76 if ( m_el
[1]->GetElementPosition() == i_cluster_pos
)
78 m_es
->I_O().setFilePointer( i_block_pos
, seek_beginning
);
79 return (EbmlMaster
*) m_el
[1];
83 // seek to the previous Cluster
84 m_es
->I_O().setFilePointer( i_cluster_pos
, seek_beginning
);
87 delete m_el
[mi_level
];
88 m_el
[mi_level
] = NULL
;
93 void EbmlParser::Up( void )
95 if( mi_user_level
== mi_level
)
97 fprintf( stderr
," arrrrrrrrrrrrrg Up cannot escape itself\n" );
103 void EbmlParser::Down( void )
109 void EbmlParser::Keep( void )
114 int EbmlParser::GetLevel( void )
116 return mi_user_level
;
119 void EbmlParser::Reset( demux_t
*p_demux
)
121 while ( mi_level
> 0)
123 delete m_el
[mi_level
];
124 m_el
[mi_level
] = NULL
;
127 mi_user_level
= mi_level
= 1;
128 // a little faster and cleaner
129 m_es
->I_O().setFilePointer( static_cast<KaxSegment
*>(m_el
[0])->GetGlobalPosition(0) );
130 mb_dummy
= config_GetInt( p_demux
, "mkv-use-dummy" );
134 /* This function workarounds a bug in KaxBlockVirtual implementation */
135 class KaxBlockVirtualWorkaround
: public KaxBlockVirtual
140 if( Data
== DataBlock
)
141 SetBuffer( NULL
, 0 );
145 EbmlElement
*EbmlParser::Get( void )
149 if( mi_user_level
!= mi_level
)
155 EbmlElement
*ret
= m_got
;
163 m_el
[mi_level
]->SkipData( *m_es
, m_el
[mi_level
]->Generic().Context
);
166 if( MKV_IS_ID( m_el
[mi_level
], KaxBlockVirtual
) )
167 static_cast<KaxBlockVirtualWorkaround
*>(m_el
[mi_level
])->Fix();
168 delete m_el
[mi_level
];
173 m_el
[mi_level
] = m_es
->FindNextElement( m_el
[mi_level
- 1]->Generic().Context
, i_ulev
, 0xFFFFFFFFL
, mb_dummy
!= 0, 1 );
174 // mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
185 delete m_el
[mi_level
- 1];
186 m_got
= m_el
[mi_level
-1] = m_el
[mi_level
];
187 m_el
[mi_level
] = NULL
;
194 else if( m_el
[mi_level
] == NULL
)
196 fprintf( stderr
," m_el[mi_level] == NULL\n" );
199 return m_el
[mi_level
];
202 bool EbmlParser::IsTopPresent( EbmlElement
*el
)
204 for( int i
= 0; i
< mi_level
; i
++ )
206 if( m_el
[i
] && m_el
[i
] == el
)