/* This file is part of the KDE project. Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 or 3 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include // For CCoeEnv #include #include "videoplayer.h" #include "utils.h" using namespace Phonon; using namespace Phonon::MMF; //----------------------------------------------------------------------------- // Constructor / destructor //----------------------------------------------------------------------------- MMF::VideoPlayer::VideoPlayer() : m_wsSession(NULL) , m_screenDevice(NULL) , m_window(NULL) { construct(); } MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player) : AbstractMediaPlayer(player) , m_wsSession(NULL) , m_screenDevice(NULL) , m_window(NULL) { construct(); } void MMF::VideoPlayer::construct() { TRACE_CONTEXT(VideoPlayer::VideoPlayer, EVideoApi); TRACE_ENTRY_0(); if(!m_videoOutput) { m_dummyVideoOutput.reset(new VideoOutput(NULL)); } const TInt priority = 0; const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; getNativeWindowSystemHandles(); // TODO: is this the correct way to handle errors which occur when // creating a Symbian object in the constructor of a Qt object? TRAPD(err, m_player = CVideoPlayerUtility::NewL ( *this, priority, preference, *m_wsSession, *m_screenDevice, *m_window, m_windowRect, m_clipRect ) ); if(KErrNone != err) { changeState(ErrorState); } TRACE_EXIT_0(); } MMF::VideoPlayer::~VideoPlayer() { TRACE_CONTEXT(VideoPlayer::~VideoPlayer, EVideoApi); TRACE_ENTRY_0(); delete m_player; TRACE_EXIT_0(); } //----------------------------------------------------------------------------- // Public API //----------------------------------------------------------------------------- void MMF::VideoPlayer::doPlay() { m_player->Play(); } void MMF::VideoPlayer::doPause() { TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi); TRAPD(err, m_player->PauseL()); if(KErrNone != err) { TRACE("PauseL error %d", err); setError(NormalError); } } void MMF::VideoPlayer::doStop() { m_player->Stop(); } int MMF::VideoPlayer::setDeviceVolume(int mmfVolume) { TRAPD(err, m_player->SetVolumeL(mmfVolume)); return err; } int MMF::VideoPlayer::openFile(RFile& file) { TRAPD(err, m_player->OpenFileL(file)); return err; } void MMF::VideoPlayer::close() { m_player->Close(); } void MMF::VideoPlayer::seek(qint64 ms) { TRACE_CONTEXT(VideoPlayer::seek, EVideoApi); TRACE_ENTRY("state %d pos %Ld", state(), ms); TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms))); if(KErrNone != err) { TRACE("SetPositionL error %d", err); setError(NormalError); } TRACE_EXIT_0(); } bool MMF::VideoPlayer::hasVideo() const { return true; } qint64 MMF::VideoPlayer::currentTime() const { TRACE_CONTEXT(VideoPlayer::currentTime, EVideoApi); TTimeIntervalMicroSeconds us; TRAPD(err, us = m_player->PositionL()) qint64 result = 0; if(KErrNone == err) { result = toMilliSeconds(us); } else { TRACE("PositionL error %d", err); // If we don't cast away constness here, we simply have to ignore // the error. const_cast(this)->setError(NormalError); } return result; } qint64 MMF::VideoPlayer::totalTime() const { TRACE_CONTEXT(VideoPlayer::totalTime, EVideoApi); qint64 result = 0; TRAPD(err, result = toMilliSeconds(m_player->DurationL())); if(KErrNone != err) { TRACE("DurationL error %d", err); // If we don't cast away constness here, we simply have to ignore // the error. const_cast(this)->setError(NormalError); } return result; } //----------------------------------------------------------------------------- // MVideoPlayerUtilityObserver callbacks //----------------------------------------------------------------------------- void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError) { TRACE_CONTEXT(VideoPlayer::MvpuoOpenComplete, EVideoApi); TRACE_ENTRY("state %d error %d", state(), aError); __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); if(KErrNone == aError) { m_player->Prepare(); } else { // TODO: set different error states according to value of aError? setError(NormalError); } TRACE_EXIT_0(); } void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError) { TRACE_CONTEXT(VideoPlayer::MvpuoPrepareComplete, EVideoApi); TRACE_ENTRY("state %d error %d", state(), aError); __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); if(KErrNone == aError) { maxVolumeChanged(m_player->MaxVolume()); emit totalTimeChanged(); changeState(StoppedState); } else { // TODO: set different error states according to value of aError? setError(NormalError); } TRACE_EXIT_0(); } void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) { TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi); TRACE_ENTRY("state %d error %d", state(), aError); // TODO Q_UNUSED(aFrame); Q_UNUSED(aError); // suppress warnings in release builds TRACE_EXIT_0(); } void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError) { TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi) TRACE_ENTRY("state %d error %d", state(), aError); // TODO Q_UNUSED(aError); // suppress warnings in release builds TRACE_EXIT_0(); } void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) { TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi); TRACE_ENTRY("state %d", state()); // TODO Q_UNUSED(aEvent); TRACE_EXIT_0(); } //----------------------------------------------------------------------------- // Private functions //----------------------------------------------------------------------------- VideoOutput& MMF::VideoPlayer::videoOutput() { TRACE_CONTEXT(VideoPlayer::videoOutput, EVideoInternal); TRACE("videoOutput 0x%08x dummy 0x%08x", m_videoOutput, m_dummyVideoOutput.data()); return m_videoOutput ? *m_videoOutput : *m_dummyVideoOutput; } void MMF::VideoPlayer::videoOutputChanged() { TRACE_CONTEXT(VideoPlayer::videoOutputChanged, EVideoInternal); TRACE_ENTRY_0(); // Lazily construct a dummy output if needed here if(!m_videoOutput and m_dummyVideoOutput.isNull()) { m_dummyVideoOutput.reset(new VideoOutput(NULL)); } getNativeWindowSystemHandles(); TRAPD(err, m_player->SetDisplayWindowL ( *m_wsSession, *m_screenDevice, *m_window, m_windowRect, m_clipRect ) ); if(KErrNone != err) { TRACE("SetDisplayWindowL error %d", err); setError(NormalError); } TRACE_EXIT_0(); } void MMF::VideoPlayer::getNativeWindowSystemHandles() { TRACE_CONTEXT(VideoPlayer::getNativeWindowSystemHandles, EVideoInternal); CCoeControl* const control = videoOutput().winId(); TRACE("control 0x%08x", control); TRACE("control isVisible %d", control->IsVisible()); TRACE("control isDimmed %d", control->IsDimmed()); TRACE("control hasBorder %d", control->HasBorder()); TRACE("control position %d %d", control->Position().iX, control->Position().iY); TRACE("control rect %d %d - %d %d", control->Rect().iTl.iX, control->Rect().iTl.iY, control->Rect().iBr.iX, control->Rect().iBr.iY); CCoeEnv* const coeEnv = control->ControlEnv(); m_wsSession = &(coeEnv->WsSession()); TRACE("session handle %d", m_wsSession->Handle()); m_screenDevice = coeEnv->ScreenDevice(); TRACE("device srv handle %d", m_screenDevice->WsHandle()); m_window = control->DrawableWindow(); TRACE("window cli handle %d", m_window->ClientHandle()); TRACE("window srv handle %d", m_window->WsHandle()); TRACE("window group %d", m_window->WindowGroupId()); TRACE("window position %d %d", m_window->Position().iX, m_window->Position().iY); m_windowRect = control->Rect(); m_clipRect = control->Rect(); }