Fixed stuttering bug for video with frame rate other then 23.976.
[xy_vsfilter.git] / src / subtitles / RTS.h
blob4b2b9aead8803dec40fa26c6bbc5211f0ac235ed
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.
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 #pragma once
24 #include "STS.h"
25 #include "Rasterizer.h"
26 #include "../SubPic/SubPicProviderImpl.h"
27 #include <atlcoll.h>
28 #include <boost/flyweight/key_value.hpp>
29 #include <boost/smart_ptr.hpp>
30 #include "mru_cache.h"
32 #define RTS_POS_SEGMENT_INDEX_BITS 16
33 #define RTS_POS_SUB_INDEX_MASK ((1<<RTS_POS_SEGMENT_INDEX_BITS)-1)
35 class CMyFont : public CFont
37 public:
38 int m_ascent, m_descent;
40 CMyFont(const STSStyleBase& style);
43 typedef ::boost::flyweights::flyweight<::boost::flyweights::key_value<STSStyleBase, CMyFont>, ::boost::flyweights::no_locking> FwCMyFont;
45 class CPolygon;
47 struct OverlayList
49 SharedPtrOverlay overlay;
50 OverlayList* next;
52 OverlayList()
54 next = NULL;
56 ~OverlayList()
58 delete next;
62 struct CompositeDrawItem
64 SharedPtrDrawItem shadow;
65 SharedPtrDrawItem outline;
66 SharedPtrDrawItem body;
69 typedef CAtlList<CompositeDrawItem> CompositeDrawItemList;
70 typedef CAtlList<CompositeDrawItemList> CompositeDrawItemListList;
72 class CWord;
73 typedef CWord* PCWord;
74 typedef ::boost::shared_ptr<CWord> SharedPtrCWord;
75 typedef ::boost::shared_ptr<CPolygon> SharedPtrCPolygon;
77 class OverlayKey;
78 class CWord
80 bool NeedTransform();
81 void Transform(SharedPtrPathData path_data, const CPoint& org);
83 void Transform_C(const SharedPtrPathData& path_data, const CPoint &org );
84 void Transform_SSE2(const SharedPtrPathData& path_data, const CPoint &org );
85 bool CreateOpaqueBox();
87 protected:
88 CStringW m_str;
90 virtual bool CreatePath(const SharedPtrPathData& path_data) = 0;
92 bool DoPaint(const CPoint& p, const CPoint& trans_org, SharedPtrOverlay* overlay, const OverlayKey& key);
93 public:
94 bool m_fWhiteSpaceChar, m_fLineBreak;
96 FwSTSStyle m_style;
98 SharedPtrCPolygon m_pOpaqueBox;
100 int m_ktype, m_kstart, m_kend;
102 int m_width, m_ascent, m_descent;
104 CWord(const FwSTSStyle& style, const CStringW& str, int ktype, int kstart, int kend); // str[0] = 0 -> m_fLineBreak = true (in this case we only need and use the height of m_font from the whole class)
105 CWord(const CWord&);
106 virtual ~CWord();
108 virtual SharedPtrCWord Copy() = 0;
109 virtual bool Append(const SharedPtrCWord& w);
111 //use static func instead of obj member to avoid constructing a shared_ptr from this
112 //shared_from_this may cause a exception if the obj is not owned by a shared_ptr
113 static void PaintAll(SharedPtrCWord word,
114 const CPoint& shadowPos, const CPoint& outlinePos, const CPoint& bodyPos, const CPoint& org,
115 OverlayList* shadow, OverlayList* outline, OverlayList* body);
116 static void Paint(SharedPtrCWord word, const CPoint& psub, const CPoint& trans_org, OverlayList* overlay_list);
118 //friend class CWordCache;
119 friend class CWordCacheKey;
120 friend class PathDataCacheKey;
121 friend std::size_t hash_value(const CWord& key);
124 class CText : public CWord
126 public:
127 struct TextInfo
129 int m_width, m_ascent, m_descent;
131 typedef ::boost::shared_ptr<TextInfo> SharedPtrTextInfo;
132 protected:
133 virtual bool CreatePath(const SharedPtrPathData& path_data);
135 static void GetTextInfo(TextInfo *output, const FwSTSStyle& style, const CStringW& str);
136 public:
137 CText(const FwSTSStyle& style, const CStringW& str, int ktype, int kstart, int kend);
138 CText(const CText& src);
140 virtual SharedPtrCWord Copy();
141 virtual bool Append(const SharedPtrCWord& w);
144 class CPolygon : public CWord
146 bool GetLONG(CStringW& str, LONG& ret);
147 bool GetPOINT(CStringW& str, POINT& ret);
148 bool ParseStr();
150 protected:
151 double m_scalex, m_scaley;
152 int m_baseline;
154 CAtlArray<BYTE> m_pathTypesOrg;
155 CAtlArray<CPoint> m_pathPointsOrg;
157 virtual bool CreatePath(const SharedPtrPathData& path_data);
159 public:
160 CPolygon(const FwSTSStyle& style, const CStringW& str, int ktype, int kstart, int kend, double scalex, double scaley, int baseline);
161 CPolygon(CPolygon&); // can't use a const reference because we need to use CAtlArray::Copy which expects a non-const reference
162 virtual ~CPolygon();
164 virtual SharedPtrCWord Copy();
165 virtual bool Append(const SharedPtrCWord& w);
168 enum eftype
170 EF_MOVE = 0, // {\move(x1=param[0], y1=param[1], x2=param[2], y2=param[3], t1=t[0], t2=t[1])} or {\pos(x=param[0], y=param[1])}
171 EF_ORG, // {\org(x=param[0], y=param[1])}
172 EF_FADE, // {\fade(a1=param[0], a2=param[1], a3=param[2], t1=t[0], t2=t[1], t3=t[2], t4=t[3])} or {\fad(t1=t[1], t2=t[2])
173 EF_BANNER, // Banner;delay=param[0][;lefttoright=param[1];fadeawaywidth=param[2]]
174 EF_SCROLL, // Scroll up/down=param[3];top=param[0];bottom=param[1];delay=param[2][;fadeawayheight=param[4]]
177 #define EF_NUMBEROFEFFECTS 5
179 class Effect
181 public:
182 enum eftype type;
183 int param[8];
184 int t[4];
187 class CClipper
189 private:
190 SharedPtrCPolygon m_polygon;
192 CSize m_size;
193 bool m_inverse;
195 Effect m_effect;
196 int m_effectType;
198 bool m_painted;
200 SharedArrayByte m_pAlphaMask;
202 void PaintBaseClipper();
203 void PaintBannerClipper();
204 void PaintScrollClipper();
206 void Paint();
207 public:
208 CClipper(CStringW str, CSize size, double scalex, double scaley, bool inverse);
209 void SetEffect(const Effect& effect, int effectType);
210 virtual ~CClipper();
212 const SharedArrayByte& GetAlphaMask();
215 class CLine: private CAtlList<SharedPtrCWord>
217 public:
218 int m_width, m_ascent, m_descent, m_borderX, m_borderY;
220 virtual ~CLine();
222 void Compact();
224 int GetWordCount();
225 void AddWord2Tail(SharedPtrCWord words);
226 bool IsEmpty();
228 CRect PaintAll(CompositeDrawItemList* output, SubPicDesc& spd, const CRect& clipRect, SharedArrayByte pAlphaMask, CPoint p, const CPoint& org, const int time, const int alpha);
231 class CSubtitle: private CAtlList<CLine*>
233 int GetFullWidth();
234 int GetFullLineWidth(POSITION pos);
235 int GetWrapWidth(POSITION pos, int maxwidth);
236 CLine* GetNextLine(POSITION& pos, int maxwidth);
238 public:
239 int m_scrAlignment;
240 int m_wrapStyle;
241 bool m_fAnimated;
242 bool m_fAnimated2; //If this Subtitle has animate effect
243 int m_relativeTo;
245 Effect* m_effects[EF_NUMBEROFEFFECTS];
247 CAtlList<SharedPtrCWord> m_words;
249 CClipper* m_pClipper;
251 CRect m_rect, m_clip;
252 int m_topborder, m_bottomborder;
253 bool m_clipInverse;
255 double m_scalex, m_scaley;
257 public:
258 CSubtitle();
259 virtual ~CSubtitle();
260 virtual void Empty();
262 void CreateClippers(CSize size);
264 void MakeLines(CSize size, CRect marginRect);
266 POSITION GetHeadLinePosition();
267 CLine* GetNextLine(POSITION& pos);
270 struct CSubtitle2
272 CSubtitle2():s(NULL){}
274 CSubtitle2(CSubtitle* s_,const CRect& clipRect_, const CPoint& org_, const CPoint& org2_, const CPoint& p_,
275 int alpha_, int time_)
276 : s(s_), clipRect(clipRect_), org(org_), org2(org2_), p(p_), alpha(alpha_), time(time_)
281 CSubtitle *s;
282 const CRect clipRect;
283 const CPoint org;
284 const CPoint org2;
285 const CPoint p;
286 int alpha;
287 int time;
290 typedef CAtlList<CSubtitle2> CSubtitle2List;
292 class CScreenLayoutAllocator
294 typedef struct
296 CRect r;
297 int segment, entry, layer;
298 } SubRect;
300 CAtlList<SubRect> m_subrects;
302 public:
303 virtual void Empty();
305 void AdvanceToSegment(int segment, const CAtlArray<int>& sa);
306 CRect AllocRect(CSubtitle* s, int segment, int entry, int layer, int collisions);
309 [uuid("537DCACA-2812-4a4f-B2C6-1A34C17ADEB0")]
310 class CRenderedTextSubtitle : public CSubPicProviderImpl, public ISubStream, public CSimpleTextSubtitle
312 public:
313 enum AssCmdType
315 CMD_1c = 0,
316 CMD_2c,
317 CMD_3c,
318 CMD_4c,
319 CMD_1a,
320 CMD_2a,
321 CMD_3a,
322 CMD_4a,
323 CMD_alpha,
324 CMD_an,
325 CMD_a,
326 CMD_blur,
327 CMD_bord,
328 CMD_be,
329 CMD_b,
330 CMD_clip,
331 CMD_iclip,
332 CMD_c,
333 CMD_fade,
334 CMD_fad,
335 CMD_fax,
336 CMD_fay,
337 CMD_fe,
338 CMD_fn,
339 CMD_frx,
340 CMD_fry,
341 CMD_frz,
342 CMD_fr,
343 CMD_fscx,
344 CMD_fscy,
345 CMD_fsc,
346 CMD_fsp,
347 CMD_fs,
348 CMD_i,
349 CMD_kt,
350 CMD_kf,
351 CMD_K,
352 CMD_ko,
353 CMD_k,
354 CMD_move,
355 CMD_org,
356 CMD_pbo,
357 CMD_pos,
358 CMD_p,
359 CMD_q,
360 CMD_r,
361 CMD_shad,
362 CMD_s,
363 CMD_t,
364 CMD_u,
365 CMD_xbord,
366 CMD_xshad,
367 CMD_ybord,
368 CMD_yshad,
369 CMD_COUNT
371 static const int MIN_CMD_LENGTH = 1;//c etc
372 static const int MAX_CMD_LENGTH = 5;//alpha, iclip, xbord, xshad, ybord, yshad
373 static CAtlMap<CStringW, AssCmdType, CStringElementTraits<CStringW>> m_cmdMap;
375 struct AssTag;
376 typedef CAtlList<AssTag> AssTagList;
377 typedef ::boost::shared_ptr<const AssTagList> SharedPtrConstAssTagList;
378 struct AssTag
380 CStringW cmd;
381 AssCmdType cmdType;
382 CAtlArray<CStringW> strParams;
383 AssTagList embeded;
385 private:
386 CAtlMap<int, CSubtitle*> m_subtitleCache;
388 CScreenLayoutAllocator m_sla;
390 CSize m_size;
391 CRect m_vidrect;
393 // temp variables, used when parsing the script
394 int m_time, m_delay;
395 int m_animStart, m_animEnd;
396 double m_animAccel;
397 int m_ktype, m_kstart, m_kend;
398 int m_nPolygon;
399 int m_polygonBaselineOffset;
400 double m_fps;
401 int m_period;//1000/m_fps
403 static void InitCmdMap();
405 void ParseEffect(CSubtitle* sub, const CString& str);
406 void ParseString(CSubtitle* sub, CStringW str, const FwSTSStyle& style);
407 void ParsePolygon(CSubtitle* sub, const CStringW& str, const FwSTSStyle& style);
408 static bool ParseSSATag(AssTagList *assTags, const CStringW& str);
409 bool ParseSSATag(CSubtitle* sub, const AssTagList& assTags, STSStyle& style, const STSStyle& org, bool fAnimate = false);
410 bool ParseSSATag(CSubtitle* sub, const CStringW& str, STSStyle& style, const STSStyle& org, bool fAnimate = false);
412 bool ParseHtmlTag(CSubtitle* sub, CStringW str, STSStyle& style, STSStyle& org);
414 double CalcAnimation(double dst, double src, bool fAnimate);
416 void Draw(SubPicDesc& spd, CompositeDrawItemListList& drawItemListList);
418 CSubtitle* GetSubtitle(int entry);
420 protected:
421 virtual void OnChanged();
423 public:
424 CRenderedTextSubtitle(CCritSec* pLock);
425 virtual ~CRenderedTextSubtitle();
427 virtual void Copy(CRenderedTextSubtitle& rts);
428 virtual void Copy(CSimpleTextSubtitle& sts);
429 virtual void Empty();
431 public:
432 bool Init(CSize size, CRect vidrect); // will call Deinit()
433 void Deinit();
435 DECLARE_IUNKNOWN
436 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
438 // ISubPicProviderEx
439 STDMETHODIMP_(POSITION) GetStartPosition(REFERENCE_TIME rt, double fps);
440 STDMETHODIMP_(POSITION) GetNext(POSITION pos);
441 STDMETHODIMP_(REFERENCE_TIME) GetStart(POSITION pos, double fps);
442 STDMETHODIMP_(REFERENCE_TIME) GetStop(POSITION pos, double fps);
443 STDMETHODIMP_(VOID) GetStartStop(POSITION pos, double fps, /*out*/REFERENCE_TIME &start, /*out*/REFERENCE_TIME &stop);
444 STDMETHODIMP_(bool) IsAnimated(POSITION pos);
445 STDMETHODIMP Render(SubPicDesc& spd, REFERENCE_TIME rt, double fps, RECT& bbox);
446 STDMETHODIMP RenderEx(SubPicDesc& spd, REFERENCE_TIME rt, double fps, CAtlList<CRect>& rectList);
447 STDMETHODIMP ParseScript(SubPicDesc& spd, REFERENCE_TIME rt, double fps, CSubtitle2List *outputSub2List );
448 static void DoRender( SubPicDesc& spd, const CSubtitle2List& sub2List,
449 CAtlList<CRect> *rectList, CompositeDrawItemListList *drawItemListList /*output*/);
450 static void RenderOneSubtitle(SubPicDesc& spd, const CSubtitle2& sub2,
451 CAtlList<CRect>* rectList, CompositeDrawItemList* drawItemList /*output*/);
452 STDMETHODIMP_(bool) IsColorTypeSupported(int type);
454 // IPersist
455 STDMETHODIMP GetClassID(CLSID* pClassID);
457 // ISubStream
458 STDMETHODIMP_(int) GetStreamCount();
459 STDMETHODIMP GetStreamInfo(int i, WCHAR** ppName, LCID* pLCID);
460 STDMETHODIMP_(int) GetStream();
461 STDMETHODIMP SetStream(int iStream);
462 STDMETHODIMP Reload();