Changeset 5bc8ca51c941b558cfa42eccb71cb9f37e0f161f
- Timestamp:
- 09/02/05 11:09:41 (4 years ago)
- git-parent:
- Files:
-
- configure.ac (modified) (2 diffs)
- modules/demux/mkv.cpp (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
configure.ac
rbe52d3f r5bc8ca5 304 304 305 305 dnl Check for usual libc functions 306 AC_CHECK_FUNCS(strdup strndup atof lseek)306 AC_CHECK_FUNCS(strdup strndup atof) 307 307 AC_CHECK_FUNCS(strcasecmp,,[AC_CHECK_FUNCS(stricmp)]) 308 308 AC_CHECK_FUNCS(strncasecmp,,[AC_CHECK_FUNCS(strnicmp)]) … … 1757 1757 AC_LANG_PUSH(C++) 1758 1758 AC_CHECK_HEADERS(ebml/EbmlVersion.h, [ 1759 AC_CHECK_HEADERS(matroska/KaxVersion.h, [ 1760 AC_CHECK_HEADERS(matroska/KaxAttachments.h) 1761 VLC_ADD_CXXFLAGS([mkv],[]) 1762 AC_CHECK_LIB(ebml_pic, main, [ 1763 # We have ebml_pic, that's good, we can build an mkv.so plugin ! 1764 VLC_ADD_PLUGINS([mkv]) 1765 VLC_ADD_LDFLAGS([mkv],[-lmatroska_pic -lebml_pic]) 1766 ], [ 1767 AC_CHECK_LIB(ebml, main, [ 1768 # We only have libebml, make mkv.a a builtin 1769 VLC_ADD_BUILTINS([mkv]) 1770 VLC_ADD_LDFLAGS([mkv],[-lmatroska -lebml]) 1759 AC_MSG_CHECKING(for libebml version >= 0.7.3) 1760 AC_EGREP_CPP(yes, 1761 [#include <ebml/EbmlVersion.h> 1762 #ifdef LIBEBML_VERSION 1763 #if LIBEBML_VERSION >= 0x000703 1764 yes 1765 #endif 1766 #endif], 1767 [AC_MSG_RESULT([yes]) 1768 AC_CHECK_HEADERS(matroska/KaxVersion.h, [ 1769 AC_MSG_CHECKING(for libmatroska version >= 0.7.5) 1770 AC_EGREP_CPP(yes, 1771 [#include <matroska/KaxVersion.h> 1772 #ifdef LIBMATROSKA_VERSION 1773 #if LIBMATROSKA_VERSION >= 0x000705 1774 yes 1775 #endif 1776 #endif], 1777 [AC_MSG_RESULT([yes]) 1778 AC_CHECK_HEADERS(matroska/KaxAttachments.h) 1779 VLC_ADD_CXXFLAGS([mkv],[]) 1780 AC_CHECK_LIB(ebml_pic, main, [ 1781 # We have ebml_pic, that's good, we can build an mkv.so plugin ! 1782 VLC_ADD_PLUGINS([mkv]) 1783 VLC_ADD_LDFLAGS([mkv],[-lmatroska_pic -lebml_pic]) 1784 ], [ 1785 AC_CHECK_LIB(ebml, main, [ 1786 # We only have libebml, make mkv.a a builtin 1787 VLC_ADD_BUILTINS([mkv]) 1788 VLC_ADD_LDFLAGS([mkv],[-lmatroska -lebml]) 1789 ]) 1790 ]) 1791 ], 1792 [AC_MSG_RESULT([no]) 1793 AC_MSG_ERROR([Your libmatroska is too old: you may get a more recent one from http://dl.matroska.org/downloads/libmatroska/. Alternatively you can use --disable-mkv to disable the matroska plugin.]) 1794 ]) 1771 1795 ]) 1772 ]) 1796 ], 1797 [AC_MSG_RESULT([no]) 1798 AC_MSG_ERROR([Your libebml is too old: you may get a more recent one from http://dl.matroska.org/downloads/libebml/. Alternatively you can use --disable-mkv to disable the matroska plugin.]) 1773 1799 ]) 1774 1800 ]) modules/demux/mkv.cpp
r94dfa75 r5bc8ca5 6 6 * 7 7 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 8 * Steve Lhomme <steve.lhomme@free.fr> 8 9 * 9 10 * This program is free software; you can redistribute it and/or modify … … 42 43 #include <cassert> 43 44 #include <typeinfo> 45 #include <string> 46 #include <vector> 47 48 #ifdef HAVE_DIRENT_H 49 # include <dirent.h> 50 #elif defined( UNDER_CE ) 51 # include <windows.h> /* GetFileAttributes() */ 52 #else 53 # include "../../src/extras/dirent.h" 54 #endif 44 55 45 56 /* libebml and matroska */ … … 50 61 #include "ebml/EbmlVersion.h" 51 62 #include "ebml/EbmlVoid.h" 52 53 #include "matroska/FileKax.h" 63 #include "ebml/StdIOCallback.h" 64 54 65 #include "matroska/KaxAttachments.h" 55 66 #include "matroska/KaxBlock.h" … … 86 97 #define MATROSKA_COMPRESSION_ZLIB 1 87 98 99 /** 100 * What's between a directory and a filename? 101 */ 102 #if defined( WIN32 ) 103 #define DIRECTORY_SEPARATOR '\\' 104 #else 105 #define DIRECTORY_SEPARATOR '/' 106 #endif 107 88 108 using namespace LIBMATROSKA_NAMESPACE; 89 109 using namespace std; … … 299 319 } mkv_index_t; 300 320 301 struct demux_sys_t 302 { 321 class demux_sys_t 322 { 323 public: 324 demux_sys_t() 325 :in(NULL) 326 ,es(NULL) 327 ,ep(NULL) 328 ,i_timescale(0) 329 ,f_duration(0.0) 330 ,i_track(0) 331 ,track(NULL) 332 ,i_cues_position(0) 333 ,i_chapters_position(0) 334 ,i_tags_position(0) 335 ,segment(NULL) 336 ,cluster(NULL) 337 ,i_pts(0) 338 ,b_cues(false) 339 ,i_index(0) 340 ,i_index_max(0) 341 ,index(NULL) 342 ,psz_muxing_application(NULL) 343 ,psz_writing_application(NULL) 344 ,psz_segment_filename(NULL) 345 ,psz_title(NULL) 346 ,psz_date_utc(NULL) 347 ,meta(NULL) 348 ,title(NULL) 349 {} 350 303 351 vlc_stream_io_callback *in; 304 352 EbmlStream *es; … … 323 371 KaxSegment *segment; 324 372 KaxCluster *cluster; 373 KaxSegmentUID segment_uid; 325 374 326 375 mtime_t i_pts; … … 341 390 342 391 input_title_t *title; 392 393 std::vector<KaxSegmentFamily> families; 394 std::vector<KaxSegment*> family_members; 343 395 }; 344 396 … … 365 417 demux_sys_t *p_sys; 366 418 uint8_t *p_peek; 419 std::string s_path, s_filename; 420 int i_upper_lvl; 421 size_t i, j; 367 422 368 423 int i_track; … … 390 445 p_demux->pf_demux = Demux; 391 446 p_demux->pf_control = Control; 392 p_demux->p_sys = p_sys = (demux_sys_t*)malloc(sizeof( demux_sys_t )); 393 394 memset( p_sys, 0, sizeof( demux_sys_t ) ); 447 p_demux->p_sys = p_sys = new demux_sys_t; 448 395 449 p_sys->in = new vlc_stream_io_callback( p_demux->s ); 396 450 p_sys->es = new EbmlStream( *p_sys->in ); … … 422 476 msg_Err( p_demux, "failed to create EbmlStream" ); 423 477 delete p_sys->in; 424 free( p_sys );478 delete p_sys; 425 479 return VLC_EGENERIC; 426 480 } … … 496 550 } 497 551 } 552 553 /* get the files from the same dir from the same family (based on p_demux->psz_path) */ 554 /* _todo_ handle multi-segment files */ 555 if (p_demux->psz_path[0] != '\0' && (!strcmp(p_demux->psz_access, "") || !strcmp(p_demux->psz_access, ""))) 556 { 557 // assume it's a regular file 558 // get the directory path 559 s_path = p_demux->psz_path; 560 if (s_path.at(s_path.length() - 1) == DIRECTORY_SEPARATOR) 561 { 562 s_path = s_path.substr(0,s_path.length()-1); 563 } 564 else 565 { 566 if (s_path.find_last_of(DIRECTORY_SEPARATOR) > 0) 567 { 568 s_path = s_path.substr(0,s_path.find_last_of(DIRECTORY_SEPARATOR)); 569 } 570 } 571 572 struct dirent *p_file_item; 573 DIR *p_src_dir = opendir(s_path.c_str()); 574 575 if (p_src_dir != NULL) 576 { 577 while (p_file_item = readdir(p_src_dir)) 578 { 579 if (p_file_item->d_namlen > 4) 580 { 581 s_filename = s_path + DIRECTORY_SEPARATOR + p_file_item->d_name; 582 583 if (!s_filename.compare(p_demux->psz_path)) 584 continue; 585 586 if (!s_filename.compare(s_filename.length() - 3, 3, "mkv") || 587 !s_filename.compare(s_filename.length() - 3, 3, "mka")) 588 { 589 // test wether this file belongs to the our family 590 bool b_keep_file_opened = false; 591 StdIOCallback *p_file_io = new StdIOCallback(s_filename.c_str(), MODE_READ); 592 EbmlStream *p_stream = new EbmlStream(*p_file_io); 593 EbmlElement *p_l0, *p_l1, *p_l2; 594 595 // verify the EBML Header 596 p_l0 = p_stream->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL); 597 if (p_l0 == NULL) 598 { 599 delete p_stream; 600 delete p_file_io; 601 continue; 602 } 603 604 p_l0->SkipData(*p_stream, EbmlHead_Context); 605 delete p_l0; 606 607 // find all segments in this file 608 p_l0 = p_stream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL); 609 if (p_l0 == NULL) 610 { 611 delete p_stream; 612 delete p_file_io; 613 continue; 614 } 615 616 i_upper_lvl = 0; 617 618 while (p_l0 != 0) 619 { 620 if (EbmlId(*p_l0) == KaxSegment::ClassInfos.GlobalId) 621 { 622 EbmlParser *ep; 623 KaxSegmentUID *p_uid = NULL; 624 625 ep = new EbmlParser(p_stream, p_l0); 626 bool b_this_segment_matches = false; 627 while (p_l1 = ep->Get()) 628 { 629 if (MKV_IS_ID(p_l1, KaxInfo)) 630 { 631 // find the families of this segment 632 KaxInfo *p_info = static_cast<KaxInfo*>(p_l1); 633 634 p_info->Read(*p_stream, KaxInfo::ClassInfos.Context, i_upper_lvl, p_l2, true); 635 for( i = 0; i < p_info->ListSize() && !b_this_segment_matches; i++ ) 636 { 637 EbmlElement *l = (*p_info)[i]; 638 639 if( MKV_IS_ID( l, KaxSegmentUID ) ) 640 { 641 p_uid = static_cast<KaxSegmentUID*>(l); 642 if (p_sys->segment_uid == *p_uid) 643 break; 644 } 645 else if( MKV_IS_ID( l, KaxSegmentFamily ) ) 646 { 647 KaxSegmentFamily *p_fam = static_cast<KaxSegmentFamily*>(l); 648 for (j=0; j<p_sys->families.size(); j++) 649 { 650 if (p_sys->families.at(j) == *p_fam) 651 { 652 b_this_segment_matches = true; 653 break; 654 } 655 } 656 } 657 } 658 break; 659 } 660 } 661 662 if (b_this_segment_matches) 663 { 664 b_keep_file_opened = true; 665 } 666 } 667 668 p_l0->SkipData(*p_stream, EbmlHead_Context); 669 delete p_l0; 670 p_l0 = p_stream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL); 671 } 672 673 if (!b_keep_file_opened) 674 { 675 delete p_stream; 676 delete p_file_io; 677 } 678 } 679 } 680 } 681 closedir( p_src_dir ); 682 } 683 } 684 498 685 499 686 if( p_sys->cluster == NULL ) … … 740 927 tk.fmt.audio.i_blockalign = ( tk.fmt.audio.i_bitspersample + 7 ) / 8 * tk.fmt.audio.i_channels; 741 928 } 929 else if( !strcmp( tk.psz_codec, "A_TTA1" ) ) 930 { 931 /* FIXME: support this codec */ 932 msg_Err( p_demux, "TTA not supported yet[%d, n=%d]", i_track, tk.i_number ); 933 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' ); 934 } 935 else if( !strcmp( tk.psz_codec, "A_WAVPACK4" ) ) 936 { 937 /* FIXME: support this codec */ 938 msg_Err( p_demux, "Wavpack not supported yet[%d, n=%d]", i_track, tk.i_number ); 939 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' ); 940 } 742 941 else if( !strcmp( tk.psz_codec, "S_TEXT/UTF8" ) ) 743 942 { … … 776 975 } 777 976 } 977 else if( !strcmp( tk.psz_codec, "B_VOBBTN" ) ) 978 { 979 /* FIXME: support this codec */ 980 msg_Err( p_demux, "Vob Buttons not supported yet[%d, n=%d]", i_track, tk.i_number ); 981 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' ); 982 } 778 983 else 779 984 { … … 798 1003 delete p_sys->es; 799 1004 delete p_sys->in; 800 free( p_sys );1005 delete p_sys; 801 1006 return VLC_EGENERIC; 802 1007 } … … 844 1049 delete p_sys->es; 845 1050 delete p_sys->in; 846 847 free( p_sys ); 1051 delete p_sys; 848 1052 } 849 1053 … … 1101 1305 if( tk.p_es == NULL ) 1102 1306 { 1307 msg_Err( p_demux, "unknown track number=%d", block->TrackNum() ); 1103 1308 return; 1104 1309 } … … 2312 2517 if( MKV_IS_ID( l, KaxSegmentUID ) ) 2313 2518 { 2314 KaxSegmentUID &uid = *(KaxSegmentUID*)l;2315 2316 msg_Dbg( p_demux, "| | + UID=%d", uint32(uid) );2519 p_sys->segment_uid = *(new KaxSegmentUID(*static_cast<KaxSegmentUID*>(l))); 2520 2521 msg_Dbg( p_demux, "| | + UID=%d", *(uint32*)p_sys->segment_uid.GetBuffer() ); 2317 2522 } 2318 2523 else if( MKV_IS_ID( l, KaxTimecodeScale ) ) … … 2368 2573 2369 2574 msg_Dbg( p_demux, "| | + Title=%s", p_sys->psz_title ); 2575 } 2576 if( MKV_IS_ID( l, KaxSegmentFamily ) ) 2577 { 2578 KaxSegmentFamily *uid = static_cast<KaxSegmentFamily*>(l); 2579 2580 p_sys->families.push_back(*uid); 2581 2582 msg_Dbg( p_demux, "| | + family=%d", *(uint32*)uid->GetBuffer() ); 2370 2583 } 2371 2584 #if defined( HAVE_GMTIME_R ) && !defined( SYS_DARWIN )
