[vlc-commits] Fix next/prev uid segment linking in MKV
Denis Charmet
git at videolan.org
Mon Mar 19 15:20:46 CET 2012
vlc | branch: master | Denis Charmet <typx at dinauz.org> | Fri Mar 16 23:32:17 2012 +0100| [50f3a9b9b79a27cd1d1d5e1fee583bf06edf9f85] | committer: Jean-Baptiste Kempf
Fix next/prev uid segment linking in MKV
This still doesn't work with ordered chapters though.
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=50f3a9b9b79a27cd1d1d5e1fee583bf06edf9f85
---
modules/demux/mkv/demux.cpp | 2 ++
modules/demux/mkv/virtual_segment.cpp | 33 +++++++++++++++++++++------------
modules/demux/mkv/virtual_segment.hpp | 4 +---
3 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/modules/demux/mkv/demux.cpp b/modules/demux/mkv/demux.cpp
index 658dc31..f68dde5 100644
--- a/modules/demux/mkv/demux.cpp
+++ b/modules/demux/mkv/demux.cpp
@@ -536,10 +536,12 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS
else if( MKV_IS_ID( l, KaxPrevUID ) )
{
p_segment1->p_prev_segment_uid = new KaxPrevUID( *static_cast<KaxPrevUID*>(l) );
+ p_segment1->b_ref_external_segments = true;
}
else if( MKV_IS_ID( l, KaxNextUID ) )
{
p_segment1->p_next_segment_uid = new KaxNextUID( *static_cast<KaxNextUID*>(l) );
+ p_segment1->b_ref_external_segments = true;
}
else if( MKV_IS_ID( l, KaxSegmentFamily ) )
{
diff --git a/modules/demux/mkv/virtual_segment.cpp b/modules/demux/mkv/virtual_segment.cpp
index 6dd0463..38db54a 100644
--- a/modules/demux/mkv/virtual_segment.cpp
+++ b/modules/demux/mkv/virtual_segment.cpp
@@ -102,8 +102,10 @@ virtual_chapter_c::~virtual_chapter_c()
virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<matroska_segment_c*> *opened_segments)
{
+ bool b_fake_ordered = false;
matroska_segment_c *p_main_segment = (*opened_segments)[0];
p_edition = p_edit;
+ b_ordered = false;
int64_t usertime_offset = 0;
@@ -123,14 +125,13 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
}
else /* Not ordered or no edition at all */
{
- b_ordered = false;
matroska_segment_c * p_cur = p_main_segment;
virtual_chapter_c * p_vchap = NULL;
int64_t tmp = 0;
/* check for prev linked segments */
- /* FIXME to avoid infinite recursion we limit to 5 prev sould be better as parameter */
- for( int limit = 0; limit < 5 && p_cur->p_prev_segment_uid ; limit++ )
+ /* FIXME to avoid infinite recursion we limit to 10 prev should be better as parameter */
+ for( int limit = 0; limit < 10 && p_cur->p_prev_segment_uid ; limit++ )
{
matroska_segment_c * p_prev = NULL;
if( ( p_prev = getSegmentbyUID( p_cur->p_prev_segment_uid, opened_segments ) ) )
@@ -139,6 +140,10 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
msg_Dbg( &p_main_segment->sys.demuxer, "Prev segment 0x%x found\n",
*(int32_t*)p_cur->p_prev_segment_uid->GetBuffer() );
+ /* Preload segment */
+ if ( !p_prev->b_preloaded )
+ p_prev->Preload();
+
/* Create virtual_chapter from the first edition if any */
chapter_item_c * p_chap = ( p_prev->stored_editions.size() > 0 )? ((chapter_item_c *)p_prev->stored_editions[0]) : NULL;
@@ -148,6 +153,7 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
chapters.insert( chapters.begin(), p_vchap );
p_cur = p_prev;
+ b_fake_ordered = true;
}
else /* segment not found */
break;
@@ -162,7 +168,7 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
chapters.push_back( p_vchap );
/* Append next linked segments */
- for( int limit = 0; limit < 5 && p_cur->p_next_segment_uid; limit++ )
+ for( int limit = 0; limit < 10 && p_cur->p_next_segment_uid; limit++ )
{
matroska_segment_c * p_next = NULL;
if( ( p_next = getSegmentbyUID( p_cur->p_next_segment_uid, opened_segments ) ) )
@@ -171,6 +177,10 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
msg_Dbg( &p_main_segment->sys.demuxer, "Next segment 0x%x found\n",
*(int32_t*) p_cur->p_next_segment_uid->GetBuffer() );
+ /* Preload segment */
+ if ( !p_next->b_preloaded )
+ p_next->Preload();
+
/* Create virtual_chapter from the first edition if any */
chapter_item_c * p_chap = ( p_next->stored_editions.size() > 0 )?( (chapter_item_c *)p_next->stored_editions[0] ) : NULL;
@@ -181,6 +191,7 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
p_cur = p_next;
+ b_fake_ordered = true;
}
else /* segment not found */
break;
@@ -188,6 +199,8 @@ virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<ma
/* Retime chapters */
retimeChapters();
+ if(b_fake_ordered)
+ b_ordered = true;
}
#if MKV_DEBUG
@@ -228,10 +241,6 @@ void virtual_edition_c::retimeChapters()
i_duration = 0;
- /* Sort by start time */
- if( chapters.size() > 1 )
- std::sort( chapters.begin(), chapters.end(), virtual_chapter_c::CompareTimecode );
-
/* On non ordered editions we have one top chapter == one segment */
for( size_t i = 0; i < chapters.size(); i++ )
{
@@ -383,8 +392,8 @@ bool virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
{
// only physically seek if necessary
if ( p_current_chapter == NULL ||
- ( p_current_chapter->p_chapter->i_end_time != p_cur_chapter->p_chapter->i_start_time ) ||
- ( p_current_chapter && p_current_chapter->p_segment != p_cur_chapter->p_segment ) )
+ ( p_current_chapter && p_current_chapter->p_segment != p_cur_chapter->p_segment ) ||
+ ( p_current_chapter->p_chapter->i_end_time != p_cur_chapter->p_chapter->i_start_time ))
{
Seek( demux, p_cur_chapter->i_virtual_start_time, 0, p_cur_chapter, -1 );
return true;
@@ -439,8 +448,8 @@ void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_
if ( p_chapter != NULL )
{
- p_sys->i_chapter_time =
- i_time_offset = p_chapter->i_virtual_start_time - ( ( p_chapter->p_chapter )? p_chapter->p_chapter->i_start_time : 0 );
+ i_time_offset = p_chapter->i_virtual_start_time - ( ( p_chapter->p_chapter )? p_chapter->p_chapter->i_start_time : 0 );
+ p_sys->i_chapter_time = i_time_offset - p_chapter->p_segment->i_start_time;
if ( p_chapter->p_chapter && p_chapter->i_seekpoint_num > 0 )
{
demuxer.info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
diff --git a/modules/demux/mkv/virtual_segment.hpp b/modules/demux/mkv/virtual_segment.hpp
index 31b45a2..9dc8e36 100644
--- a/modules/demux/mkv/virtual_segment.hpp
+++ b/modules/demux/mkv/virtual_segment.hpp
@@ -63,9 +63,7 @@ public:
static bool CompareTimecode( const virtual_chapter_c * itemA, const virtual_chapter_c * itemB )
{
- return ( itemA->i_virtual_start_time < itemB->i_virtual_start_time ||
- ( itemA->i_virtual_start_time == itemB->i_virtual_start_time &&
- itemA->i_virtual_stop_time < itemB->i_virtual_stop_time ) );
+ return ( itemA->i_virtual_start_time < itemB->i_virtual_start_time );
}
matroska_segment_c *p_segment;
More information about the vlc-commits
mailing list