Minor change: get_PreBuffering and put_PreBuffering now work more properly.
[xy_vsfilter.git] / src / filters / transform / vsfilter / DirectVobSub.cpp
blob51ba1d4aa8cf77c4716dbba761d7f8a767496629
1 /*
2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "stdafx.h"
23 #include "DirectVobSub.h"
24 #include "VSFilter.h"
26 CDirectVobSub::CDirectVobSub()
28 AFX_MANAGE_STATE(AfxGetStaticModuleState());
30 BYTE* pData = NULL;
31 UINT nSize = 0;
33 m_iSelectedLanguage = 0;
34 m_fHideSubtitles = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_HIDE), 0);
35 m_fDoPreBuffering = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_DOPREBUFFERING), 1);
37 m_colourSpace = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_COLOUR_SPACE), 0);
38 if( m_colourSpace!=CDirectVobSub::AUTO_GUESS &&
39 m_colourSpace!=CDirectVobSub::BT_601 &&
40 m_colourSpace!=CDirectVobSub::BT_709 )
42 m_colourSpace = CDirectVobSub::BT_601;
44 m_bt601Width = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_BT601_WIDTH), 1024);
45 m_bt601Height = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_BT601_HEIGHT), 600);
47 m_fOverridePlacement = !!theApp.GetProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_OVERRIDEPLACEMENT), 0);
48 m_PlacementXperc = theApp.GetProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_XPERC), 50);
49 m_PlacementYperc = theApp.GetProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_YPERC), 90);
50 m_fBufferVobSub = !!theApp.GetProfileInt(ResStr(IDS_R_VOBSUB), ResStr(IDS_RV_BUFFER), 1);
51 m_fOnlyShowForcedVobSubs = !!theApp.GetProfileInt(ResStr(IDS_R_VOBSUB), ResStr(IDS_RV_ONLYSHOWFORCEDSUBS), 0);
52 m_fPolygonize = !!theApp.GetProfileInt(ResStr(IDS_R_VOBSUB), ResStr(IDS_RV_POLYGONIZE), 0);
53 m_defStyle <<= theApp.GetProfileString(ResStr(IDS_R_TEXT), ResStr(IDS_RT_STYLE), _T(""));
54 m_fFlipPicture = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_FLIPPICTURE), 0);
55 m_fFlipSubtitles = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_FLIPSUBTITLES), 0);
56 m_fOSD = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_SHOWOSDSTATS), 0);
57 m_fSaveFullPath = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_SAVEFULLPATH), 0);
58 m_nReloaderDisableCount = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_DISABLERELOADER), 0) ? 1 : 0;
59 m_SubtitleDelay = theApp.GetProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_SUBTITLEDELAY), 0);
60 m_SubtitleSpeedMul = theApp.GetProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_SUBTITLESPEEDMUL), 1000);
61 m_SubtitleSpeedDiv = theApp.GetProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_SUBTITLESPEEDDIV), 1000);
62 m_fMediaFPSEnabled = !!theApp.GetProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_MEDIAFPSENABLED), 0);
63 m_ePARCompensationType = static_cast<CSimpleTextSubtitle::EPARCompensationType>(theApp.GetProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_AUTOPARCOMPENSATION), 0));
65 m_overlay_cache_max_item_num = theApp.GetProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_OVERLAY_CACHE_MAX_ITEM_NUM), 256);
66 if(m_overlay_cache_max_item_num<0) m_overlay_cache_max_item_num = 0;
68 m_overlay_no_blur_cache_max_item_num = theApp.GetProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_OVERLAY_NO_BLUR_CACHE_MAX_ITEM_NUM), 256);
69 if(m_overlay_no_blur_cache_max_item_num<0) m_overlay_no_blur_cache_max_item_num = 0;
71 m_scan_line_data_cache_max_item_num = theApp.GetProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_SCAN_LINE_DATA_CACHE_MAX_ITEM_NUM), 512);
72 if(m_scan_line_data_cache_max_item_num<0) m_scan_line_data_cache_max_item_num = 0;
74 m_path_data_cache_max_item_num = theApp.GetProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_PATH_DATA_CACHE_MAX_ITEM_NUM), 512);
75 if(m_path_data_cache_max_item_num<0) m_path_data_cache_max_item_num = 0;
77 m_subpixel_pos_level = theApp.GetProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_SUBPIXEL_POS_LEVEL), SubpixelPositionControler::EIGHT_X_EIGHT);
78 if(m_subpixel_pos_level<0) m_subpixel_pos_level=0;
79 else if(m_subpixel_pos_level>=SubpixelPositionControler::MAX_COUNT) m_subpixel_pos_level=SubpixelPositionControler::EIGHT_X_EIGHT;
81 m_fFollowUpstreamPreferredOrder = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_USE_UPSTREAM_PREFERRED_ORDER), true);
82 // get output colorspace config
83 if(pData)
85 delete [] pData;
86 pData = NULL;
88 if(theApp.GetProfileBinary(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_OUTPUT_COLORFORMATS), &pData, &nSize)
89 && pData && nSize == 2*GetOutputColorSpaceNumber())
91 for (int i=0;i<nSize/2;i++)
93 m_outputColorSpace[i] = static_cast<ColorSpaceId>(pData[2*i]);
94 m_selectedOutputColorSpace[i] = static_cast<bool>(pData[2*i+1]);
97 else
99 for (int i=0;i<GetOutputColorSpaceNumber();i++)
101 m_outputColorSpace[i] = static_cast<ColorSpaceId>(i);
102 m_selectedOutputColorSpace[i] = true;
106 // get input colorspace config
107 if(pData)
109 delete [] pData;
110 pData = NULL;
112 if(theApp.GetProfileBinary(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_INPUT_COLORFORMATS), &pData, &nSize)
113 && pData && nSize == 2*GetInputColorSpaceNumber())
115 for (int i=0;i<nSize/2;i++)
117 m_inputColorSpace[i] = static_cast<ColorSpaceId>(pData[2*i]);
118 m_selectedInputColorSpace[i] = static_cast<bool>(pData[2*i+1]);
121 else
123 for (int i=0;i<GetOutputColorSpaceNumber();i++)
125 m_inputColorSpace[i] = static_cast<ColorSpaceId>(i);
126 m_selectedInputColorSpace[i] = true;
131 if(pData)
133 delete [] pData;
134 pData = NULL;
136 if(theApp.GetProfileBinary(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_MEDIAFPS), &pData, &nSize) && pData)
138 if(nSize != sizeof(m_MediaFPS)) m_MediaFPS = 25.0;
139 else memcpy(&m_MediaFPS, pData, sizeof(m_MediaFPS));
141 m_ZoomRect.left = m_ZoomRect.top = 0;
142 m_ZoomRect.right = m_ZoomRect.bottom = 1;
144 m_fForced = false;
145 if(pData)
147 delete [] pData;
148 pData = NULL;
152 CDirectVobSub::~CDirectVobSub()
154 CAutoLock cAutoLock(&m_propsLock);
157 STDMETHODIMP CDirectVobSub::get_FileName(WCHAR* fn)
159 CAutoLock cAutoLock(&m_propsLock);
161 if(!fn) return E_POINTER;
163 #ifdef UNICODE
164 wcscpy(fn, m_FileName);
165 #else
166 mbstowcs(fn, m_FileName, m_FileName.GetLength()+1);
167 #endif
169 return S_OK;
172 STDMETHODIMP CDirectVobSub::put_FileName(WCHAR* fn)
174 CAutoLock cAutoLock(&m_propsLock);
176 if(!fn) return E_POINTER;
178 CString tmp = fn;
179 if(!m_FileName.Left(m_FileName.ReverseFind('.')+1).CompareNoCase(tmp.Left(tmp.ReverseFind('.')+1))) return S_FALSE;
181 #ifdef UNICODE
182 m_FileName = fn;
183 #else
184 CHARSETINFO cs={0};
185 ::TranslateCharsetInfo((DWORD *)DEFAULT_CHARSET, &cs, TCI_SRCCHARSET);
186 CHAR* buff = m_FileName.GetBuffer(MAX_PATH*2);
187 int len = WideCharToMultiByte(cs.ciACP/*CP_OEMCP*/, NULL, fn, -1, buff, MAX_PATH*2, NULL, NULL);
188 m_FileName.ReleaseBuffer(len+1);
189 #endif
191 return S_OK;
194 STDMETHODIMP CDirectVobSub::get_LanguageCount(int* nLangs)
196 CAutoLock cAutoLock(&m_propsLock);
198 return nLangs ? *nLangs = 0, S_OK : E_POINTER;
201 STDMETHODIMP CDirectVobSub::get_LanguageName(int iLanguage, WCHAR** ppName)
203 return S_OK;
206 STDMETHODIMP CDirectVobSub::get_SelectedLanguage(int* iSelected)
208 CAutoLock cAutoLock(&m_propsLock);
210 return iSelected ? *iSelected = m_iSelectedLanguage, S_OK : E_POINTER;
213 STDMETHODIMP CDirectVobSub::put_SelectedLanguage(int iSelected)
215 CAutoLock cAutoLock(&m_propsLock);
217 if(m_iSelectedLanguage == iSelected) return S_FALSE;
219 int nCount;
220 if(FAILED(get_LanguageCount(&nCount))
221 || iSelected < 0
222 || iSelected >= nCount)
223 return E_FAIL;
225 m_iSelectedLanguage = iSelected;
227 return S_OK;
230 STDMETHODIMP CDirectVobSub::get_HideSubtitles(bool* fHideSubtitles)
232 CAutoLock cAutoLock(&m_propsLock);
234 return fHideSubtitles ? *fHideSubtitles = m_fHideSubtitles, S_OK : E_POINTER;
237 STDMETHODIMP CDirectVobSub::put_HideSubtitles(bool fHideSubtitles)
239 CAutoLock cAutoLock(&m_propsLock);
241 if(m_fHideSubtitles == fHideSubtitles) return S_FALSE;
243 m_fHideSubtitles = fHideSubtitles;
245 return S_OK;
248 STDMETHODIMP CDirectVobSub::get_PreBuffering(bool* fDoPreBuffering)
250 CAutoLock cAutoLock(&m_propsLock);
252 //return fDoPreBuffering ? *fDoPreBuffering = m_fDoPreBuffering, S_OK : E_POINTER;
253 return fDoPreBuffering ? *fDoPreBuffering = false, S_OK : E_POINTER;
256 STDMETHODIMP CDirectVobSub::put_PreBuffering(bool fDoPreBuffering)
258 return E_NOTIMPL;
259 //CAutoLock cAutoLock(&m_propsLock);
261 //if(m_fDoPreBuffering == fDoPreBuffering) return S_FALSE;
263 //m_fDoPreBuffering = fDoPreBuffering;
265 //return S_OK;
268 STDMETHODIMP CDirectVobSub::get_ColourSpace(int* colourSpace)
270 CAutoLock cAutoLock(&m_propsLock);
272 return colourSpace ? *colourSpace = m_colourSpace, S_OK : E_POINTER;
275 STDMETHODIMP CDirectVobSub::put_ColourSpace(int colourSpace)
277 CAutoLock cAutoLock(&m_propsLock);
279 if(m_colourSpace == colourSpace) return S_FALSE;
281 m_colourSpace = colourSpace;
283 return S_OK;
285 STDMETHODIMP CDirectVobSub::get_Placement(bool* fOverridePlacement, int* xperc, int* yperc)
287 CAutoLock cAutoLock(&m_propsLock);
289 if(fOverridePlacement) *fOverridePlacement = m_fOverridePlacement;
290 if(xperc) *xperc = m_PlacementXperc;
291 if(yperc) *yperc = m_PlacementYperc;
293 return S_OK;
296 STDMETHODIMP CDirectVobSub::put_Placement(bool fOverridePlacement, int xperc, int yperc)
298 DbgLog((LOG_TRACE, 3, "%s(%d): %s", __FILE__, __LINE__, __FUNCTION__));
299 CAutoLock cAutoLock(&m_propsLock);
301 DbgLog((LOG_TRACE, 3, "\tfOverridePlacement:%d xperc:%d yperc:%d", (int)fOverridePlacement, xperc, yperc));
302 DbgLog((LOG_TRACE, 3, "\tm_fOverridePlacement:%d m_PlacementXperc:%d m_PlacementYperc:%d", (int)m_fOverridePlacement, m_PlacementXperc, m_PlacementYperc));
303 if(m_fOverridePlacement == fOverridePlacement && m_PlacementXperc == xperc && m_PlacementYperc == yperc) return S_FALSE;
305 m_fOverridePlacement = fOverridePlacement;
306 m_PlacementXperc = xperc;
307 m_PlacementYperc = yperc;
309 return S_OK;
312 STDMETHODIMP CDirectVobSub::get_VobSubSettings(bool* fBuffer, bool* fOnlyShowForcedSubs, bool* fPolygonize)
314 CAutoLock cAutoLock(&m_propsLock);
316 if(fBuffer) *fBuffer = m_fBufferVobSub;
317 if(fOnlyShowForcedSubs) *fOnlyShowForcedSubs = m_fOnlyShowForcedVobSubs;
318 if(fPolygonize) *fPolygonize = m_fPolygonize;
320 return S_OK;
323 STDMETHODIMP CDirectVobSub::put_VobSubSettings(bool fBuffer, bool fOnlyShowForcedSubs, bool fPolygonize)
325 CAutoLock cAutoLock(&m_propsLock);
327 if(m_fBufferVobSub == fBuffer && m_fOnlyShowForcedVobSubs == fOnlyShowForcedSubs && m_fPolygonize == fPolygonize) return S_FALSE;
329 m_fBufferVobSub = fBuffer;
330 m_fOnlyShowForcedVobSubs = fOnlyShowForcedSubs;
331 m_fPolygonize = fPolygonize;
333 return S_OK;
336 STDMETHODIMP CDirectVobSub::get_TextSettings(void* lf, int lflen, COLORREF* color, bool* fShadow, bool* fOutline, bool* fAdvancedRenderer)
338 CAutoLock cAutoLock(&m_propsLock);
340 if(lf)
342 if(lflen == sizeof(LOGFONTA))
343 strncpy_s(((LOGFONTA*)lf)->lfFaceName, LF_FACESIZE, CStringA(m_defStyle.fontName), _TRUNCATE);
344 else if(lflen == sizeof(LOGFONTW))
345 wcsncpy_s(((LOGFONTW*)lf)->lfFaceName, LF_FACESIZE, CStringW(m_defStyle.fontName), _TRUNCATE);
346 else
347 return E_INVALIDARG;
349 ((LOGFONT*)lf)->lfCharSet = m_defStyle.charSet;
350 ((LOGFONT*)lf)->lfItalic = m_defStyle.fItalic;
351 ((LOGFONT*)lf)->lfHeight = m_defStyle.fontSize;
352 ((LOGFONT*)lf)->lfWeight = m_defStyle.fontWeight;
353 ((LOGFONT*)lf)->lfStrikeOut = m_defStyle.fStrikeOut;
354 ((LOGFONT*)lf)->lfUnderline = m_defStyle.fUnderline;
357 if(color) *color = m_defStyle.colors[0];
358 if(fShadow) *fShadow = (m_defStyle.shadowDepthX>0) || (m_defStyle.shadowDepthY>0);
359 if(fOutline) *fOutline = (m_defStyle.outlineWidthX>0) || (m_defStyle.outlineWidthY>0);
360 if(fAdvancedRenderer) *fAdvancedRenderer = m_fAdvancedRenderer;
362 return S_OK;
365 STDMETHODIMP CDirectVobSub::put_TextSettings(void* lf, int lflen, COLORREF color, bool fShadow, bool fOutline, bool fAdvancedRenderer)
367 CAutoLock cAutoLock(&m_propsLock);
368 STSStyle tmp = m_defStyle;
369 if(lf)
371 if(lflen == sizeof(LOGFONTA))
372 tmp.fontName = ((LOGFONTA*)lf)->lfFaceName;
373 else if(lflen == sizeof(LOGFONTW))
374 tmp.fontName = ((LOGFONTW*)lf)->lfFaceName;
375 else
376 return E_INVALIDARG;
378 tmp.charSet = ((LOGFONT*)lf)->lfCharSet;
379 tmp.fItalic = !!((LOGFONT*)lf)->lfItalic;
380 tmp.fontSize = ((LOGFONT*)lf)->lfHeight;
381 tmp.fontWeight = ((LOGFONT*)lf)->lfWeight;
382 tmp.fStrikeOut = !!((LOGFONT*)lf)->lfStrikeOut;
383 tmp.fUnderline = !!((LOGFONT*)lf)->lfUnderline;
385 if(tmp.fontSize < 0)
387 HDC hdc = ::GetDC(0);
388 m_defStyle.fontSize = -m_defStyle.fontSize * 72 / GetDeviceCaps(hdc, LOGPIXELSY);
389 ::ReleaseDC(0, hdc);
394 tmp.colors[0] = color;
395 tmp.shadowDepthX = tmp.shadowDepthY = fShadow?2:0;
396 tmp.outlineWidthX = tmp.outlineWidthY = fOutline?2:0;
398 if(tmp==m_defStyle)
400 return S_FALSE;//Important! Avoid unnecessary deinit
402 else
404 m_defStyle = tmp;
405 return S_OK;
410 STDMETHODIMP CDirectVobSub::get_Flip(bool* fPicture, bool* fSubtitles)
412 CAutoLock cAutoLock(&m_propsLock);
414 if(fPicture) *fPicture = m_fFlipPicture;
415 if(fSubtitles) *fSubtitles = m_fFlipSubtitles;
417 return S_OK;
420 STDMETHODIMP CDirectVobSub::put_Flip(bool fPicture, bool fSubtitles)
422 CAutoLock cAutoLock(&m_propsLock);
424 if(m_fFlipPicture == fPicture && m_fFlipSubtitles == fSubtitles) return S_FALSE;
426 m_fFlipPicture = fPicture;
427 m_fFlipSubtitles = fSubtitles;
429 return S_OK;
432 STDMETHODIMP CDirectVobSub::get_OSD(bool* fOSD)
434 CAutoLock cAutoLock(&m_propsLock);
436 return fOSD ? *fOSD = m_fOSD, S_OK : E_POINTER;
439 STDMETHODIMP CDirectVobSub::put_OSD(bool fOSD)
441 CAutoLock cAutoLock(&m_propsLock);
443 if(m_fOSD == fOSD) return S_FALSE;
445 m_fOSD = fOSD;
447 return S_OK;
450 STDMETHODIMP CDirectVobSub::get_SaveFullPath(bool* fSaveFullPath)
452 CAutoLock cAutoLock(&m_propsLock);
454 return fSaveFullPath ? *fSaveFullPath = m_fSaveFullPath, S_OK : E_POINTER;
457 STDMETHODIMP CDirectVobSub::put_SaveFullPath(bool fSaveFullPath)
459 CAutoLock cAutoLock(&m_propsLock);
461 if(m_fSaveFullPath == fSaveFullPath) return S_FALSE;
463 m_fSaveFullPath = fSaveFullPath;
465 return S_OK;
468 STDMETHODIMP CDirectVobSub::get_SubtitleTiming(int* delay, int* speedmul, int* speeddiv)
470 CAutoLock cAutoLock(&m_propsLock);
472 if(delay) *delay = m_SubtitleDelay;
473 if(speedmul) *speedmul = m_SubtitleSpeedMul;
474 if(speeddiv) *speeddiv = m_SubtitleSpeedDiv;
476 return S_OK;
479 STDMETHODIMP CDirectVobSub::put_SubtitleTiming(int delay, int speedmul, int speeddiv)
481 CAutoLock cAutoLock(&m_propsLock);
483 if(m_SubtitleDelay == delay && m_SubtitleSpeedMul == speedmul && m_SubtitleSpeedDiv == speeddiv) return S_FALSE;
485 m_SubtitleDelay = delay;
486 m_SubtitleSpeedMul = speedmul;
487 if(speeddiv > 0) m_SubtitleSpeedDiv = speeddiv;
489 return S_OK;
492 STDMETHODIMP CDirectVobSub::get_MediaFPS(bool* fEnabled, double* fps)
494 CAutoLock cAutoLock(&m_propsLock);
496 if(fEnabled) *fEnabled = m_fMediaFPSEnabled;
497 if(fps) *fps = m_MediaFPS;
499 return S_OK;
502 STDMETHODIMP CDirectVobSub::put_MediaFPS(bool fEnabled, double fps)
504 CAutoLock cAutoLock(&m_propsLock);
506 if(m_fMediaFPSEnabled == fEnabled && m_MediaFPS == fps) return S_FALSE;
508 m_fMediaFPSEnabled = fEnabled;
509 if(fps > 0) m_MediaFPS = fps;
511 return S_OK;
514 STDMETHODIMP CDirectVobSub::get_ZoomRect(NORMALIZEDRECT* rect)
516 CAutoLock cAutoLock(&m_propsLock);
518 if(!rect) return E_POINTER;
520 *rect = m_ZoomRect;
522 return S_OK;
525 STDMETHODIMP CDirectVobSub::put_ZoomRect(NORMALIZEDRECT* rect)
527 CAutoLock cAutoLock(&m_propsLock);
529 if(!rect) return E_POINTER;
531 if(!memcmp(&m_ZoomRect, rect, sizeof(m_ZoomRect))) return S_FALSE;
533 m_ZoomRect = *rect;
535 return S_OK;
538 STDMETHODIMP CDirectVobSub::get_OutputColorFormat(ColorSpaceId* preferredOrder, bool* fSelected, UINT* count)
540 CAutoLock cAutoLock(&m_propsLock);
541 if(count)
543 *count = GetOutputColorSpaceNumber();
545 if(preferredOrder)
547 memcpy(preferredOrder, m_outputColorSpace, GetOutputColorSpaceNumber()*sizeof(*preferredOrder));
549 if(fSelected)
551 memcpy(fSelected, m_selectedOutputColorSpace, GetOutputColorSpaceNumber()*sizeof(*fSelected));
554 return S_OK;
557 STDMETHODIMP CDirectVobSub::put_OutputColorFormat( const ColorSpaceId* preferredOrder, const bool* fSelected, UINT count )
559 CAutoLock cAutoLock(&m_propsLock);
561 if( count!=GetOutputColorSpaceNumber() )
562 return S_FALSE;
563 if( (preferredOrder==NULL || !memcmp(preferredOrder, m_outputColorSpace, count*sizeof(*preferredOrder)))
564 && (fSelected==NULL || !memcmp(fSelected, m_selectedOutputColorSpace, count*sizeof(*fSelected))) )
565 return S_FALSE;
566 if(preferredOrder)
567 memcpy(m_outputColorSpace, preferredOrder, count*sizeof(*preferredOrder));
568 if(fSelected)
569 memcpy(m_selectedOutputColorSpace, fSelected, count*sizeof(*fSelected));
571 return S_OK;
574 STDMETHODIMP CDirectVobSub::get_InputColorFormat( ColorSpaceId* preferredOrder, bool* fSelected, UINT* count )
576 CAutoLock cAutoLock(&m_propsLock);
577 if(count)
579 *count = GetInputColorSpaceNumber();
581 if(preferredOrder)
583 memcpy(preferredOrder, m_inputColorSpace, GetOutputColorSpaceNumber()*sizeof(*preferredOrder));
585 if(fSelected)
587 memcpy(fSelected, m_selectedInputColorSpace, GetOutputColorSpaceNumber()*sizeof(*fSelected));
590 return S_OK;
593 STDMETHODIMP CDirectVobSub::put_InputColorFormat( const ColorSpaceId* preferredOrder, const bool* fSelected, UINT count )
595 CAutoLock cAutoLock(&m_propsLock);
597 if( count!=GetInputColorSpaceNumber() )
598 return S_FALSE;
599 if( (preferredOrder==NULL || !memcmp(preferredOrder, m_inputColorSpace, count*sizeof(*preferredOrder)))
600 && (fSelected==NULL || !memcmp(fSelected, m_selectedInputColorSpace, count*sizeof(*fSelected))) )
601 return S_FALSE;
602 if(preferredOrder)
603 memcpy(m_inputColorSpace, preferredOrder, count*sizeof(*preferredOrder));
604 if(fSelected)
605 memcpy(m_selectedInputColorSpace, fSelected, count*sizeof(*fSelected));
607 return S_OK;
610 STDMETHODIMP CDirectVobSub::get_OverlayCacheMaxItemNum(int* overlay_cache_max_item_num)
612 CAutoLock cAutoLock(&m_propsLock);
614 if(overlay_cache_max_item_num) *overlay_cache_max_item_num = m_overlay_cache_max_item_num;
616 return S_OK;
619 STDMETHODIMP CDirectVobSub::put_OverlayCacheMaxItemNum(int overlay_cache_max_item_num)
621 CAutoLock cAutoLock(&m_propsLock);
623 if(m_overlay_cache_max_item_num == overlay_cache_max_item_num || overlay_cache_max_item_num<0) return S_FALSE;
625 m_overlay_cache_max_item_num = overlay_cache_max_item_num;
627 return S_OK;
630 STDMETHODIMP CDirectVobSub::get_ScanLineDataCacheMaxItemNum(int* scan_line_data_cache_max_item_num)
632 CAutoLock cAutoLock(&m_propsLock);
634 if(scan_line_data_cache_max_item_num) *scan_line_data_cache_max_item_num = m_scan_line_data_cache_max_item_num;
636 return S_OK;
639 STDMETHODIMP CDirectVobSub::put_ScanLineDataCacheMaxItemNum(int scan_line_data_cache_max_item_num)
641 CAutoLock cAutoLock(&m_propsLock);
643 if(m_scan_line_data_cache_max_item_num == scan_line_data_cache_max_item_num || scan_line_data_cache_max_item_num<0) return S_FALSE;
644 m_scan_line_data_cache_max_item_num = scan_line_data_cache_max_item_num;
646 return S_OK;
649 STDMETHODIMP CDirectVobSub::get_PathDataCacheMaxItemNum(int* path_data_cache_max_item_num)
651 CAutoLock cAutoLock(&m_propsLock);
653 if(path_data_cache_max_item_num) *path_data_cache_max_item_num = m_path_data_cache_max_item_num;
655 return S_OK;
658 STDMETHODIMP CDirectVobSub::put_PathDataCacheMaxItemNum(int path_data_cache_max_item_num)
660 CAutoLock cAutoLock(&m_propsLock);
662 if(m_path_data_cache_max_item_num == path_data_cache_max_item_num || path_data_cache_max_item_num<0) return S_FALSE;
663 m_path_data_cache_max_item_num = path_data_cache_max_item_num;
665 return S_OK;
668 STDMETHODIMP CDirectVobSub::get_OverlayNoBlurCacheMaxItemNum(int* overlay_no_blur_cache_max_item_num)
670 CAutoLock cAutoLock(&m_propsLock);
672 if(overlay_no_blur_cache_max_item_num) *overlay_no_blur_cache_max_item_num = m_overlay_no_blur_cache_max_item_num;
674 return S_OK;
677 STDMETHODIMP CDirectVobSub::put_OverlayNoBlurCacheMaxItemNum(int overlay_no_blur_cache_max_item_num)
679 CAutoLock cAutoLock(&m_propsLock);
681 if(m_overlay_no_blur_cache_max_item_num == overlay_no_blur_cache_max_item_num || overlay_no_blur_cache_max_item_num<0) return S_FALSE;
682 m_overlay_no_blur_cache_max_item_num = overlay_no_blur_cache_max_item_num;
684 return S_OK;
687 STDMETHODIMP CDirectVobSub::get_CachesInfo(CachesInfo* caches_info)
689 CAutoLock cAutoLock(&m_propsLock);
690 if(caches_info)
692 caches_info->path_cache_cur_item_num = 0;
693 caches_info->path_cache_hit_count = 0;
694 caches_info->path_cache_query_count = 0;
695 caches_info->scanline_cache_cur_item_num= 0;
696 caches_info->scanline_cache_hit_count = 0;
697 caches_info->scanline_cache_query_count = 0;
698 caches_info->non_blur_cache_cur_item_num= 0;
699 caches_info->non_blur_cache_hit_count = 0;
700 caches_info->non_blur_cache_query_count = 0;
701 caches_info->overlay_cache_cur_item_num = 0;
702 caches_info->overlay_cache_hit_count = 0;
703 caches_info->overlay_cache_query_count = 0;
704 caches_info->interpolate_cache_cur_item_num = 0;
705 caches_info->interpolate_cache_query_count = 0;
706 caches_info->interpolate_cache_hit_count = 0;
707 caches_info->text_info_cache_cur_item_num = 0;
708 caches_info->text_info_cache_query_count = 0;
709 caches_info->text_info_cache_hit_count = 0;
710 caches_info->word_info_cache_cur_item_num = 0;
711 caches_info->word_info_cache_query_count = 0;
712 caches_info->word_info_cache_hit_count = 0;
713 return S_OK;
715 else
717 return S_FALSE;
721 STDMETHODIMP CDirectVobSub::get_SubpixelPositionLevel(int* subpixel_pos_level)
723 CAutoLock cAutoLock(&m_propsLock);
725 if(subpixel_pos_level) *subpixel_pos_level = m_subpixel_pos_level;
727 return S_OK;
730 STDMETHODIMP CDirectVobSub::put_SubpixelPositionLevel(int subpixel_pos_level)
732 CAutoLock cAutoLock(&m_propsLock);
734 if(m_subpixel_pos_level == subpixel_pos_level || subpixel_pos_level<0 || subpixel_pos_level>=SubpixelPositionControler::MAX_COUNT) return S_FALSE;
735 m_subpixel_pos_level = subpixel_pos_level;
737 return S_OK;
740 STDMETHODIMP CDirectVobSub::get_FollowUpstreamPreferredOrder( bool *fFollowUpstreamPreferredOrder )
742 CAutoLock cAutoLock(&m_propsLock);
744 if(fFollowUpstreamPreferredOrder) *fFollowUpstreamPreferredOrder=m_fFollowUpstreamPreferredOrder;
746 return S_OK;
749 STDMETHODIMP CDirectVobSub::put_FollowUpstreamPreferredOrder( bool fFollowUpstreamPreferredOrder )
751 CAutoLock cAutoLock(&m_propsLock);
753 if(m_fFollowUpstreamPreferredOrder == fFollowUpstreamPreferredOrder) return S_FALSE;
754 m_fFollowUpstreamPreferredOrder = fFollowUpstreamPreferredOrder;
756 return S_OK;
759 STDMETHODIMP CDirectVobSub::UpdateRegistry()
761 AFX_MANAGE_STATE(AfxGetStaticModuleState());
763 CAutoLock cAutoLock(&m_propsLock);
765 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_HIDE), m_fHideSubtitles);
766 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_DOPREBUFFERING), m_fDoPreBuffering);
768 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_COLOUR_SPACE), m_colourSpace);
769 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_BT601_WIDTH), 1024);
770 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_BT601_HEIGHT), 600);
772 theApp.WriteProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_OVERRIDEPLACEMENT), m_fOverridePlacement);
773 theApp.WriteProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_XPERC), m_PlacementXperc);
774 theApp.WriteProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_YPERC), m_PlacementYperc);
775 theApp.WriteProfileInt(ResStr(IDS_R_VOBSUB), ResStr(IDS_RV_BUFFER), m_fBufferVobSub);
776 theApp.WriteProfileInt(ResStr(IDS_R_VOBSUB), ResStr(IDS_RV_ONLYSHOWFORCEDSUBS), m_fOnlyShowForcedVobSubs);
777 theApp.WriteProfileInt(ResStr(IDS_R_VOBSUB), ResStr(IDS_RV_POLYGONIZE), m_fPolygonize);
778 CString style;
779 theApp.WriteProfileString(ResStr(IDS_R_TEXT), ResStr(IDS_RT_STYLE), style <<= m_defStyle);
780 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_FLIPPICTURE), m_fFlipPicture);
781 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_FLIPSUBTITLES), m_fFlipSubtitles);
782 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_SHOWOSDSTATS), m_fOSD);
783 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_SAVEFULLPATH), m_fSaveFullPath);
784 theApp.WriteProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_SUBTITLEDELAY), m_SubtitleDelay);
785 theApp.WriteProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_SUBTITLESPEEDMUL), m_SubtitleSpeedMul);
786 theApp.WriteProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_SUBTITLESPEEDDIV), m_SubtitleSpeedDiv);
787 theApp.WriteProfileInt(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_MEDIAFPSENABLED), m_fMediaFPSEnabled);
788 theApp.WriteProfileBinary(ResStr(IDS_R_TIMING), ResStr(IDS_RTM_MEDIAFPS), (BYTE*)&m_MediaFPS, sizeof(m_MediaFPS));
789 theApp.WriteProfileInt(ResStr(IDS_R_TEXT), ResStr(IDS_RT_AUTOPARCOMPENSATION), m_ePARCompensationType);
791 theApp.WriteProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_OVERLAY_CACHE_MAX_ITEM_NUM), m_overlay_cache_max_item_num);
792 theApp.WriteProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_OVERLAY_NO_BLUR_CACHE_MAX_ITEM_NUM), m_overlay_no_blur_cache_max_item_num);
793 theApp.WriteProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_SCAN_LINE_DATA_CACHE_MAX_ITEM_NUM), m_scan_line_data_cache_max_item_num);
794 theApp.WriteProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_PATH_DATA_CACHE_MAX_ITEM_NUM), m_path_data_cache_max_item_num);
795 theApp.WriteProfileInt(ResStr(IDS_R_PERFORMANCE), ResStr(IDS_RP_SUBPIXEL_POS_LEVEL), m_subpixel_pos_level);
796 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_USE_UPSTREAM_PREFERRED_ORDER), m_fFollowUpstreamPreferredOrder);
798 //save output color config
800 int count = GetOutputColorSpaceNumber();
801 BYTE* pData = new BYTE[2*count];
802 for(int i = 0; i < count; i++)
804 pData[2*i] = static_cast<BYTE>(m_outputColorSpace[i]);
805 pData[2*i+1] = static_cast<BYTE>(m_selectedOutputColorSpace[i]);
807 theApp.WriteProfileBinary(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_OUTPUT_COLORFORMATS), pData, 2*count);
809 delete [] pData;
812 //save input color config
814 int count = GetInputColorSpaceNumber();
815 BYTE* pData = new BYTE[2*count];
816 for(int i = 0; i < count; i++)
818 pData[2*i] = static_cast<BYTE>(m_inputColorSpace[i]);
819 pData[2*i+1] = static_cast<BYTE>(m_selectedInputColorSpace[i]);
821 theApp.WriteProfileBinary(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_INPUT_COLORFORMATS), pData, 2*count);
823 delete [] pData;
827 return S_OK;
830 STDMETHODIMP CDirectVobSub::HasConfigDialog(int iSelected)
832 return E_NOTIMPL;
835 STDMETHODIMP CDirectVobSub::ShowConfigDialog(int iSelected, HWND hWndParent)
837 return E_NOTIMPL;
840 STDMETHODIMP CDirectVobSub::IsSubtitleReloaderLocked(bool* fLocked)
842 CAutoLock cAutoLock(&m_propsLock);
844 if(!fLocked) return E_POINTER;
846 bool fDisabled;
847 get_SubtitleReloader(&fDisabled);
849 *fLocked = fDisabled || m_nReloaderDisableCount > 0;
851 return S_OK;
854 STDMETHODIMP CDirectVobSub::LockSubtitleReloader(bool fLock)
856 CAutoLock cAutoLock(&m_propsLock);
858 if(fLock) m_nReloaderDisableCount++;
859 else m_nReloaderDisableCount--;
861 ASSERT(m_nReloaderDisableCount >= 0);
862 if(m_nReloaderDisableCount < 0) m_nReloaderDisableCount = 0;
864 return S_OK;
867 STDMETHODIMP CDirectVobSub::get_SubtitleReloader(bool* fDisabled)
869 AFX_MANAGE_STATE(AfxGetStaticModuleState());
871 CAutoLock cAutoLock(&m_propsLock);
873 if(fDisabled) *fDisabled = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_DISABLERELOADER), 0);
875 return S_OK;
878 STDMETHODIMP CDirectVobSub::put_SubtitleReloader(bool fDisable)
880 AFX_MANAGE_STATE(AfxGetStaticModuleState());
882 CAutoLock cAutoLock(&m_propsLock);
884 bool b;
885 get_SubtitleReloader(&b);
886 if(b == fDisable) return S_FALSE;
888 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_DISABLERELOADER), fDisable);
890 return S_OK;
893 STDMETHODIMP CDirectVobSub::get_ExtendPicture(int* horizontal, int* vertical, int* resx2, int* resx2minw, int* resx2minh)
895 AFX_MANAGE_STATE(AfxGetStaticModuleState());
897 CAutoLock cAutoLock(&m_propsLock);
899 if(horizontal) *horizontal = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_MOD32FIX), 0) & 1;
900 if(vertical) *vertical = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_EXTPIC), 0);
901 if(resx2) *resx2 = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_RESX2), 2) & 3;
902 if(resx2minw) *resx2minw = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_RESX2MINW), 384);
903 if(resx2minh) *resx2minh = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_RESX2MINH), 288);
905 return S_OK;
908 STDMETHODIMP CDirectVobSub::put_ExtendPicture(int horizontal, int vertical, int resx2, int resx2minw, int resx2minh)
910 AFX_MANAGE_STATE(AfxGetStaticModuleState());
912 CAutoLock cAutoLock(&m_propsLock);
914 int i[5];
915 get_ExtendPicture(i, i+1, i+2, i+3, i+4);
916 if(i[0] == horizontal && i[1] == vertical && i[2] == resx2 && i[3] == resx2minw && i[4] == resx2minh) return S_FALSE;
918 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_MOD32FIX), horizontal & 1);
919 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_EXTPIC), vertical);
920 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_RESX2), resx2 & 3);
921 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_RESX2MINW), resx2minw);
922 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_RESX2MINH), resx2minh);
924 return S_OK;
927 STDMETHODIMP CDirectVobSub::get_LoadSettings(int* level, bool* fExternalLoad, bool* fWebLoad, bool* fEmbeddedLoad)
929 AFX_MANAGE_STATE(AfxGetStaticModuleState());
931 CAutoLock cAutoLock(&m_propsLock);
933 if(level) *level = theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_LOADLEVEL), 0) & 3;
934 if(fExternalLoad) *fExternalLoad = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_EXTERNALLOAD), 1);
935 if(fWebLoad) *fWebLoad = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_WEBLOAD), 0);
936 if(fEmbeddedLoad) *fEmbeddedLoad = !!theApp.GetProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_EMBEDDEDLOAD), 1);
938 return S_OK;
941 STDMETHODIMP CDirectVobSub::put_LoadSettings(int level, bool fExternalLoad, bool fWebLoad, bool fEmbeddedLoad)
943 AFX_MANAGE_STATE(AfxGetStaticModuleState());
945 CAutoLock cAutoLock(&m_propsLock);
947 int i;
948 bool b[3];
949 get_LoadSettings(&i, b, b+1, b+2);
950 if(i == level && b[0] == fExternalLoad && b[1] == fWebLoad && b[2] == fEmbeddedLoad) return S_FALSE;
952 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_LOADLEVEL), level & 3);
953 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_EXTERNALLOAD), fExternalLoad);
954 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_WEBLOAD), fWebLoad);
955 theApp.WriteProfileInt(ResStr(IDS_R_GENERAL), ResStr(IDS_RG_EMBEDDEDLOAD), fEmbeddedLoad);
957 return S_OK;
960 // IDirectVobSub2
962 STDMETHODIMP CDirectVobSub::AdviseSubClock(ISubClock* pSubClock)
964 m_pSubClock = pSubClock;
965 return S_OK;
968 STDMETHODIMP_(bool) CDirectVobSub::get_Forced()
970 return m_fForced;
973 STDMETHODIMP CDirectVobSub::put_Forced(bool fForced)
975 if(m_fForced==fForced)
976 return S_FALSE;
978 m_fForced = fForced;
979 return S_OK;
982 STDMETHODIMP CDirectVobSub::get_TextSettings(STSStyle* pDefStyle)
984 CheckPointer(pDefStyle, E_POINTER);
986 CAutoLock cAutoLock(&m_propsLock);
988 *pDefStyle = m_defStyle;
990 return S_OK;
993 STDMETHODIMP CDirectVobSub::put_TextSettings(STSStyle* pDefStyle)
995 CheckPointer(pDefStyle, E_POINTER);
997 CAutoLock cAutoLock(&m_propsLock);
999 if(m_defStyle==*pDefStyle)
1000 return S_FALSE;
1001 if(!memcmp(&m_defStyle, pDefStyle, sizeof(m_defStyle)))
1002 return S_FALSE;
1004 m_defStyle = *pDefStyle;
1006 return S_OK;
1009 STDMETHODIMP CDirectVobSub::get_AspectRatioSettings(CSimpleTextSubtitle::EPARCompensationType* ePARCompensationType)
1011 CAutoLock cAutoLock(&m_propsLock);
1013 *ePARCompensationType = m_ePARCompensationType;
1015 return S_OK;
1018 STDMETHODIMP CDirectVobSub::put_AspectRatioSettings(CSimpleTextSubtitle::EPARCompensationType* ePARCompensationType)
1020 CAutoLock cAutoLock(&m_propsLock);
1022 if(m_ePARCompensationType==*ePARCompensationType)
1023 return S_FALSE;
1025 m_ePARCompensationType = *ePARCompensationType;
1027 return S_OK;
1030 // IFilterVersion
1032 STDMETHODIMP_(DWORD) CDirectVobSub::GetFilterVersion()
1034 return 0x0234;