mkv.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:31k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mkv.cpp : matroska demuxer
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 the VideoLAN team
  5.  * $Id: 102a807476bf03ef2a8836475b691aad191db9db $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Steve Lhomme <steve.lhomme@free.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #include "mkv.hpp"
  25. #include "util.hpp"
  26. #include "matroska_segment.hpp"
  27. #include "demux.hpp"
  28. #include "chapters.hpp"
  29. #include "Ebml_parser.hpp"
  30. #include "stream_io_callback.hpp"
  31. /*****************************************************************************
  32.  * Module descriptor
  33.  *****************************************************************************/
  34. static int  Open ( vlc_object_t * );
  35. static void Close( vlc_object_t * );
  36. vlc_module_begin ()
  37.     set_shortname( "Matroska" )
  38.     set_description( N_("Matroska stream demuxer" ) )
  39.     set_capability( "demux", 50 )
  40.     set_callbacks( Open, Close )
  41.     set_category( CAT_INPUT )
  42.     set_subcategory( SUBCAT_INPUT_DEMUX )
  43.     add_bool( "mkv-use-ordered-chapters", 1, NULL,
  44.             N_("Ordered chapters"),
  45.             N_("Play ordered chapters as specified in the segment."), true );
  46.     add_bool( "mkv-use-chapter-codec", 1, NULL,
  47.             N_("Chapter codecs"),
  48.             N_("Use chapter codecs found in the segment."), true );
  49.     add_bool( "mkv-preload-local-dir", 0, NULL,
  50.             N_("Preload Directory"),
  51.             N_("Preload matroska files from the same family in the same directory (not good for broken files)."), true );
  52.     add_bool( "mkv-seek-percent", 0, NULL,
  53.             N_("Seek based on percent not time"),
  54.             N_("Seek based on percent not time."), true );
  55.     add_bool( "mkv-use-dummy", 0, NULL,
  56.             N_("Dummy Elements"),
  57.             N_("Read and discard unknown EBML elements (not good for broken files)."), true );
  58.     add_shortcut( "mka" )
  59.     add_shortcut( "mkv" )
  60. vlc_module_end ()
  61. class demux_sys_t;
  62. static int  Demux  ( demux_t * );
  63. static int  Control( demux_t *, int, va_list );
  64. static void Seek   ( demux_t *, mtime_t i_date, double f_percent, chapter_item_c *psz_chapter );
  65. /*****************************************************************************
  66.  * Open: initializes matroska demux structures
  67.  *****************************************************************************/
  68. static int Open( vlc_object_t * p_this )
  69. {
  70.     demux_t            *p_demux = (demux_t*)p_this;
  71.     demux_sys_t        *p_sys;
  72.     matroska_stream_c  *p_stream;
  73.     matroska_segment_c *p_segment;
  74.     const uint8_t      *p_peek;
  75.     std::string         s_path, s_filename;
  76.     vlc_stream_io_callback *p_io_callback;
  77.     EbmlStream         *p_io_stream;
  78.     /* peek the begining */
  79.     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
  80.     /* is a valid file */
  81.     if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||
  82.         p_peek[2] != 0xdf || p_peek[3] != 0xa3 ) return VLC_EGENERIC;
  83.     /* Set the demux function */
  84.     p_demux->pf_demux   = Demux;
  85.     p_demux->pf_control = Control;
  86.     p_demux->p_sys      = p_sys = new demux_sys_t( *p_demux );
  87.     p_io_callback = new vlc_stream_io_callback( p_demux->s, false );
  88.     p_io_stream = new EbmlStream( *p_io_callback );
  89.     if( p_io_stream == NULL )
  90.     {
  91.         msg_Err( p_demux, "failed to create EbmlStream" );
  92.         delete p_io_callback;
  93.         delete p_sys;
  94.         return VLC_EGENERIC;
  95.     }
  96.     p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_io_stream, true );
  97.     if( p_stream == NULL )
  98.     {
  99.         msg_Err( p_demux, "cannot find KaxSegment" );
  100.         goto error;
  101.     }
  102.     p_sys->streams.push_back( p_stream );
  103.     p_stream->p_in = p_io_callback;
  104.     p_stream->p_es = p_io_stream;
  105.     for (size_t i=0; i<p_stream->segments.size(); i++)
  106.     {
  107.         p_stream->segments[i]->Preload();
  108.     }
  109.     p_segment = p_stream->segments[0];
  110.     if( p_segment->cluster == NULL )
  111.     {
  112.         msg_Err( p_demux, "cannot find any cluster, damaged file ?" );
  113.         goto error;
  114.     }
  115.     if (config_GetInt( p_demux, "mkv-preload-local-dir" ))
  116.     {
  117.         /* get the files from the same dir from the same family (based on p_demux->psz_path) */
  118.         if (p_demux->psz_path[0] != '' && !strcmp(p_demux->psz_access, ""))
  119.         {
  120.             // assume it's a regular file
  121.             // get the directory path
  122.             s_path = p_demux->psz_path;
  123.             if (s_path.at(s_path.length() - 1) == DIRECTORY_SEPARATOR)
  124.             {
  125.                 s_path = s_path.substr(0,s_path.length()-1);
  126.             }
  127.             else
  128.             {
  129.                 if (s_path.find_last_of(DIRECTORY_SEPARATOR) > 0)
  130.                 {
  131.                     s_path = s_path.substr(0,s_path.find_last_of(DIRECTORY_SEPARATOR));
  132.                 }
  133.             }
  134.             DIR *p_src_dir = utf8_opendir(s_path.c_str());
  135.             if (p_src_dir != NULL)
  136.             {
  137.                 char *psz_file;
  138.                 while ((psz_file = utf8_readdir(p_src_dir)) != NULL)
  139.                 {
  140.                     if (strlen(psz_file) > 4)
  141.                     {
  142.                         s_filename = s_path + DIRECTORY_SEPARATOR + psz_file;
  143. #ifdef WIN32
  144.                         if (!strcasecmp(s_filename.c_str(), p_demux->psz_path))
  145. #else
  146.                         if (!s_filename.compare(p_demux->psz_path))
  147. #endif
  148.                         {
  149.                             free (psz_file);
  150.                             continue; // don't reuse the original opened file
  151.                         }
  152. #if defined(__GNUC__) && (__GNUC__ < 3)
  153.                         if (!s_filename.compare("mkv", s_filename.length() - 3, 3) ||
  154.                             !s_filename.compare("mka", s_filename.length() - 3, 3))
  155. #else
  156.                         if (!s_filename.compare(s_filename.length() - 3, 3, "mkv") ||
  157.                             !s_filename.compare(s_filename.length() - 3, 3, "mka"))
  158. #endif
  159.                         {
  160.                             // test wether this file belongs to our family
  161.                             const uint8_t *p_peek;
  162.                             bool          file_ok = false;
  163.                             stream_t      *p_file_stream = stream_UrlNew(
  164.                                                             p_demux,
  165.                                                             s_filename.c_str());
  166.                             /* peek the begining */
  167.                             if( p_file_stream &&
  168.                                 stream_Peek( p_file_stream, &p_peek, 4 ) >= 4
  169.                                 && p_peek[0] == 0x1a && p_peek[1] == 0x45 &&
  170.                                 p_peek[2] == 0xdf && p_peek[3] == 0xa3 ) file_ok = true;
  171.                             if ( file_ok )
  172.                             {
  173.                                 vlc_stream_io_callback *p_file_io = new vlc_stream_io_callback( p_file_stream, true );
  174.                                 EbmlStream *p_estream = new EbmlStream(*p_file_io);
  175.                                 p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_estream );
  176.                                 if ( p_stream == NULL )
  177.                                 {
  178.                                     msg_Dbg( p_demux, "the file '%s' will not be used", s_filename.c_str() );
  179.                                     delete p_estream;
  180.                                     delete p_file_io;
  181.                                 }
  182.                                 else
  183.                                 {
  184.                                     p_stream->p_in = p_file_io;
  185.                                     p_stream->p_es = p_estream;
  186.                                     p_sys->streams.push_back( p_stream );
  187.                                 }
  188.                             }
  189.                             else
  190.                             {
  191.                                 if( p_file_stream ) {
  192.                                     stream_Delete( p_file_stream );
  193.                                 }
  194.                                 msg_Dbg( p_demux, "the file '%s' cannot be opened", s_filename.c_str() );
  195.                             }
  196.                         }
  197.                     }
  198.                     free (psz_file);
  199.                 }
  200.                 closedir( p_src_dir );
  201.             }
  202.         }
  203.         p_sys->PreloadFamily( *p_segment );
  204.     }
  205.     p_sys->PreloadLinked( p_segment );
  206.     if ( !p_sys->PreparePlayback( NULL ) )
  207.     {
  208.         msg_Err( p_demux, "cannot use the segment" );
  209.         goto error;
  210.     }
  211.     p_sys->StartUiThread();
  212.  
  213.     return VLC_SUCCESS;
  214. error:
  215.     delete p_sys;
  216.     return VLC_EGENERIC;
  217. }
  218. /*****************************************************************************
  219.  * Close: frees unused data
  220.  *****************************************************************************/
  221. static void Close( vlc_object_t *p_this )
  222. {
  223.     demux_t     *p_demux = (demux_t*)p_this;
  224.     demux_sys_t *p_sys   = p_demux->p_sys;
  225.     delete p_sys;
  226. }
  227. /*****************************************************************************
  228.  * Control:
  229.  *****************************************************************************/
  230. static int Control( demux_t *p_demux, int i_query, va_list args )
  231. {
  232.     demux_sys_t        *p_sys = p_demux->p_sys;
  233.     int64_t     *pi64;
  234.     double      *pf, f;
  235.     int         i_skp;
  236.     size_t      i_idx;
  237.     vlc_meta_t *p_meta;
  238.     input_attachment_t ***ppp_attach;
  239.     int *pi_int;
  240.     switch( i_query )
  241.     {
  242.         case DEMUX_GET_ATTACHMENTS:
  243.             ppp_attach = (input_attachment_t***)va_arg( args, input_attachment_t*** );
  244.             pi_int = (int*)va_arg( args, int * );
  245.             if( p_sys->stored_attachments.size() <= 0 )
  246.                 return VLC_EGENERIC;
  247.             *pi_int = p_sys->stored_attachments.size();
  248.             *ppp_attach = (input_attachment_t**)malloc( sizeof(input_attachment_t**) *
  249.                                                         p_sys->stored_attachments.size() );
  250.             if( !(*ppp_attach) )
  251.                 return VLC_ENOMEM;
  252.             for( size_t i = 0; i < p_sys->stored_attachments.size(); i++ )
  253.             {
  254.                 attachment_c *a = p_sys->stored_attachments[i];
  255.                 (*ppp_attach)[i] = vlc_input_attachment_New( a->psz_file_name.c_str(), a->psz_mime_type.c_str(), NULL,
  256.                                                              a->p_data, a->i_size );
  257.             }
  258.             return VLC_SUCCESS;
  259.         case DEMUX_GET_META:
  260.             p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
  261.             vlc_meta_Merge( p_meta, p_sys->meta );
  262.             return VLC_SUCCESS;
  263.         case DEMUX_GET_LENGTH:
  264.             pi64 = (int64_t*)va_arg( args, int64_t * );
  265.             if( p_sys->f_duration > 0.0 )
  266.             {
  267.                 *pi64 = (int64_t)(p_sys->f_duration * 1000);
  268.                 return VLC_SUCCESS;
  269.             }
  270.             return VLC_EGENERIC;
  271.         case DEMUX_GET_POSITION:
  272.             pf = (double*)va_arg( args, double * );
  273.             if ( p_sys->f_duration > 0.0 )
  274.                 *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);
  275.             return VLC_SUCCESS;
  276.         case DEMUX_SET_POSITION:
  277.             f = (double)va_arg( args, double );
  278.             Seek( p_demux, -1, f, NULL );
  279.             return VLC_SUCCESS;
  280.         case DEMUX_GET_TIME:
  281.             pi64 = (int64_t*)va_arg( args, int64_t * );
  282.             *pi64 = p_sys->i_pts;
  283.             return VLC_SUCCESS;
  284.         case DEMUX_GET_TITLE_INFO:
  285.             if( p_sys->titles.size() > 1 || ( p_sys->titles.size() == 1 && p_sys->titles[0]->i_seekpoint > 0 ) )
  286.             {
  287.                 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
  288.                 int *pi_int    = (int*)va_arg( args, int* );
  289.                 *pi_int = p_sys->titles.size();
  290.                 *ppp_title = (input_title_t**)malloc( sizeof( input_title_t**) * p_sys->titles.size() );
  291.                 for( size_t i = 0; i < p_sys->titles.size(); i++ )
  292.                 {
  293.                     (*ppp_title)[i] = vlc_input_title_Duplicate( p_sys->titles[i] );
  294.                 }
  295.                 return VLC_SUCCESS;
  296.             }
  297.             return VLC_EGENERIC;
  298.         case DEMUX_SET_TITLE:
  299.             /* TODO handle editions as titles */
  300.             i_idx = (int)va_arg( args, int );
  301.             if( i_idx < p_sys->used_segments.size() )
  302.             {
  303.                 p_sys->JumpTo( *p_sys->used_segments[i_idx], NULL );
  304.                 return VLC_SUCCESS;
  305.             }
  306.             return VLC_EGENERIC;
  307.         case DEMUX_SET_SEEKPOINT:
  308.             i_skp = (int)va_arg( args, int );
  309.             // TODO change the way it works with the << & >> buttons on the UI (+1/-1 instead of a number)
  310.             if( p_sys->titles.size() && i_skp < p_sys->titles[p_sys->i_current_title]->i_seekpoint)
  311.             {
  312.                 Seek( p_demux, (int64_t)p_sys->titles[p_sys->i_current_title]->seekpoint[i_skp]->i_time_offset, -1, NULL);
  313.                 p_demux->info.i_seekpoint |= INPUT_UPDATE_SEEKPOINT;
  314.                 p_demux->info.i_seekpoint = i_skp;
  315.                 return VLC_SUCCESS;
  316.             }
  317.             return VLC_EGENERIC;
  318.         case DEMUX_GET_FPS:
  319.             pf = (double *)va_arg( args, double * );
  320.             *pf = 0.0;
  321.             if( p_sys->p_current_segment && p_sys->p_current_segment->Segment() )
  322.             {
  323.                 const matroska_segment_c *p_segment = p_sys->p_current_segment->Segment();
  324.                 for( size_t i = 0; i < p_segment->tracks.size(); i++ )
  325.                 {
  326.                     mkv_track_t *tk = p_segment->tracks[i];
  327.                     if( tk->fmt.i_cat == VIDEO_ES && tk->fmt.video.i_frame_rate_base > 0 )
  328.                     {
  329.                         *pf = (double)tk->fmt.video.i_frame_rate / tk->fmt.video.i_frame_rate_base;
  330.                         break;
  331.                     }
  332.                 }
  333.             }
  334.             return VLC_SUCCESS;
  335.         case DEMUX_SET_TIME:
  336.         default:
  337.             return VLC_EGENERIC;
  338.     }
  339. }
  340. /* Seek */
  341. static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, chapter_item_c *psz_chapter )
  342. {
  343.     demux_sys_t        *p_sys = p_demux->p_sys;
  344.     virtual_segment_c  *p_vsegment = p_sys->p_current_segment;
  345.     matroska_segment_c *p_segment = p_vsegment->Segment();
  346.     mtime_t            i_time_offset = 0;
  347.     int64_t            i_global_position = -1;
  348.     int         i_index;
  349.     msg_Dbg( p_demux, "seek request to %"PRId64" (%f%%)", i_date, f_percent );
  350.     if( i_date < 0 && f_percent < 0 )
  351.     {
  352.         msg_Warn( p_demux, "cannot seek nowhere !" );
  353.         return;
  354.     }
  355.     if( f_percent > 1.0 )
  356.     {
  357.         msg_Warn( p_demux, "cannot seek so far !" );
  358.         return;
  359.     }
  360.     /* seek without index or without date */
  361.     if( f_percent >= 0 && (config_GetInt( p_demux, "mkv-seek-percent" ) || !p_segment->b_cues || i_date < 0 ))
  362.     {
  363.         if( p_sys->f_duration >= 0 && p_segment->b_cues )
  364.         {
  365.             i_date = int64_t( f_percent * p_sys->f_duration * 1000.0 );
  366.         }
  367.         else
  368.         {
  369.             int64_t i_pos = int64_t( f_percent * stream_Size( p_demux->s ) );
  370.             msg_Dbg( p_demux, "inaccurate way of seeking for pos:%"PRId64, i_pos );
  371.             for( i_index = 0; i_index < p_segment->i_index; i_index++ )
  372.             {
  373.                 if( p_segment->b_cues && p_segment->p_indexes[i_index].i_position < i_pos )
  374.                     break;
  375.                 if( !p_segment->b_cues && p_segment->p_indexes[i_index].i_position >= i_pos && p_segment->p_indexes[i_index].i_time > 0 )
  376.                     break;
  377.             }
  378.             if( i_index == p_segment->i_index )
  379.             {
  380.                 i_index--;
  381.             }
  382.             i_date = p_segment->p_indexes[i_index].i_time;
  383.             if( !p_segment->b_cues && ( p_segment->p_indexes[i_index].i_position < i_pos || p_segment->p_indexes[i_index].i_position - i_pos > 2000000 ))
  384.             {
  385.                 msg_Dbg( p_demux, "no cues, seek request to global pos: %"PRId64, i_pos );
  386.                 i_global_position = i_pos;
  387.             }
  388.         }
  389.     }
  390.     p_vsegment->Seek( *p_demux, i_date, i_time_offset, psz_chapter, i_global_position );
  391. }
  392. /* Utility function for BlockDecode */
  393. static block_t *MemToBlock( demux_t *p_demux, uint8_t *p_mem, int i_mem, size_t offset)
  394. {
  395.     block_t *p_block;
  396.     if( !(p_block = block_New( p_demux, i_mem + offset ) ) ) return NULL;
  397.     memcpy( p_block->p_buffer + offset, p_mem, i_mem );
  398.     //p_block->i_rate = p_input->stream.control.i_rate;
  399.     return p_block;
  400. }
  401. /* Needed by matroska_segment::Seek() */
  402. static void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock,
  403.                          mtime_t i_pts, mtime_t i_duration, bool f_mandatory )
  404. {
  405.     demux_sys_t        *p_sys = p_demux->p_sys;
  406.     matroska_segment_c *p_segment = p_sys->p_current_segment->Segment();
  407.     size_t          i_track;
  408.     unsigned int    i;
  409.     bool            b;
  410.     if( p_segment->BlockFindTrackIndex( &i_track, block, simpleblock ) )
  411.     {
  412.         msg_Err( p_demux, "invalid track number" );
  413.         return;
  414.     }
  415.     mkv_track_t *tk = p_segment->tracks[i_track];
  416.     if( tk->fmt.i_cat != NAV_ES && tk->p_es == NULL )
  417.     {
  418.         msg_Err( p_demux, "unknown track number" );
  419.         return;
  420.     }
  421.     if( i_pts + i_duration < p_sys->i_start_pts && tk->fmt.i_cat == AUDIO_ES )
  422.     {
  423.         return; /* discard audio packets that shouldn't be rendered */
  424.     }
  425.     if ( tk->fmt.i_cat != NAV_ES )
  426.     {
  427.         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
  428.         if( !b )
  429.         {
  430.             tk->b_inited = false;
  431.             return;
  432.         }
  433.     }
  434.     /* First send init data */
  435.     if( !tk->b_inited && tk->i_data_init > 0 )
  436.     {
  437.         block_t *p_init;
  438.         msg_Dbg( p_demux, "sending header (%d bytes)", tk->i_data_init );
  439.         p_init = MemToBlock( p_demux, tk->p_data_init, tk->i_data_init, 0 );
  440.         if( p_init ) es_out_Send( p_demux->out, tk->p_es, p_init );
  441.     }
  442.     tk->b_inited = true;
  443.     for( i = 0;
  444.          (block != NULL && i < block->NumberFrames()) || (simpleblock != NULL && i < simpleblock->NumberFrames());
  445.          i++ )
  446.     {
  447.         block_t *p_block;
  448.         DataBuffer *data;
  449.         if( simpleblock != NULL )
  450.         {
  451.             data = &simpleblock->GetBuffer(i);
  452.             // condition when the DTS is correct (keyframe or B frame == NOT P frame)
  453.             f_mandatory = simpleblock->IsDiscardable() || simpleblock->IsKeyframe();
  454.         }
  455.         else
  456.         {
  457.             data = &block->GetBuffer(i);
  458.         }
  459.         if( tk->i_compression_type == MATROSKA_COMPRESSION_HEADER && tk->p_compression_data != NULL )
  460.             p_block = MemToBlock( p_demux, data->Buffer(), data->Size(), tk->p_compression_data->GetSize() );
  461.         else
  462.             p_block = MemToBlock( p_demux, data->Buffer(), data->Size(), 0 );
  463.         if( p_block == NULL )
  464.         {
  465.             break;
  466.         }
  467. #if defined(HAVE_ZLIB_H)
  468.         if( tk->i_compression_type == MATROSKA_COMPRESSION_ZLIB )
  469.         {
  470.             p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );
  471.         }
  472.         else
  473. #endif
  474.         if( tk->i_compression_type == MATROSKA_COMPRESSION_HEADER )
  475.         {
  476.             memcpy( p_block->p_buffer, tk->p_compression_data->GetBuffer(), tk->p_compression_data->GetSize() );
  477.         }
  478.         if ( tk->fmt.i_cat == NAV_ES )
  479.         {
  480.             // TODO handle the start/stop times of this packet
  481.             if ( p_sys->b_ui_hooked )
  482.             {
  483.                 vlc_mutex_lock( &p_sys->p_ev->lock );
  484.                 memcpy( &p_sys->pci_packet, &p_block->p_buffer[1], sizeof(pci_t) );
  485.                 p_sys->SwapButtons();
  486.                 p_sys->b_pci_packet_set = true;
  487.                 vlc_mutex_unlock( &p_sys->p_ev->lock );
  488.                 block_Release( p_block );
  489.             }
  490.             return;
  491.         }
  492.         // correct timestamping when B frames are used
  493.         if( tk->fmt.i_cat != VIDEO_ES )
  494.         {
  495.             p_block->i_dts = p_block->i_pts = i_pts;
  496.         }
  497.         else
  498.         {
  499.             if( tk->b_dts_only )
  500.             {
  501.                 p_block->i_pts = 0;
  502.                 p_block->i_dts = i_pts;
  503.             }
  504.             else
  505.             {
  506.                 p_block->i_pts = i_pts;
  507.                 if ( f_mandatory )
  508.                     p_block->i_dts = p_block->i_pts;
  509.                 else
  510.                     p_block->i_dts = min( i_pts, tk->i_last_dts + (mtime_t)(tk->i_default_duration >> 10));
  511.                 p_sys->i_pts = p_block->i_dts;
  512.             }
  513.         }
  514.         tk->i_last_dts = p_block->i_dts;
  515. #if 0
  516. msg_Dbg( p_demux, "block i_dts: %"PRId64" / i_pts: %"PRId64, p_block->i_dts, p_block->i_pts);
  517. #endif
  518.         if( strcmp( tk->psz_codec, "S_VOBSUB" ) )
  519.         {
  520.             p_block->i_length = i_duration * 1000;
  521.         }
  522.         /* FIXME remove when VLC_TS_INVALID work is done */
  523.         if( i == 0 || p_block->i_dts > 0 )
  524.             p_block->i_dts++;
  525.         if( !tk->b_dts_only && ( i == 0 || p_block->i_pts ) )
  526.             p_block->i_pts++;
  527.         es_out_Send( p_demux->out, tk->p_es, p_block );
  528.         /* use time stamp only for first block */
  529.         i_pts = 0;
  530.     }
  531. }
  532. void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
  533. {
  534.     KaxBlock    *block;
  535.     KaxSimpleBlock *simpleblock;
  536.     int         i_track_skipping;
  537.     int64_t     i_block_duration;
  538.     int64_t     i_block_ref1;
  539.     int64_t     i_block_ref2;
  540.     size_t      i_track;
  541.     int64_t     i_seek_position = i_start_pos;
  542.     int64_t     i_seek_time = i_start_time;
  543.     if( i_global_position >= 0 )
  544.     {
  545.         /* Special case for seeking in files with no cues */
  546.         EbmlElement *el = NULL;
  547.         es.I_O().setFilePointer( i_start_pos, seek_beginning );
  548.         delete ep;
  549.         ep = new EbmlParser( &es, segment, &sys.demuxer );
  550.         cluster = NULL;
  551.         while( ( el = ep->Get() ) != NULL )
  552.         {
  553.             if( MKV_IS_ID( el, KaxCluster ) )
  554.             {
  555.                 cluster = (KaxCluster *)el;
  556.                 i_cluster_pos = cluster->GetElementPosition();
  557.                 if( i_index == 0 ||
  558.                         ( i_index > 0 && p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
  559.                 {
  560.                     IndexAppendCluster( cluster );
  561.                 }
  562.                 if( es.I_O().getFilePointer() >= i_global_position )
  563.                 {
  564.                     ParseCluster();
  565.                     msg_Dbg( &sys.demuxer, "we found a cluster that is in the neighbourhood" );
  566.                     return;
  567.                 }
  568.             }
  569.         }
  570.         msg_Err( &sys.demuxer, "This file has no cues, and we were unable to seek to the requested position by parsing." );
  571.         return;
  572.     }
  573.     if ( i_index > 0 )
  574.     {
  575.         int i_idx = 0;
  576.         for( ; i_idx < i_index; i_idx++ )
  577.         {
  578.             if( p_indexes[i_idx].i_time + i_time_offset > i_date )
  579.             {
  580.                 break;
  581.             }
  582.         }
  583.         if( i_idx > 0 )
  584.         {
  585.             i_idx--;
  586.         }
  587.         i_seek_position = p_indexes[i_idx].i_position;
  588.         i_seek_time = p_indexes[i_idx].i_time;
  589.     }
  590.     msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)",
  591.                 i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
  592.     es.I_O().setFilePointer( i_seek_position, seek_beginning );
  593.     delete ep;
  594.     ep = new EbmlParser( &es, segment, &sys.demuxer );
  595.     cluster = NULL;
  596.     sys.i_start_pts = i_date;
  597.     /* now parse until key frame */
  598.     i_track_skipping = 0;
  599.     for( i_track = 0; i_track < tracks.size(); i_track++ )
  600.     {
  601.         if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
  602.         {
  603.             tracks[i_track]->b_search_keyframe = true;
  604.             i_track_skipping++;
  605.         }
  606.     }
  607.     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
  608.     while( i_track_skipping > 0 )
  609.     {
  610.         if( BlockGet( block, simpleblock, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
  611.         {
  612.             msg_Warn( &sys.demuxer, "cannot get block EOF?" );
  613.             return;
  614.         }
  615.         ep->Down();
  616.         for( i_track = 0; i_track < tracks.size(); i_track++ )
  617.         {
  618.             if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
  619.                 (block && tracks[i_track]->i_number == block->TrackNum()) )
  620.             {
  621.                 break;
  622.             }
  623.         }
  624.         if( simpleblock )
  625.             sys.i_pts = (sys.i_chapter_time + simpleblock->GlobalTimecode()) / (mtime_t) 1000;
  626.         else
  627.             sys.i_pts = (sys.i_chapter_time + block->GlobalTimecode()) / (mtime_t) 1000;
  628.         if( i_track < tracks.size() )
  629.         {
  630.             if( sys.i_pts >= sys.i_start_pts )
  631.             {
  632.                 cluster = static_cast<KaxCluster*>(ep->UnGet( i_block_pos, i_cluster_pos ));
  633.                 i_track_skipping = 0;
  634.             }
  635.             else if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
  636.             {
  637.                 if( i_block_ref1 == 0 && tracks[i_track]->b_search_keyframe )
  638.                 {
  639.                     tracks[i_track]->b_search_keyframe = false;
  640.                     i_track_skipping--;
  641.                 }
  642.                 if( !tracks[i_track]->b_search_keyframe )
  643.                 {
  644.                     BlockDecode( &sys.demuxer, block, simpleblock, sys.i_pts, 0, i_block_ref1 >= 0 || i_block_ref2 > 0 );
  645.                 }
  646.             }
  647.         }
  648.         delete block;
  649.     }
  650.     /* FIXME current ES_OUT_SET_NEXT_DISPLAY_TIME does not work that well if
  651.      * the delay is too high. */
  652.     if( sys.i_pts + 500*1000 < sys.i_start_pts )
  653.     {
  654.         sys.i_start_pts = sys.i_pts;
  655.         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, sys.i_start_pts );
  656.     }
  657. }
  658. /*****************************************************************************
  659.  * Demux: reads and demuxes data packets
  660.  *****************************************************************************
  661.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  662.  *****************************************************************************/
  663. static int Demux( demux_t *p_demux)
  664. {
  665.     demux_sys_t        *p_sys = p_demux->p_sys;
  666.     vlc_mutex_lock( &p_sys->lock_demuxer );
  667.     virtual_segment_c  *p_vsegment = p_sys->p_current_segment;
  668.     matroska_segment_c *p_segment = p_vsegment->Segment();
  669.     if ( p_segment == NULL ) return 0;
  670.     int                i_block_count = 0;
  671.     int                i_return = 0;
  672.     for( ;; )
  673.     {
  674.         if ( p_sys->demuxer.b_die )
  675.             break;
  676.         if( p_sys->i_pts >= p_sys->i_start_pts  )
  677.             if ( p_vsegment->UpdateCurrentToChapter( *p_demux ) )
  678.             {
  679.                 i_return = 1;
  680.                 break;
  681.             }
  682.  
  683.         if ( p_vsegment->Edition() && p_vsegment->Edition()->b_ordered && p_vsegment->CurrentChapter() == NULL )
  684.         {
  685.             /* nothing left to read in this ordered edition */
  686.             if ( !p_vsegment->SelectNext() )
  687.                 break;
  688.             p_segment->UnSelect( );
  689.  
  690.             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  691.             /* switch to the next segment */
  692.             p_segment = p_vsegment->Segment();
  693.             if ( !p_segment->Select( 0 ) )
  694.             {
  695.                 msg_Err( p_demux, "Failed to select new segment" );
  696.                 break;
  697.             }
  698.             continue;
  699.         }
  700.         KaxBlock *block;
  701.         KaxSimpleBlock *simpleblock;
  702.         int64_t i_block_duration = 0;
  703.         int64_t i_block_ref1;
  704.         int64_t i_block_ref2;
  705.         if( p_segment->BlockGet( block, simpleblock, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
  706.         {
  707.             if ( p_vsegment->Edition() && p_vsegment->Edition()->b_ordered )
  708.             {
  709.                 const chapter_item_c *p_chap = p_vsegment->CurrentChapter();
  710.                 // check if there are more chapters to read
  711.                 if ( p_chap != NULL )
  712.                 {
  713.                     /* TODO handle successive chapters with the same user_start_time/user_end_time
  714.                     if ( p_chap->i_user_start_time == p_chap->i_user_start_time )
  715.                         p_vsegment->SelectNext();
  716.                     */
  717.                     p_sys->i_pts = p_chap->i_user_end_time;
  718.                     p_sys->i_pts++; // trick to avoid staying on segments with no duration and no content
  719.                     i_return = 1;
  720.                 }
  721.                 break;
  722.             }
  723.             else
  724.             {
  725.                 msg_Warn( p_demux, "cannot get block EOF?" );
  726.                 p_segment->UnSelect( );
  727.  
  728.                 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  729.                 /* switch to the next segment */
  730.                 if ( !p_vsegment->SelectNext() )
  731.                     // no more segments in this stream
  732.                     break;
  733.                 p_segment = p_vsegment->Segment();
  734.                 if ( !p_segment->Select( 0 ) )
  735.                 {
  736.                     msg_Err( p_demux, "Failed to select new segment" );
  737.                     break;
  738.                 }
  739.                 continue;
  740.             }
  741.         }
  742.         if( simpleblock != NULL )
  743.             p_sys->i_pts = (p_sys->i_chapter_time + simpleblock->GlobalTimecode()) / (mtime_t) 1000;
  744.         else
  745.             p_sys->i_pts = (p_sys->i_chapter_time + block->GlobalTimecode()) / (mtime_t) 1000;
  746.         /* FIXME remove the +1 when VLC_TS_INVALID work is done */
  747.         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts+1 );
  748.         if( p_sys->i_pts >= p_sys->i_start_pts  )
  749.         {
  750.             if ( p_vsegment->UpdateCurrentToChapter( *p_demux ) )
  751.             {
  752.                 i_return = 1;
  753.                 delete block;
  754.                 break;
  755.             }
  756.         }
  757.  
  758.         if ( p_vsegment->Edition() && p_vsegment->Edition()->b_ordered && p_vsegment->CurrentChapter() == NULL )
  759.         {
  760.             /* nothing left to read in this ordered edition */
  761.             if ( !p_vsegment->SelectNext() )
  762.             {
  763.                 delete block;
  764.                 break;
  765.             }
  766.             p_segment->UnSelect( );
  767.  
  768.             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  769.             /* switch to the next segment */
  770.             p_segment = p_vsegment->Segment();
  771.             if ( !p_segment->Select( 0 ) )
  772.             {
  773.                 msg_Err( p_demux, "Failed to select new segment" );
  774.                 delete block;
  775.                 break;
  776.             }
  777.             delete block;
  778.             continue;
  779.         }
  780.         BlockDecode( p_demux, block, simpleblock, p_sys->i_pts, i_block_duration, i_block_ref1 >= 0 || i_block_ref2 > 0 );
  781.         delete block;
  782.         i_block_count++;
  783.         // TODO optimize when there is need to leave or when seeking has been called
  784.         if( i_block_count > 5 )
  785.         {
  786.             i_return = 1;
  787.             break;
  788.         }
  789.     }
  790.     vlc_mutex_unlock( &p_sys->lock_demuxer );
  791.     return i_return;
  792. }