/* * (C) 2003-2006 Gabest * (C) 2006-2013 see Authors.txt * * This file is part of MPC-HC. * * MPC-HC is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * MPC-HC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #pragma once #include #include #include "../BaseSplitter/BaseSplitter.h" #include "../../../DSUtil/GolombBuffer.h" #define NO_SUBTITLE_PID 1 // Fake PID use for the "No subtitle" entry #define NO_SUBTITLE_NAME _T("No subtitle") #define ISVALIDPID(pid) (pid >= 0x10 && pid < 0x1fff) //#define MVC_SUPPORT class CMpegSplitterFile : public CBaseSplitterFileEx { CAtlMap m_pid2pes; CAtlMap avch; bool m_bIsHdmv; bool m_init; HRESULT Init(IAsyncReader* pAsyncReader); void OnComplete(IAsyncReader* pAsyncReader); public: CHdmvClipInfo& m_ClipInfo; CMpegSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr, bool bIsHdmv, CHdmvClipInfo& ClipInfo, int guid_flag, bool ForcedSub, int AC3CoreOnly, bool m_AlternativeDuration); REFERENCE_TIME NextPTS(DWORD TrackNum); CCritSec m_csProps; MPEG_TYPES m_type; REFERENCE_TIME m_rtMin, m_rtMax; __int64 m_posMin, m_posMax; REFERENCE_TIME m_rtPrec; bool m_bPTSWrap; int m_rate; // byte/sec int m_nVC1_GuidFlag, m_AC3CoreOnly; bool m_ForcedSub, m_AlternativeDuration; struct stream { CMpegSplitterFile* m_pFile; CMediaType mt; WORD pid; BYTE pesid, ps1id; struct stream() : m_pFile(0) { pid = pesid = ps1id = 0; } operator DWORD() const { return pid ? pid : ((pesid << 8) | ps1id); } bool operator == (const struct stream& s) const { return (DWORD) * this == (DWORD)s; } }; enum { video, audio, subpic, #if defined(MVC_SUPPORT) stereo, #endif unknown }; class CStreamList : public CAtlList { public: void Insert(stream& s, CMpegSplitterFile* _pFile) { s.m_pFile = _pFile; AddTail(s); if (GetCount() > 1) { for (size_t j = 0; j < GetCount(); j++) { for (size_t i = 0; i < GetCount() - 1; i++) { if (GetAt(FindIndex(i)) > GetAt(FindIndex(i + 1))) { SwapElements(FindIndex(i), FindIndex(i + 1)); } } } } } void Replace(stream& source, stream& dest, CMpegSplitterFile* _pFile) { source.m_pFile = _pFile; dest.m_pFile = _pFile; for (POSITION pos = GetHeadPosition(); pos; GetNext(pos)) { stream& s = GetAt(pos); if (source == s) { SetAt(pos, dest); return; } } } static CStringW ToString(int type) { return type == video ? L"Video" : type == audio ? L"Audio" : type == subpic ? L"Subtitle" : #if defined(MVC_SUPPORT) type == stereo ? L"Stereo" : #endif L"Unknown"; } const stream* FindStream(int pid) { for (POSITION pos = GetHeadPosition(); pos; GetNext(pos)) { const stream& s = GetAt(pos); if (s.pid == pid) { return &s; } } return NULL; } } m_streams[unknown]; HRESULT SearchStreams(__int64 start, __int64 stop, IAsyncReader* pAsyncReader, BOOL CalcDuration = FALSE); DWORD AddStream(WORD pid, BYTE pesid, BYTE ps1id, DWORD len); void AddHdmvPGStream(WORD pid, const char* language_code); CAtlList* GetMasterStream(); bool IsHdmv() { return m_bIsHdmv; }; struct program { WORD program_number; struct stream { WORD pid; PES_STREAM_TYPE type; }; stream streams[64]; struct program() { memset(this, 0, sizeof(*this)); } BYTE ts_buffer[1024]; WORD ts_len_cur, ts_len_packet; }; CAtlMap m_programs; void SearchPrograms(__int64 start, __int64 stop); void UpdatePrograms(const tshdr& h, bool UpdateLang = true); void UpdatePrograms(CGolombBuffer gb, WORD pid, bool UpdateLang = true); const program* FindProgram(WORD pid, int& iStream, const CHdmvClipInfo::Stream*& _pClipInfo); CAtlMap m_pPMT_Lang; bool GetStreamType(WORD pid, PES_STREAM_TYPE& stream_type); };