~ubuntu-branches/ubuntu/quantal/mythtv/quantal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "mythlogging.h"
#include "subtitlereader.h"

SubtitleReader::SubtitleReader()
  : m_AVSubtitlesEnabled(false), m_TextSubtitlesEnabled(false),
    m_RawTextSubtitlesEnabled(false)
{
}

SubtitleReader::~SubtitleReader()
{
    ClearAVSubtitles();
    m_TextSubtitles.Clear();
    ClearRawTextSubtitles();
}

void SubtitleReader::EnableAVSubtitles(bool enable)
{
    m_AVSubtitlesEnabled = enable;
}

void SubtitleReader::EnableTextSubtitles(bool enable)
{
    m_TextSubtitlesEnabled = enable;
}

void SubtitleReader::EnableRawTextSubtitles(bool enable)
{
    m_RawTextSubtitlesEnabled = enable;
}

bool SubtitleReader::AddAVSubtitle(const AVSubtitle &subtitle,
                                   bool fix_position,
                                   bool allow_forced)
{
    bool enableforced = false;
    if (!m_AVSubtitlesEnabled && !subtitle.forced)
    {
        FreeAVSubtitle(subtitle);
        return enableforced;
    }

    if (!m_AVSubtitlesEnabled && subtitle.forced)
    {
        if (!allow_forced)
        {
            LOG(VB_PLAYBACK, LOG_INFO,
                "SubtitleReader: Ignoring forced AV subtitle.");
            FreeAVSubtitle(subtitle);
            return enableforced;
        }
        LOG(VB_PLAYBACK, LOG_INFO,
            "SubtitleReader: Allowing forced AV subtitle.");
        enableforced = true;
    }

    bool clearsubs = false;
    m_AVSubtitles.lock.lock();
    m_AVSubtitles.fixPosition = fix_position;
    m_AVSubtitles.buffers.push_back(subtitle);
    // in case forced subtitles aren't displayed, avoid leaking by
    // manually clearing the subtitles
    if (m_AVSubtitles.buffers.size() > 20)
    {
        LOG(VB_GENERAL, LOG_ERR,
            "SubtitleReader: >20 AVSubtitles queued - clearing.");
        clearsubs = true;
    }
    m_AVSubtitles.lock.unlock();

    if (clearsubs)
        ClearAVSubtitles();

    return enableforced;
}

void SubtitleReader::ClearAVSubtitles(void)
{
    m_AVSubtitles.lock.lock();
    while (!m_AVSubtitles.buffers.empty())
    {
        FreeAVSubtitle(m_AVSubtitles.buffers.front());
        m_AVSubtitles.buffers.pop_front();
    }
    m_AVSubtitles.lock.unlock();
}

void SubtitleReader::FreeAVSubtitle(const AVSubtitle &subtitle)
{
    for (std::size_t i = 0; i < subtitle.num_rects; ++i)
    {
         AVSubtitleRect* rect = subtitle.rects[i];
         av_free(rect->pict.data[0]);
         av_free(rect->pict.data[1]);
    }
    if (subtitle.num_rects > 0)
        av_free(subtitle.rects);
}

bool SubtitleReader::LoadExternalSubtitles(const QString &subtitleFileName)
{
    m_TextSubtitles.Clear();
    return TextSubtitleParser::LoadSubtitles(subtitleFileName, m_TextSubtitles);
}

bool SubtitleReader::HasTextSubtitles(void)
{
    return m_TextSubtitles.GetSubtitleCount() > 0;
}

QStringList SubtitleReader::GetRawTextSubtitles(uint64_t &duration)
{
    QMutexLocker lock(&m_RawTextSubtitles.lock);
    if (m_RawTextSubtitles.buffers.empty())
        return QStringList();

    duration = m_RawTextSubtitles.duration;
    QStringList result = m_RawTextSubtitles.buffers;
    result.detach();
    m_RawTextSubtitles.buffers.clear();
    return result;
}

void SubtitleReader::AddRawTextSubtitle(QStringList list, uint64_t duration)
{
    if (!m_RawTextSubtitlesEnabled || list.empty())
        return;

    QMutexLocker lock(&m_RawTextSubtitles.lock);
    m_RawTextSubtitles.buffers.clear();
    m_RawTextSubtitles.buffers = list;
    m_RawTextSubtitles.duration = duration;
}

void SubtitleReader::ClearRawTextSubtitles(void)
{
    QMutexLocker lock(&m_RawTextSubtitles.lock);
    m_RawTextSubtitles.buffers.clear();
}