www.pudn.com > VOBSUB.rar > DirectVobSubFilter.h
#pragma once #include#include #include "DirectVobSub.h" #include "../vobsub/vobsub.h" #include "MyCustomAllocator.h" #define MAXSUBIMAGECACHE 10 // ms #define LOOKAHEADSIZE 60000 #define LOOKAHEADSTEPSIZE 10 class CDirectVobSubFilter; typedef struct { public: HBITMAP hbm; int start, stop; void Clear(uint c); void ConvertToYUY2(); } SubImage; typedef struct { HWND hSystrayWnd; IFilterGraph* graph; IDirectVobSub* dvs; bool fRunOnce, fShowIcon; } SystrayIconData; /* This is for graphedit */ class CDirectVobSubFilter : public CTransformFilter, public CDirectVobSub, public ISpecifyPropertyPages, public IAMStreamSelect, public CAMThread { friend class CDirectVobSubInputPin; friend class CDirectVobSubOutputPin; friend class CTextInputPin; #ifdef DEBUG DWORD dwRegister; #endif public: DECLARE_IUNKNOWN; static CUnknown* WINAPI CreateInstance(LPUNKNOWN punk, HRESULT* phr); STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv); HRESULT InitializeOutputSample(IMediaSample* pSample, IMediaSample** ppOutSample); // Overriden from CTransformFilter base class HRESULT Receive(IMediaSample* pSample), Transform(IMediaSample* pIn, IMediaSample* pOut), CheckInputType(const CMediaType* mtIn), CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut), DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties), GetMediaType(int iPosition, CMediaType* pMediaType), SetMediaType(PIN_DIRECTION direction, const CMediaType* pMediaType), CheckConnect(PIN_DIRECTION direction, IPin* pPin), CompleteConnect(PIN_DIRECTION direction, IPin* pReceivePin), BreakConnect(PIN_DIRECTION direction), StartStreaming(), StopStreaming(), NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); HRESULT CheckOutputType(const CMediaType* mtOut); // Overriden from CBaseFilter base class STDMETHODIMP JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName); STDMETHODIMP SetSyncSource(IReferenceClock* pClock); STDMETHODIMP QueryFilterInfo(FILTER_INFO* pInfo); CArray m_pTextInput; CMyCustomAllocator m_Allocator; bool m_fUsingOwnAllocator; CBasePin* GetPin(int n); int GetPinCount(); // IDirectVobSub STDMETHODIMP put_FileName(WCHAR* fn); STDMETHODIMP get_LanguageCount(int* nLangs); STDMETHODIMP get_LanguageName(int iLanguage, WCHAR** ppName); STDMETHODIMP put_SelectedLanguage(int iSelected); STDMETHODIMP put_PreBuffering(bool fDoPreBuffering); STDMETHODIMP put_Placement(bool fOverridePlacement, int xperc, int yperc); STDMETHODIMP put_VobSubSettings(bool fBuffer, bool fOnlyShowForcedSubs, bool fPolygonize); STDMETHODIMP put_TextSettings(void* lf, int lflen, COLORREF color, bool fShadow, bool fOutline, bool fAdvancedRenderer); STDMETHODIMP put_SubtitleTiming(int delay, int speedmul, int speeddiv); STDMETHODIMP get_MediaFPS(bool* fEnabled, double* fps); STDMETHODIMP put_MediaFPS(bool fEnabled, double fps); STDMETHODIMP get_ZoomRect(NORMALIZEDRECT* rect); STDMETHODIMP put_ZoomRect(NORMALIZEDRECT* rect); STDMETHODIMP get_ColorFormat(int* iPosition); STDMETHODIMP put_ColorFormat(int iPosition); STDMETHODIMP HasConfigDialog(int iSelected); STDMETHODIMP ShowConfigDialog(int iSelected, HWND hWndParent); // ISpecifyPropertyPages STDMETHODIMP GetPages(CAUUID* pPages); // IAMStreamSelect STDMETHODIMP Count(DWORD* pcStreams); STDMETHODIMP Enable(long lIndex, DWORD dwFlags); STDMETHODIMP Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk); // CPersistStream STDMETHODIMP GetClassID(CLSID* pClsid); protected: CDirectVobSubFilter(TCHAR* tszName, LPUNKNOWN punk, HRESULT* phr, const GUID& guid); virtual ~CDirectVobSubFilter(); protected: BITMAPINFOHEADER m_bihIn, m_bihSub, m_bihOut; HRESULT ChangeMediaType(int iPosition); bool AdjustFrameSize(int& w, int& h); HRESULT ConvertMediaTypeInputToOutput(CMediaType* pmt, int iVIHTemplate = -1, bool fVIH2 = false); HRESULT Copy(BYTE* pOut, BYTE* pIn, SubImage* img); HRESULT CopyYV12(BYTE* pOut, BYTE* pIn, SubImage* img); HDC m_hdc; HBITMAP m_hbm; HFONT m_hfont; void PrintMessages(BYTE* pOut); /* ResX2 */ BYTE* m_pTempPicBuff; bool m_fResX2Active; void Scale2x(BYTE* pOut, BYTE* pIn); // segment start time, absolute time CRefTime m_tOff, m_tPrev; int CalcCurrentTime(); double m_fps; // needed when opening a saved .grp // without reconnecting we may not start playing bool m_fAudioReconnected; // 3.x- versions of microsoft's mpeg4 codec output flipped image bool m_fMSMpeg4Fix; // DivxPlus puts our picture upside-down on the tv bool m_fDivxPlusFix; // don't set the "hide subtitles" stream until we are finished with loading bool m_fLoading; bool Open(); typedef enum {NONE, VOBSUB, TEXT} smode; smode m_mode; // lock for all subtitle sources (m_file, m_textlangs) CCritSec m_fileLock; int FindPreferedLanguage(bool fHideToo = true); void UpdatePreferedLanguages(CString lang); // int m_curIndex; // vobsub file CVobSubFile* m_file; typedef CArray TextLangs; TextLangs m_textlangs; int m_textidx; bool InitRTSStreams(bool fApplyDefStyle = true); // the text input pin is using these void AddTextStream(CString name); void AddNewEntryToTextStream(CString name, CString str, int start, int end); void ChangeName(CString oldname, CString newname, bool fUnicode); void ChangeName(CString oldname, CString newname); void RemoveEntriesFromTextStream(CString name); void RemoveTextStream(CString name); void OpenRawTextSubtitle(CString name, BYTE* data, int len); // Whether the text output pins of AVI splitter get connected to our input pins // depends on their rendering order. Since I haven't found a better way yet, we // just simply reconnect them to ours... bool m_fTextStreamWorkaroundDone; void HookTextStreams(); // support for EC_OLE_EVENT void Post_EC_OLE_EVENT(); int m_iLastSegmentPosted; protected: class SubImageCache { HDC hdc; HFONT hfont; SubImage imgs[MAXSUBIMAGECACHE]; int pos, size, start, stop; void RemoveOldest(); public: int w, h; SubImageCache(); virtual ~SubImageCache(); void Init(int width, int heigth), DeInit(); void SetFont(LOGFONT* lf); void Update(int PTS); void RemoveAll(); void FreeExtra(int PTS); void MarkAsStart(int PTS), MarkAsEnd(int PTS); int SeekToEnd(int PTS); bool CachedEnough(), CachedEnough(int PTS); SubImage * LookupSubImage(int PTS), * GetSubImage(int i), // i is a logical value ((pos+i)%MAXSUBIMAGECACHE) * GetLast(), * GetNextFree(); // returns a pointer to the first free slot in the queue (or NULL when full) // call this after being ready with setting up what GetNextFree() returned // it will also do a stop = imgs['next'].stop void MarkNextAsOccupied(); void GetStats(int& start, int& stop, int& pos, int& size); int GetSize() {return(size);} HDC GetDC() {return(hdc);} // we would need a lock on hdc and a ReleaseDC() too, but it works just fine without it... HFONT GetFont() {return(hfont);} CCritSec m_csAccessLock; }; SubImageCache m_sic; enum {CMD_EXIT, CMD_INIT, CMD_RESET, CMD_BREAK, CMD_SETFONT, CMD_SETPTS}; DWORD ThreadProc(); bool m_fThreadActive, m_fBreakBuffering; SubImage* GetSubImage(); void AddVobSub(SubImage* img, int start, int stop); void AddText(SubImage* img, int start, int stop, int PTS); private: class CFileReloaderData { public: HANDLE hThread, hEndThreadEvent, hRefreshEvent; CStringArray files; CArray mtime; CDirectVobSubFilter* pFilter; } m_frd; static void SetupFRD(CFileReloaderData* frd, CStringArray& paths, CArray & handles); static DWORD WINAPI FileReloaderThreadProc(LPVOID lpParameter); private: HANDLE m_hSystrayThread; SystrayIconData m_tbid; private: bool m_fVMRFilter, m_fVMRFilterActive; /* private: CComPtr m_pDD; */ }; /* The "auto-loading" version */ class CDirectVobSubFilter2 : public CDirectVobSubFilter { bool ShouldWeAutoload(IFilterGraph* pGraph); void GetRidOfInternalScriptRenderer(); public: static CUnknown* WINAPI CreateInstance(LPUNKNOWN punk, HRESULT* phr); // Overriden from CTransformFilter base class HRESULT CheckConnect(PIN_DIRECTION dir, IPin* pPin); STDMETHODIMP JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName); HRESULT CheckInputType(const CMediaType* mtIn); STDMETHODIMP GetClassID(CLSID* pClsid); private: CDirectVobSubFilter2(TCHAR* tszName, LPUNKNOWN punk, HRESULT* phr, const GUID& guid); };