2 * Copyright (C) 2005-2013 Team XBMC
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)
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 XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "DVDSubtitlesLibass.h"
23 #include "filesystem/SpecialProtocol.h"
24 #include "settings/GUISettings.h"
25 #include "utils/log.h"
26 #include "threads/SingleLock.h"
27 #include "threads/Atomics.h"
31 static void libass_log(int level, const char *fmt, va_list args, void *data)
36 log.FormatV(fmt, args);
37 CLog::Log(LOGDEBUG, "CDVDSubtitlesLibass: [ass] %s", log.c_str());
40 CDVDSubtitlesLibass::CDVDSubtitlesLibass()
50 CLog::Log(LOGERROR, "CDVDSubtitlesLibass: Failed to load libass library");
54 //Setting the font directory to the temp dir(where mkv fonts are extracted to)
55 CStdString strPath = "special://temp/fonts/";
57 CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Creating ASS library structure");
58 m_library = m_dll.ass_library_init();
62 m_dll.ass_set_message_cb(m_library, libass_log, this);
64 CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Initializing ASS library font settings");
65 // libass uses fontconfig (system lib) which is not wrapped
66 // so translate the path before calling into libass
67 m_dll.ass_set_fonts_dir(m_library, CSpecialProtocol::TranslatePath(strPath).c_str());
68 m_dll.ass_set_extract_fonts(m_library, 1);
69 m_dll.ass_set_style_overrides(m_library, NULL);
71 CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Initializing ASS Renderer");
73 m_renderer = m_dll.ass_renderer_init(m_library);
78 //Setting default font to the Arial in \media\fonts (used if FontConfig fails)
79 strPath = "special://xbmc/media/Fonts/";
80 strPath += g_guiSettings.GetString("subtitles.font");
81 int fc = !g_guiSettings.GetBool("subtitles.overrideassfonts");
83 m_dll.ass_set_margins(m_renderer, 0, 0, 0, 0);
84 m_dll.ass_set_use_margins(m_renderer, 0);
85 m_dll.ass_set_font_scale(m_renderer, 1);
87 // libass uses fontconfig (system lib) which is not wrapped
88 // so translate the path before calling into libass
89 m_dll.ass_set_fonts(m_renderer, CSpecialProtocol::TranslatePath(strPath).c_str(), "Arial", fc, NULL, 1);
93 CDVDSubtitlesLibass::~CDVDSubtitlesLibass()
98 m_dll.ass_free_track(m_track);
99 m_dll.ass_renderer_done(m_renderer);
100 m_dll.ass_library_done(m_library);
105 /*Decode Header of SSA, needed to properly decode demux packets*/
106 bool CDVDSubtitlesLibass::DecodeHeader(char* data, int size)
108 CSingleLock lock(m_section);
109 if(!m_library || !data)
114 CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Creating new ASS track");
115 m_track = m_dll.ass_new_track(m_library) ;
118 m_dll.ass_process_codec_private(m_track, data, size);
122 bool CDVDSubtitlesLibass::DecodeDemuxPkt(char* data, int size, double start, double duration)
124 CSingleLock lock(m_section);
127 CLog::Log(LOGERROR, "CDVDSubtitlesLibass: No SSA header found.");
131 m_dll.ass_process_chunk(m_track, data, size, DVD_TIME_TO_MSEC(start), DVD_TIME_TO_MSEC(duration));
135 bool CDVDSubtitlesLibass::CreateTrack(char* buf)
137 CSingleLock lock(m_section);
140 CLog::Log(LOGERROR, "CDVDSubtitlesLibass: %s - No ASS library struct", __FUNCTION__);
144 CLog::Log(LOGINFO, "SSA Parser: Creating m_track from SSA buffer");
146 m_track = m_dll.ass_read_memory(m_library, buf, 0, 0);
153 ASS_Image* CDVDSubtitlesLibass::RenderImage(int imageWidth, int imageHeight, double pts, int *changes)
155 CSingleLock lock(m_section);
156 if(!m_renderer || !m_track)
158 CLog::Log(LOGERROR, "CDVDSubtitlesLibass: %s - Missing ASS structs(m_track or m_renderer)", __FUNCTION__);
162 m_dll.ass_set_frame_size(m_renderer, imageWidth, imageHeight);
163 return m_dll.ass_render_frame(m_renderer, m_track, DVD_TIME_TO_MSEC(pts), changes);
166 ASS_Event* CDVDSubtitlesLibass::GetEvents()
168 CSingleLock lock(m_section);
171 CLog::Log(LOGERROR, "CDVDSubtitlesLibass: %s - Missing ASS structs(m_track)", __FUNCTION__);
174 return m_track->events;
177 int CDVDSubtitlesLibass::GetNrOfEvents()
179 CSingleLock lock(m_section);
182 return m_track->n_events;