diff options
author | Dimitri John Ledkov <dimitri.ledkov@canonical.com> | 2014-02-20 16:10:52 +0000 |
---|---|---|
committer | Dimitri John Ledkov <dimitri.ledkov@canonical.com> | 2014-02-20 19:15:57 +0000 |
commit | d20f4a64eba38690337ac914a04a113de7caf125 (patch) | |
tree | 6828990e93ca5d8847b8cde2f2febb6566b0d53f /src/player/SoundNode.cpp | |
parent | 28161e9209f21be1a600f637565ecede94855a36 (diff) |
New upstream release. Closes: #721047debian/1.8.0-1
Drop all patches, none are needed with this new upstream release.
Port to dh.
Specify foreign in configure.ac.
Diffstat (limited to 'src/player/SoundNode.cpp')
-rw-r--r-- | src/player/SoundNode.cpp | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/src/player/SoundNode.cpp b/src/player/SoundNode.cpp index 9d31597..3bb089c 100644 --- a/src/player/SoundNode.cpp +++ b/src/player/SoundNode.cpp @@ -1,6 +1,6 @@ // // libavg - Media Playback Engine. -// Copyright (C) 2003-2011 Ulrich von Zadow +// Copyright (C) 2003-2014 Ulrich von Zadow // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,18 +20,18 @@ // #include "SoundNode.h" #include "Player.h" -#include "NodeDefinition.h" +#include "TypeDefinition.h" #include "Canvas.h" #include "../base/Exception.h" #include "../base/Logger.h" #include "../base/ScopeTimer.h" #include "../base/XMLHelper.h" +#include "../base/ObjectCounter.h" -#include "../audio/SDLAudioEngine.h" +#include "../audio/AudioEngine.h" #include "../video/AsyncVideoDecoder.h" -#include "../video/FFMpegDecoder.h" #include <iostream> #include <sstream> @@ -40,33 +40,35 @@ #include <unistd.h> #endif -using namespace boost::python; +using namespace boost; using namespace std; namespace avg { -NodeDefinition SoundNode::createDefinition() +void SoundNode::registerType() { - return NodeDefinition("sound", Node::buildNode<SoundNode>) - .extendDefinition(AreaNode::createDefinition()) + TypeDefinition def = TypeDefinition("sound", "areanode", + ExportedObject::buildObject<SoundNode>) .addArg(Arg<UTF8String>("href", "", false, offsetof(SoundNode, m_href))) .addArg(Arg<bool>("loop", false, false, offsetof(SoundNode, m_bLoop))) - .addArg(Arg<double>("volume", 1.0, false, offsetof(SoundNode, m_Volume))) + .addArg(Arg<float>("volume", 1.0, false, offsetof(SoundNode, m_Volume))) ; + TypeRegistry::get()->registerType(def); } SoundNode::SoundNode(const ArgList& args) : m_Filename(""), m_pEOFCallback(0), + m_SeekBeforeCanRenderTime(0), m_pDecoder(0), m_Volume(1.0), - m_State(Unloaded) + m_State(Unloaded), + m_AudioID(-1) { args.setMembers(this); m_Filename = m_href; initFilename(m_Filename); - VideoDecoderPtr pSyncDecoder(new FFMpegDecoder()); - m_pDecoder = new AsyncVideoDecoder(pSyncDecoder, 8); + m_pDecoder = new AsyncVideoDecoder(8); ObjectCounter::get()->incRef(&typeid(*this)); } @@ -110,7 +112,7 @@ int SoundNode::getNumAudioChannels() const long long SoundNode::getCurTime() const { exceptionIfUnloaded("getCurTime"); - return (long long)(m_pDecoder->getCurTime(SS_AUDIO)*1000); + return (long long)(m_pDecoder->getCurTime()*1000); } void SoundNode::seekToTime(long long Time) @@ -129,13 +131,19 @@ void SoundNode::setEOFCallback(PyObject * pEOFCallback) if (m_pEOFCallback) { Py_DECREF(m_pEOFCallback); } - Py_INCREF(pEOFCallback); - m_pEOFCallback = pEOFCallback; + if (pEOFCallback == Py_None) { + m_pEOFCallback = 0; + } else { + avgDeprecationWarning("1.8", "SoundNode.setEOFCallback()", + "Node.subscribe(END_OF_FILE)"); + Py_INCREF(pEOFCallback); + m_pEOFCallback = pEOFCallback; + } } void SoundNode::connectDisplay() { - if (!SDLAudioEngine::get()) { + if (!AudioEngine::get()) { throw Exception(AVG_ERR_UNSUPPORTED, "Sound nodes can only be created if audio is not disabled."); } @@ -154,6 +162,7 @@ void SoundNode::connectDisplay() void SoundNode::connect(CanvasPtr pCanvas) { + checkReload(); AreaNode::connect(pCanvas); pCanvas->registerFrameEndListener(this); } @@ -194,19 +203,19 @@ void SoundNode::setHRef(const UTF8String& href) checkReload(); } -double SoundNode::getVolume() +float SoundNode::getVolume() { return m_Volume; } -void SoundNode::setVolume(double volume) +void SoundNode::setVolume(float volume) { if (volume < 0) { volume = 0; } m_Volume = volume; - if (m_pDecoder) { - m_pDecoder->setVolume(volume); + if (m_AudioID != -1) { + AudioEngine::get()->setSourceVolume(m_AudioID, volume); } } @@ -215,13 +224,12 @@ void SoundNode::checkReload() string fileName (m_href); if (m_href != "") { initFilename(fileName); - if (fileName != m_Filename) { - SoundState oldState = m_State; + if (fileName != m_Filename && m_State != Unloaded) { changeSoundState(Unloaded); m_Filename = fileName; - if (oldState != Unloaded) { - changeSoundState(Paused); - } + changeSoundState(Paused); + } else { + m_Filename = fileName; } } else { changeSoundState(Unloaded); @@ -231,17 +239,12 @@ void SoundNode::checkReload() void SoundNode::onFrameEnd() { - if (m_State == Playing && m_pDecoder->isEOF(SS_AUDIO)) { - onEOF(); - } -} - -int SoundNode::fillAudioBuffer(AudioBufferPtr pBuffer) -{ if (m_State == Playing) { - return m_pDecoder->fillAudioBuffer(pBuffer); - } else { - return 0; + m_pDecoder->updateAudioStatus(); + } + if (m_State == Playing && m_pDecoder->isEOF()) { + NodePtr pTempThis = getSharedThis(); + onEOF(); } } @@ -265,8 +268,10 @@ void SoundNode::changeSoundState(SoundState newSoundState) } if (newSoundState == Paused) { m_PauseStartTime = curTime; + AudioEngine::get()->pauseSource(m_AudioID); } else if (newSoundState == Playing && m_State == Paused) { m_PauseTime += curTime-m_PauseStartTime; + AudioEngine::get()->playSource(m_AudioID); } } m_State = newSoundState; @@ -274,16 +279,22 @@ void SoundNode::changeSoundState(SoundState newSoundState) void SoundNode::seek(long long destTime) { - m_pDecoder->seek(double(destTime)/1000); - m_StartTime = Player::get()->getFrameTime() - destTime; - m_PauseTime = 0; - m_PauseStartTime = Player::get()->getFrameTime(); + if (getState() == NS_CANRENDER) { + AudioEngine::get()->notifySeek(m_AudioID); + m_pDecoder->seek(float(destTime)/1000); + m_StartTime = Player::get()->getFrameTime() - destTime; + m_PauseTime = 0; + m_PauseStartTime = Player::get()->getFrameTime(); + } else { + // If we get a seek command before decoding has really started, we need to defer + // the actual seek until the decoder is ready. + m_SeekBeforeCanRenderTime = destTime; + } } void SoundNode::open() { - m_pDecoder->setVolume(m_Volume); - m_pDecoder->open(m_Filename, true); + m_pDecoder->open(m_Filename, false, true); VideoInfo videoInfo = m_pDecoder->getVideoInfo(); if (!videoInfo.m_bHasAudio) { throw Exception(AVG_ERR_VIDEO_GENERAL, @@ -294,14 +305,23 @@ void SoundNode::open() void SoundNode::startDecoding() { - SDLAudioEngine* pEngine = SDLAudioEngine::get(); + AudioEngine* pEngine = AudioEngine::get(); m_pDecoder->startDecoding(false, pEngine->getParams()); - pEngine->addSource(this); + m_AudioID = pEngine->addSource(*m_pDecoder->getAudioMsgQ(), + *m_pDecoder->getAudioStatusQ()); + pEngine->setSourceVolume(m_AudioID, m_Volume); + if (m_SeekBeforeCanRenderTime != 0) { + seek(m_SeekBeforeCanRenderTime); + m_SeekBeforeCanRenderTime = 0; + } } void SoundNode::close() { - SDLAudioEngine::get()->removeSource(this); + if (m_AudioID != -1) { + AudioEngine::get()->removeSource(m_AudioID); + m_AudioID = -1; + } m_pDecoder->close(); } @@ -309,7 +329,7 @@ void SoundNode::exceptionIfUnloaded(const std::string& sFuncName) const { if (m_State == Unloaded) { throw Exception(AVG_ERR_VIDEO_GENERAL, - string("SoundNode.")+sFuncName+" failed: video not loaded."); + string("SoundNode.")+sFuncName+" failed: sound not loaded."); } } @@ -324,10 +344,11 @@ void SoundNode::onEOF() PyObject * result = PyEval_CallObject(m_pEOFCallback, arglist); Py_DECREF(arglist); if (!result) { - throw error_already_set(); + throw py::error_already_set(); } Py_DECREF(result); } + notifySubscribers("END_OF_FILE"); } } |