📄 mkv.cpp
字号:
vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/#ifdef HAVE_ZLIB_Hblock_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) { int result, dstsize, n; unsigned char *dst; block_t *p_block; z_stream d_stream; d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; result = inflateInit(&d_stream); if( result != Z_OK ) { msg_Dbg( p_this, "inflateInit() failed. Result: %d", result ); return NULL; } d_stream.next_in = (Bytef *)p_in_block->p_buffer; d_stream.avail_in = p_in_block->i_buffer; n = 0; p_block = block_New( p_this, 0 ); dst = NULL; do { n++; p_block = block_Realloc( p_block, 0, n * 1000 ); dst = (unsigned char *)p_block->p_buffer; d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000]; d_stream.avail_out = 1000; result = inflate(&d_stream, Z_NO_FLUSH); if( ( result != Z_OK ) && ( result != Z_STREAM_END ) ) { msg_Dbg( p_this, "Zlib decompression failed. Result: %d", result ); return NULL; } } while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) && ( result != Z_STREAM_END ) ); dstsize = d_stream.total_out; inflateEnd( &d_stream ); p_block = block_Realloc( p_block, 0, dstsize ); p_block->i_buffer = dstsize; block_Release( p_in_block ); return p_block;}#endif/** * Helper function to print the mkv parse tree */static void MkvTree( demux_t & demuxer, int i_level, char *psz_format, ... ){ va_list args; if( i_level > 9 ) { msg_Err( &demuxer, "too deep tree" ); return; } va_start( args, psz_format ); static char *psz_foo = "| | | | | | | | | |"; char *psz_foo2 = (char*)malloc( ( i_level * 4 + 3 + strlen( psz_format ) ) * sizeof(char) ); strncpy( psz_foo2, psz_foo, 4 * i_level ); psz_foo2[ 4 * i_level ] = '+'; psz_foo2[ 4 * i_level + 1 ] = ' '; strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format ); __msg_GenericVa( VLC_OBJECT(&demuxer), VLC_MSG_DBG, "mkv", psz_foo2, args ); free( psz_foo2 ); va_end( args );} /***************************************************************************** * Stream managment *****************************************************************************/class vlc_stream_io_callback: public IOCallback{ private: stream_t *s; vlc_bool_t mb_eof; vlc_bool_t b_owner; public: vlc_stream_io_callback( stream_t *, vlc_bool_t ); virtual ~vlc_stream_io_callback() { if( b_owner ) stream_Delete( s ); } virtual uint32 read ( void *p_buffer, size_t i_size); virtual void setFilePointer ( int64_t i_offset, seek_mode mode = seek_beginning ); virtual size_t write ( const void *p_buffer, size_t i_size); virtual uint64 getFilePointer ( void ); virtual void close ( void );};/***************************************************************************** * Ebml Stream parser *****************************************************************************/class EbmlParser{ public: EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux ); virtual ~EbmlParser( void ); void Up( void ); void Down( void ); void Reset( demux_t *p_demux ); EbmlElement *Get( void ); void Keep( void ); EbmlElement *UnGet( uint64 i_block_pos, uint64 i_cluster_pos ); int GetLevel( void ); private: EbmlStream *m_es; int mi_level; EbmlElement *m_el[10]; int64_t mi_remain_size[10]; EbmlElement *m_got; int mi_user_level; vlc_bool_t mb_keep; vlc_bool_t mb_dummy;};/***************************************************************************** * Some functions to manipulate memory *****************************************************************************/#define GetFOURCC( p ) __GetFOURCC( (uint8_t*)p )static vlc_fourcc_t __GetFOURCC( uint8_t *p ){ return VLC_FOURCC( p[0], p[1], p[2], p[3] );}/***************************************************************************** * definitions of structures and functions used by this plugins *****************************************************************************/typedef struct{ vlc_bool_t b_default; vlc_bool_t b_enabled; unsigned int i_number; int i_extra_data; uint8_t *p_extra_data; char *psz_codec; uint64_t i_default_duration; float f_timecodescale; /* video */ es_format_t fmt; float f_fps; es_out_id_t *p_es; vlc_bool_t b_inited; /* data to be send first */ int i_data_init; uint8_t *p_data_init; /* hack : it's for seek */ vlc_bool_t b_search_keyframe; vlc_bool_t b_silent; /* informative */ char *psz_codec_name; char *psz_codec_settings; char *psz_codec_info_url; char *psz_codec_download_url; /* encryption/compression */ int i_compression_type;} mkv_track_t;typedef struct{ int i_track; int i_block_number; int64_t i_position; int64_t i_time; vlc_bool_t b_key;} mkv_index_t;class demux_sys_t;const binary MATROSKA_DVD_LEVEL_SS = 0x30;const binary MATROSKA_DVD_LEVEL_LU = 0x2A;const binary MATROSKA_DVD_LEVEL_TT = 0x28;const binary MATROSKA_DVD_LEVEL_PGC = 0x20;const binary MATROSKA_DVD_LEVEL_PG = 0x18;const binary MATROSKA_DVD_LEVEL_PTT = 0x10;const binary MATROSKA_DVD_LEVEL_CN = 0x08;class chapter_codec_cmds_c{public: chapter_codec_cmds_c( demux_sys_t & demuxer, int codec_id = -1) :p_private_data(NULL) ,i_codec_id( codec_id ) ,sys( demuxer ) {} virtual ~chapter_codec_cmds_c() { delete p_private_data; std::vector<KaxChapterProcessData*>::iterator indexe = enter_cmds.begin(); while ( indexe != enter_cmds.end() ) { delete (*indexe); indexe++; } std::vector<KaxChapterProcessData*>::iterator indexl = leave_cmds.begin(); while ( indexl != leave_cmds.end() ) { delete (*indexl); indexl++; } std::vector<KaxChapterProcessData*>::iterator indexd = during_cmds.begin(); while ( indexd != during_cmds.end() ) { delete (*indexd); indexd++; } } void SetPrivate( const KaxChapterProcessPrivate & private_data ) { p_private_data = new KaxChapterProcessPrivate( private_data ); } void AddCommand( const KaxChapterProcessCommand & command ); /// \return wether the codec has seeked in the files or not virtual bool Enter() { return false; } virtual bool Leave() { return false; } virtual std::string GetCodecName( bool f_for_title = false ) const { return ""; } virtual int16 GetTitleNumber() { return -1; } KaxChapterProcessPrivate *p_private_data;protected: std::vector<KaxChapterProcessData*> enter_cmds; std::vector<KaxChapterProcessData*> during_cmds; std::vector<KaxChapterProcessData*> leave_cmds; int i_codec_id; demux_sys_t & sys;};class dvd_command_interpretor_c{public: dvd_command_interpretor_c( demux_sys_t & demuxer ) :sys( demuxer ) { memset( p_PRMs, 0, sizeof(p_PRMs) ); p_PRMs[ 0x80 + 1 ] = 15; p_PRMs[ 0x80 + 2 ] = 62; p_PRMs[ 0x80 + 3 ] = 1; p_PRMs[ 0x80 + 4 ] = 1; p_PRMs[ 0x80 + 7 ] = 1; p_PRMs[ 0x80 + 8 ] = 1; p_PRMs[ 0x80 + 16 ] = 0xFFFFu; p_PRMs[ 0x80 + 18 ] = 0xFFFFu; } bool Interpret( const binary * p_command, size_t i_size = 8 ); uint16 GetPRM( size_t index ) const { if ( index < 256 ) return p_PRMs[ index ]; else return 0; } uint16 GetGPRM( size_t index ) const { if ( index >= 0 && index < 16 ) return p_PRMs[ index ]; else return 0; } uint16 GetSPRM( size_t index ) const { // 21,22,23 reserved for future use if ( index >= 0x80 && index < 0x95 ) return p_PRMs[ index ]; else return 0; } bool SetPRM( size_t index, uint16 value ) { if ( index >= 0 && index < 16 ) { p_PRMs[ index ] = value; return true; } return false; } bool SetGPRM( size_t index, uint16 value ) { if ( index >= 0 && index < 16 ) { p_PRMs[ index ] = value; return true; } return false; } bool SetSPRM( size_t index, uint16 value ) { if ( index > 0x80 && index <= 0x8D && index != 0x8C ) { p_PRMs[ index ] = value; return true; } return false; }protected: std::string GetRegTypeName( bool b_value, uint16 value ) const { std::string result; char s_value[6], s_reg_value[6]; sprintf( s_value, "%.5d", value ); if ( b_value ) { result = "value ("; result += s_value; result += ")"; } else if ( value < 0x80 ) { sprintf( s_reg_value, "%.5d", GetPRM( value ) ); result = "GPreg["; result += s_value; result += "] ("; result += s_reg_value; result += ")"; } else { sprintf( s_reg_value, "%.5d", GetPRM( value ) ); result = "SPreg["; result += s_value; result += "] ("; result += s_reg_value; result += ")"; } return result; } uint16 p_PRMs[256]; demux_sys_t & sys; // DVD command IDs // Tests // wether it's a comparison on the value or register static const uint16 CMD_DVD_TEST_VALUE = 0x80; static const uint16 CMD_DVD_IF_GPREG_AND = (1 << 4); static const uint16 CMD_DVD_IF_GPREG_EQUAL = (2 << 4); static const uint16 CMD_DVD_IF_GPREG_NOT_EQUAL = (3 << 4); static const uint16 CMD_DVD_IF_GPREG_SUP_EQUAL = (4 << 4); static const uint16 CMD_DVD_IF_GPREG_SUP = (5 << 4); static const uint16 CMD_DVD_IF_GPREG_INF_EQUAL = (6 << 4); static const uint16 CMD_DVD_IF_GPREG_INF = (7 << 4); static const uint16 CMD_DVD_NOP = 0x0000; static const uint16 CMD_DVD_GOTO_LINE = 0x0001; static const uint16 CMD_DVD_BREAK = 0x0002; // Links static const uint16 CMD_DVD_NOP2 = 0x2001; static const uint16 CMD_DVD_LINKPGCN = 0x2004; static const uint16 CMD_DVD_LINKPGN = 0x2006; static const uint16 CMD_DVD_LINKCN = 0x2007; static const uint16 CMD_DVD_JUMP_TT = 0x3002; static const uint16 CMD_DVD_JUMPVTS_TT = 0x3003; static const uint16 CMD_DVD_JUMPVTS_PTT = 0x3005; static const uint16 CMD_DVD_JUMP_SS = 0x3006; static const uint16 CMD_DVD_CALLSS_VTSM1 = 0x3008; // static const uint16 CMD_DVD_SET_HL_BTNN2 = 0x4600; static const uint16 CMD_DVD_SET_HL_BTNN_LINKPGCN1 = 0x4604; static const uint16 CMD_DVD_SET_STREAM = 0x5100; static const uint16 CMD_DVD_SET_GPRMMD = 0x5300; static const uint16 CMD_DVD_SET_HL_BTNN1 = 0x5600; static const uint16 CMD_DVD_SET_HL_BTNN_LINKPGCN2 = 0x5604; static const uint16 CMD_DVD_SET_HL_BTNN_LINKCN = 0x5607; // Operations static const uint16 CMD_DVD_MOV_SPREG_PREG = 0x6100;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -