Skip to content

Commit

Permalink
sub: rewrite load order. file set by user won't be reset internally
Browse files Browse the repository at this point in the history
file set by user > auto load subtitles > embedded subtitles
  • Loading branch information
wang-bin committed Mar 17, 2016
1 parent 1c6b1ea commit 2d8c9c7
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 108 deletions.
15 changes: 6 additions & 9 deletions qml/QmlAV/QuickSubtitle.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -37,6 +37,7 @@ class QmlAVPlayer;
/*!
* \brief The QuickSubtitle class
* high level Subtitle processor for QML. No rendering.
* Subtitle load priority: user specified file (setFile(...)) > auto load external (autoLoad() must be true) > embedded subtitle
*/
class QuickSubtitle : public QObject, public QtAV::SubtitleAPIProxy
{
Expand Down Expand Up @@ -84,17 +85,13 @@ class QuickSubtitle : public QObject, public QtAV::SubtitleAPIProxy
bool isEnabled() const;
/*!
* \brief setFile
* load user selected subtitle. autoLoad must be false.
* if replay the same video, subtitle does not change
* if play a new video, you have to set subtitle again
* Load user selected subtitle. The subtitle will not change unless you manually setFile(QString()).
*/
void setFile(const QString& file);
QString file() const;
/*!
* \brief autoLoad
* auto find a suitable subtitle.
* if false, load the user selected subtile in setFile() (empty if start a new video)
* \return
* Auto find and load a suitable external subtitle if file() is not empty.
*/
bool autoLoad() const;
//void setAssFrameSize(int width, int height);
Expand Down
6 changes: 3 additions & 3 deletions qml/QuickSubtitle.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down
6 changes: 3 additions & 3 deletions src/QtAV/Subtitle.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2065 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down
15 changes: 6 additions & 9 deletions src/QtAV/SubtitleFilter.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -33,6 +33,7 @@ class SubtitleFilterPrivate;
/*!
* \brief The SubtitleFilter class
* draw text and image subtitles
* Subtitle load priority: user specified file (setFile(...)) > auto load external (autoLoad() must be true) > embedded subtitle
*/
class Q_AV_EXPORT SubtitleFilter : public VideoFilter, public SubtitleAPIProxy
{
Expand Down Expand Up @@ -66,17 +67,13 @@ class Q_AV_EXPORT SubtitleFilter : public VideoFilter, public SubtitleAPIProxy
}
/*!
* \brief setFile
* load user selected subtitle. autoLoad must be false.
* if replay the same video, subtitle does not change
* if play a new video, you have to set subtitle again
* Load user selected subtitle. The subtitle will not change unless you manually setFile(QString()).
*/
void setFile(const QString& file);
QString file() const;
/*!
* \brief autoLoad
* auto find a suitable subtitle.
* if false, load the user selected subtile in setFile() (empty if start a new video)
* \return
* Auto find and load a suitable external subtitle if file() is not empty.
*/
bool autoLoad() const;
// <1 means normalized. not valid means the whole target rect. default is (0, 0, 1, 0.9) and align bottom
Expand Down
16 changes: 6 additions & 10 deletions src/QtAV/private/PlayerSubtitle.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -35,6 +35,7 @@ class Subtitle;
/*!
* \brief The PlayerSubtitle class
* Bind Subtitle to AVPlayer. Used by SubtitleFilter and QuickSubtitle.
* Subtitle load priority: user specified file (setFile(...)) > auto load external (autoLoad() must be true) > embedded subtitle
*/
class Q_AV_PRIVATE_EXPORT PlayerSubtitle : public QObject
{
Expand All @@ -45,19 +46,14 @@ class Q_AV_PRIVATE_EXPORT PlayerSubtitle : public QObject
Subtitle* subtitle();
/*!
* \brief setFile
* load user selected subtitle. autoLoad must be false.
* if replay the same video, subtitle does not change
* if play a new video, you have to set subtitle again
* Load user selected subtitle. The subtitle will not change unless you manually setFile(QString()).
*/
void setFile(const QString& file);
QString file() const;
/*!
* \brief autoLoad
* auto find a suitable subtitle.
* if false, load the user selected subtile in setFile() (empty if start a new video)
* \return
* Auto find and load a suitable external subtitle if file() is not empty.
*/
// TODO: enable changed & autoload=> load
void setAutoLoad(bool value);
bool autoLoad() const;
Q_SIGNALS:
Expand Down
15 changes: 10 additions & 5 deletions src/filter/SubtitleFilter.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -84,6 +84,11 @@ SubtitleFilter::SubtitleFilter(QObject *parent) :
connect(this, SIGNAL(enabledChanged(bool)), d.player_sub.data(), SLOT(onEnabledChanged(bool)));
connect(d.player_sub.data(), SIGNAL(autoLoadChanged(bool)), this, SIGNAL(autoLoadChanged(bool)));
connect(d.player_sub.data(), SIGNAL(fileChanged()), this, SIGNAL(fileChanged()));

if (parent && !qstrcmp(parent->metaObject()->className(), "AVPlayer")) {
AVPlayer* p = reinterpret_cast<AVPlayer*>(parent);
setPlayer(p);
}
}

void SubtitleFilter::setPlayer(AVPlayer *player)
Expand Down Expand Up @@ -162,9 +167,9 @@ void SubtitleFilter::process(Statistics *statistics, VideoFrame *frame)
qWarning("no paint device!");
return;
}
if (frame && frame->timestamp() > 0.0)
d.player_sub->subtitle()->setTimestamp(frame->timestamp());
if (d.player_sub->subtitle()->canRender()) {
if (frame && frame->timestamp() > 0.0)
d.player_sub->subtitle()->setTimestamp(frame->timestamp()); //TODO: set to current display video frame's timestamp
QRect rect;
/*
* image quality maybe to low if use video frame resolution for large display.
Expand Down
120 changes: 54 additions & 66 deletions src/subtitle/PlayerSubtitle.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -107,7 +107,7 @@ void PlayerSubtitle::setAutoLoad(bool value)
if (m_auto == value)
return;
m_auto = value;
emit autoLoadChanged(value);
Q_EMIT autoLoadChanged(value);
}

bool PlayerSubtitle::autoLoad() const
Expand All @@ -117,10 +117,12 @@ bool PlayerSubtitle::autoLoad() const

void PlayerSubtitle::onPlayerSourceChanged()
{
m_file = QString();
if (!m_auto || !m_enabled) {
if (!m_auto) {
m_sub->setFileName(QString());
return;
}
if (!m_enabled)
return;
AVPlayer *p = qobject_cast<AVPlayer*>(sender());
if (!p)
return;
Expand All @@ -141,61 +143,54 @@ void PlayerSubtitle::onPlayerStart()
{
if (!m_enabled)
return;
if (!autoLoad()) {
// priority: user file > auto load file > embedded
if (!m_file.isEmpty()) {
if (m_file == m_sub->fileName())
return;
m_sub->setFileName(m_file);
m_sub->setFuzzyMatch(false);
if (m_file.isEmpty()) {
const int n = m_player->currentSubtitleStream();
if (n < 0 || m_tracks.isEmpty() || m_tracks.size() <= n) {
m_sub->processHeader(QByteArray(), QByteArray()); // reset
return;
}
QVariantMap track = m_tracks[n].toMap();
QByteArray codec(track.value(QStringLiteral("codec")).toByteArray());
QByteArray data(track.value(QStringLiteral("extra")).toByteArray());
m_sub->processHeader(codec, data);
} else {
m_sub->loadAsync();
}
m_sub->loadAsync();
return;
}
if (m_file != m_sub->fileName())
return;
if (!m_player)
if (autoLoad() && !m_sub->fileName().isEmpty())
return; //already loaded in onPlayerSourceChanged()
// try embedded subtitles
const int n = m_player->currentSubtitleStream();
if (n < 0 || m_tracks.isEmpty() || m_tracks.size() <= n) {
m_sub->processHeader(QByteArray(), QByteArray()); // reset
return;
// autoLoad was false then reload then true then reload
// previous loaded is user selected subtitle
m_sub->setFileName(getSubtitleBasePath(m_player->file()));
m_sub->setFuzzyMatch(true);
m_sub->loadAsync();
}
QVariantMap track = m_tracks[n].toMap();
QByteArray codec(track.value(QStringLiteral("codec")).toByteArray());
QByteArray data(track.value(QStringLiteral("extra")).toByteArray());
m_sub->processHeader(codec, data);
return;
}

void PlayerSubtitle::onEnabledChanged(bool value)
{
m_enabled = value;
if (value) {
if (m_player) {
connectSignals();
}
if (autoLoad()) {
if (!m_player)
return;
m_sub->setFileName(getSubtitleBasePath(m_player->file()));
m_sub->setFuzzyMatch(true);
m_sub->loadAsync();
} else {
m_sub->setFileName(m_file);
m_sub->setFuzzyMatch(false);
m_sub->loadAsync();
}
} else {
if (m_player) {
disconnectSignals();
}
if (!m_enabled) {
disconnectSignals();
return;
}
connectSignals();
// priority: user file > auto load file > embedded
if (!m_file.isEmpty()) {
if (m_sub->fileName() == m_file && m_sub->isLoaded())
return;
m_sub->setFileName(m_file);
m_sub->setFuzzyMatch(false);
m_sub->loadAsync();
}
if (!m_player)
return;
if (!autoLoad()) // fallback to internal subtitles
return;
m_sub->setFileName(getSubtitleBasePath(m_player->file()));
m_sub->setFuzzyMatch(true);
m_sub->loadAsync();
return;
}

void PlayerSubtitle::tryReload()
Expand All @@ -210,37 +205,26 @@ void PlayerSubtitle::tryReloadInternalSub()

void PlayerSubtitle::tryReload(int flag)
{
if (!m_player)
if (!m_enabled)
return;
if (!m_player->isPlaying())
return;
const int kReloadInternal = 1;
const int kReloadExternal = 1<<1;
if (flag & kReloadExternal) {
if (!m_file.isEmpty() && m_enabled) { //engine changed
m_sub->processHeader(QByteArray(), QByteArray()); // reset
m_sub->loadAsync();
return;
}
}
if (!(flag & kReloadInternal)) { // if internal flag is set, try internal first, then fallback to external if internal is failed
if (!m_enabled)
return;
if (flag & kReloadExternal) {
m_sub->processHeader(QByteArray(), QByteArray()); // reset
m_sub->loadAsync();
}
//engine or charset changed
m_sub->processHeader(QByteArray(), QByteArray()); // reset
m_sub->loadAsync();
return;
}

// kReloadExternal is not set, kReloadInternal is unknown
//fallback to external sub if no valid internal sub track is set
const int n = m_player->currentSubtitleStream();
if (n < 0 || m_tracks.isEmpty() || m_tracks.size() <= n) {
m_sub->processHeader(QByteArray(), QByteArray()); // reset, null processor
//try to fallback to external sub if an invalid internal sub track is set
if ((flag & kReloadExternal) && m_enabled)
m_sub->loadAsync();
m_sub->loadAsync();
return;
}
// try internal subtitles
QVariantMap track = m_tracks[n].toMap();
QByteArray codec(track.value(QStringLiteral("codec")).toByteArray());
QByteArray data(track.value(QStringLiteral("extra")).toByteArray());
Expand Down Expand Up @@ -270,6 +254,8 @@ void PlayerSubtitle::processInternalSubtitleHeader(const QByteArray& codec, cons

void PlayerSubtitle::connectSignals()
{
if (!m_player)
return;
connect(m_player, SIGNAL(sourceChanged()), this, SLOT(onPlayerSourceChanged()));
connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPlayerPositionChanged()));
connect(m_player, SIGNAL(started()), this, SLOT(onPlayerStart()));
Expand All @@ -284,6 +270,8 @@ void PlayerSubtitle::connectSignals()

void PlayerSubtitle::disconnectSignals()
{
if (!m_player)
return;
disconnect(m_player, SIGNAL(sourceChanged()), this, SLOT(onPlayerSourceChanged()));
disconnect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPlayerPositionChanged()));
disconnect(m_player, SIGNAL(started()), this, SLOT(onPlayerStart()));
Expand Down
8 changes: 5 additions & 3 deletions src/subtitle/Subtitle.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -466,6 +466,8 @@ void Subtitle::checkCapability()

void Subtitle::loadAsync()
{
if (fileName().isEmpty())
return;
class Loader : public QRunnable {
public:
Loader(Subtitle *sub) : m_sub(sub) {}
Expand Down

0 comments on commit 2d8c9c7

Please sign in to comment.