[vlc-commits] demux:mkv: use parsers for Tags
Steve Lhomme
git at videolan.org
Wed Jan 3 11:17:40 CET 2018
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Jan 2 16:38:08 2018 +0100| [121b07c4bd284fa529a69a20b1709e3db71b4513] | committer: Jean-Baptiste Kempf
demux:mkv: use parsers for Tags
It's better to read them in memory than reinventing the wheel for seek/infinite
issues.
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=121b07c4bd284fa529a69a20b1709e3db71b4513
---
modules/demux/mkv/matroska_segment.cpp | 249 ++++++++++++++++-----------------
1 file changed, 121 insertions(+), 128 deletions(-)
diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index bd2fd7e7be..bd7cc3202c 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -267,69 +267,51 @@ static const struct {
bool matroska_segment_c::ParseSimpleTags( SimpleTag* pout_simple, KaxTagSimple *tag, int target_type )
{
- EbmlParser eparser ( &es, tag, &sys.demuxer, var_InheritBool( &sys.demuxer, "mkv-use-dummy" ) );
- EbmlElement *el;
- size_t max_size = tag->GetSize();
- size_t size = 0;
-
- if( !sys.meta )
- sys.meta = vlc_meta_New();
-
msg_Dbg( &sys.demuxer, "| + Simple Tag ");
- try
+ struct SimpleTagHandlerPayload
{
- while( ( el = eparser.Get() ) != NULL && size < max_size)
+ matroska_segment_c * const obj;
+ EbmlParser * const ep;
+ demux_sys_t & sys;
+ SimpleTag & out;
+ int target_type;
+ } payload = { this, ep, sys, *pout_simple, 50 };
+ MKV_SWITCH_CREATE( EbmlTypeDispatcher, SimpleTagHandler, SimpleTagHandlerPayload )
+ {
+ MKV_SWITCH_INIT();
+ E_CASE( KaxTagName, entry )
{
- if( unlikely( !el->ValidateSize() ) )
- {
- msg_Err( &sys.demuxer, "Error %s too big ignoring the tag", typeid(*el).name() );
- delete ep;
- return false;
- }
- if( MKV_CHECKED_PTR_DECL ( ktn_ptr, KaxTagName, el ) )
- {
- ktn_ptr->ReadData( es.I_O(), SCOPE_ALL_DATA );
- pout_simple->tag_name = UTFstring( *ktn_ptr ).GetUTF8().c_str();
- }
- else if( MKV_CHECKED_PTR_DECL ( kts_ptr, KaxTagString, el ) )
- {
- kts_ptr->ReadData( es.I_O(), SCOPE_ALL_DATA );
- pout_simple->value = UTFstring( *kts_ptr ).GetUTF8().c_str();
- }
- else if( MKV_CHECKED_PTR_DECL ( ktl_ptr, KaxTagLangue, el ) )
- {
- ktl_ptr->ReadData( es.I_O(), SCOPE_ALL_DATA );
- pout_simple->lang = *ktl_ptr;
- }
- else if( MKV_CHECKED_PTR_DECL ( ktd_ptr, KaxTagDefault, el ) )
- {
- VLC_UNUSED(ktd_ptr); // TODO: we do not care about this value, but maybe we should?
- }
- /*Tags can be nested*/
- else if( MKV_CHECKED_PTR_DECL ( kts_ptr, KaxTagSimple, el) )
- {
- SimpleTag st; // ParseSimpleTags will write to this variable
- // the SimpleTag is valid if ParseSimpleTags returns `true`
+ vars.out.tag_name = UTFstring( entry ).GetUTF8().c_str();
+ }
+ E_CASE( KaxTagString, entry )
+ {
+ vars.out.value = UTFstring( entry ).GetUTF8().c_str();
+ }
+ E_CASE( KaxTagLangue, entry )
+ {
+ vars.out.lang = entry;
+ }
+ E_CASE( KaxTagDefault, unused )
+ {
+ }
+ E_CASE( KaxTagSimple, simple )
+ {
+ SimpleTag st; // ParseSimpleTags will write to this variable
+ // the SimpleTag is valid if ParseSimpleTags returns `true`
- if (ParseSimpleTags( &st, kts_ptr, target_type )) {
- pout_simple->sub_tags.push_back( st );
- }
- }
- /*TODO Handle binary tags*/
- size += el->HeadSize() + el->GetSize();
+ if (vars.obj->ParseSimpleTags( &st, &simple, vars.target_type ))
+ vars.out.sub_tags.push_back( st );
}
- }
- catch(...)
- {
- msg_Err( &sys.demuxer, "Error while reading Tag ");
- return false;
- }
+ };
+ SimpleTagHandler::Dispatcher().iterate( tag->begin(), tag->end(), SimpleTagHandler::Payload( payload ) );
if( pout_simple->tag_name.empty() )
{
msg_Warn( &sys.demuxer, "Invalid MKV SimpleTag found.");
return false;
}
+ if( !sys.meta )
+ sys.meta = vlc_meta_New();
for( int i = 0; metadata_map[i].key; i++ )
{
if( pout_simple->tag_name == metadata_map[i].key &&
@@ -349,104 +331,115 @@ done:
void matroska_segment_c::LoadTags( KaxTags *tags )
{
/* Master elements */
- EbmlParser eparser = EbmlParser( &es, tags, &sys.demuxer, true );
- EbmlElement *el;
+ if( unlikely( tags->IsFiniteSize() && tags->GetSize() >= SIZE_MAX ) )
+ {
+ msg_Err( &sys.demuxer, "Tags too big, aborting" );
+ return;
+ }
+ try
+ {
+ EbmlElement *el;
+ int i_upper_level = 0;
+ tags->Read( es, EBML_CONTEXT(tags), i_upper_level, el, true );
+ }
+ catch(...)
+ {
+ msg_Err( &sys.demuxer, "Couldn't read tags" );
+ return;
+ }
- while( ( el = eparser.Get() ) != NULL )
+ struct TagsHandlerPayload
+ {
+ matroska_segment_c * const obj;
+ EbmlParser * const ep;
+ demux_sys_t & sys;
+ int target_type;
+ } payload = { this, ep, sys, 50 };
+ MKV_SWITCH_CREATE( EbmlTypeDispatcher, KaxTagsHandler, TagsHandlerPayload )
{
- if( MKV_IS_ID( el, KaxTag ) )
+ MKV_SWITCH_INIT();
+ E_CASE( KaxTag, entry )
{
+ msg_Dbg( &vars.sys.demuxer, "+ Tag" );
Tag tag;
-
- msg_Dbg( &sys.demuxer, "+ Tag" );
- eparser.Down();
- int target_type = 50;
- while( ( el = eparser.Get() ) != NULL )
+ struct TagHandlerPayload
+ {
+ matroska_segment_c * const obj;
+ EbmlParser * const ep;
+ demux_sys_t & sys;
+ Tag & tag;
+ int target_type;
+ } payload = { vars.obj, vars.ep, vars.sys, tag, 50 };
+ MKV_SWITCH_CREATE( EbmlTypeDispatcher, TagHandler, TagHandlerPayload )
{
- if( MKV_IS_ID( el, KaxTagTargets ) )
+ MKV_SWITCH_INIT();
+ E_CASE( KaxTagTargets, targets )
{
- msg_Dbg( &sys.demuxer, "| + Targets" );
- eparser.Down();
- while( ( el = eparser.Get() ) != NULL )
+ msg_Dbg( &vars.sys.demuxer, "| + Targets" );
+
+ MKV_SWITCH_CREATE( EbmlTypeDispatcher, TargetsHandler, TagHandlerPayload )
{
- try
+ MKV_SWITCH_INIT();
+ E_CASE( KaxTagTargetTypeValue, entry )
{
- if( unlikely( !el->ValidateSize() ) )
- {
- msg_Err( &sys.demuxer, "Invalid size while reading tag");
- break;
- }
- if( MKV_CHECKED_PTR_DECL ( ktttv_ptr, KaxTagTargetTypeValue, el ) )
- {
- ktttv_ptr->ReadData( es.I_O() );
-
- msg_Dbg( &sys.demuxer, "| | + TargetTypeValue: %u", uint32(*ktttv_ptr));
- target_type = static_cast<uint32>( *ktttv_ptr );
- }
- else if( MKV_CHECKED_PTR_DECL ( kttu_ptr, KaxTagTrackUID, el ) )
- {
- tag.i_tag_type = TRACK_UID;
- kttu_ptr->ReadData( es.I_O() );
- tag.i_uid = static_cast<uint64>( *kttu_ptr );
- msg_Dbg( &sys.demuxer, "| | + TrackUID: %" PRIu64, tag.i_uid);
-
- }
- else if( MKV_CHECKED_PTR_DECL ( kteu_ptr, KaxTagEditionUID, el ) )
- {
- tag.i_tag_type = EDITION_UID;
- kteu_ptr->ReadData( es.I_O() );
- tag.i_uid = static_cast<uint64>( *kteu_ptr );
- msg_Dbg( &sys.demuxer, "| | + EditionUID: %" PRIu64, tag.i_uid);
- }
- else if( MKV_CHECKED_PTR_DECL ( ktcu_ptr, KaxTagChapterUID, el ) )
- {
- tag.i_tag_type = CHAPTER_UID;
- ktcu_ptr->ReadData( es.I_O() );
- tag.i_uid = static_cast<uint64>( *ktcu_ptr );
- msg_Dbg( &sys.demuxer, "| | + ChapterUID: %" PRIu64, tag.i_uid);
- }
- else if( MKV_CHECKED_PTR_DECL ( ktau_ptr, KaxTagAttachmentUID, el ) )
- {
- tag.i_tag_type = ATTACHMENT_UID;
- ktau_ptr->ReadData( es.I_O() );
- tag.i_uid = static_cast<uint64>( *ktau_ptr );
- msg_Dbg( &sys.demuxer, "| | + AttachmentUID: %" PRIu64, tag.i_uid);
- }
- else
- {
- msg_Dbg( &sys.demuxer, "| | + LoadTag Unknown (%s)", typeid( *el ).name() );
- }
+ vars.target_type = static_cast<uint32>( entry );
+ msg_Dbg( &vars.sys.demuxer, "| | + TargetTypeValue: %u", vars.target_type);
}
- catch(...)
+ E_CASE( KaxTagTrackUID, entry )
{
- msg_Err( &sys.demuxer, "Error while reading tag");
- break;
+ vars.tag.i_tag_type = TRACK_UID;
+ vars.tag.i_uid = static_cast<uint64>( entry );
+ msg_Dbg( &vars.sys.demuxer, "| | + TrackUID: %" PRIu64, vars.tag.i_uid);
}
- }
- eparser.Up();
+ E_CASE( KaxTagEditionUID, entry )
+ {
+ vars.tag.i_tag_type = EDITION_UID;
+ vars.tag.i_uid = static_cast<uint64>( entry );
+ msg_Dbg( &vars.sys.demuxer, "| | + EditionUID: %" PRIu64, vars.tag.i_uid);
+ }
+ E_CASE( KaxTagChapterUID, entry )
+ {
+ vars.tag.i_tag_type = CHAPTER_UID;
+ vars.tag.i_uid = static_cast<uint64>( entry );
+ msg_Dbg( &vars.sys.demuxer, "| | + ChapterUID: %" PRIu64, vars.tag.i_uid);
+ }
+ E_CASE( KaxTagAttachmentUID, entry )
+ {
+ vars.tag.i_tag_type = ATTACHMENT_UID;
+ vars.tag.i_uid = static_cast<uint64>( entry );
+ msg_Dbg( &vars.sys.demuxer, "| | + AttachmentUID: %" PRIu64, vars.tag.i_uid);
+ }
+ E_CASE_DEFAULT( el )
+ {
+ msg_Dbg( &vars.sys.demuxer, "| | + Unknown (%s)", typeid(el).name() );
+ }
+ };
+
+ TargetsHandler::Dispatcher().iterate( targets.begin(), targets.end(), TargetsHandler::Payload( vars ) );
}
- else if( MKV_CHECKED_PTR_DECL ( kts_ptr, KaxTagSimple, el ) )
+ E_CASE( KaxTagSimple, entry )
{
SimpleTag simple;
- if (ParseSimpleTags(&simple, kts_ptr, target_type )) {
- tag.simple_tags.push_back( simple );
- }
+ if (vars.obj->ParseSimpleTags( &simple, &entry, vars.target_type ))
+ vars.tag.simple_tags.push_back( simple );
}
- else
+ E_CASE_DEFAULT( el )
{
- msg_Dbg( &sys.demuxer, "| + LoadTag Unknown (%s)", typeid( *el ).name() );
+ msg_Dbg( &vars.sys.demuxer, "| | + Unknown (%s)", typeid(el).name() );
}
- }
- eparser.Up();
- this->tags.push_back(tag);
+ };
+
+ TagHandler::Dispatcher().iterate( entry.begin(), entry.end(), TagHandler::Payload( payload ) );
+ vars.obj->tags.push_back(tag);
}
- else
+ E_CASE_DEFAULT( el )
{
- msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
+ msg_Dbg( &vars.sys.demuxer, "| + LoadTag Unknown (%s)", typeid(el).name() );
}
- }
+ };
+ KaxTagsHandler::Dispatcher().iterate( tags->begin(), tags->end(), KaxTagsHandler::Payload( payload ) );
msg_Dbg( &sys.demuxer, "loading tags done." );
}
More information about the vlc-commits
mailing list