2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <mm_player.h>
19 #include <dpl/log/log.h>
20 #include <Commons/Exception.h>
23 namespace WrtDeviceApis {
28 MMPlayer::MMPlayer() :
29 Commons::EventListener<EventOnEOS>(Commons::ThreadEnum::NULL_THREAD),
31 m_currentState(STATE_UNDEFINED),
36 } Catch(Commons::Exception) {
37 LogError("Unknown exception while constructing MMPlayer");
47 MMHandleType MMPlayer::getHandler() const
52 void MMPlayer::setEmitter(const EventOnStateChangeEmitterPtr& emitter)
55 DPL::Mutex::ScopedLock lock(&m_emitterMtx);
56 m_onStateChangeEmitter = emitter;
59 EventOnStateChangeEmitterPtr MMPlayer::getEmitter()
61 DPL::Mutex::ScopedLock lock(&m_emitterMtx);
62 return m_onStateChangeEmitter;
65 void MMPlayer::clearEmitter()
68 DPL::Mutex::ScopedLock lock(&m_emitterMtx);
69 m_onStateChangeEmitter.Reset();
72 int MMPlayer::onStateChange(int message,
77 static DPL::Mutex playerMtx;
78 MMPlayer *this_ = static_cast<MMPlayer*>(data);
80 EventOnStateChangePtr event(new EventOnStateChange());
81 { //Separated block to avoid deadlock when this_->m_emitterMtx will be locked
82 DPL::Mutex::ScopedLock lock(&playerMtx);
84 case MM_MESSAGE_ERROR:
86 MMMessageParamType* type =
87 static_cast<MMMessageParamType*>(param);
88 if (type && (MM_MSG_UNION_CODE == type->union_type)) {
90 "Error from platform, code: " << std::hex <<
93 event->setPlayerState(EventOnStateChange::BEGIN);
97 case MM_MESSAGE_BEGIN_OF_STREAM:
98 LogInfo("Begin of stream");
99 event->setPlayerState(EventOnStateChange::PLAYING);
102 case MM_MESSAGE_END_OF_STREAM:
103 LogInfo("End of stream");
104 event->setPlayerState(EventOnStateChange::COMPLETED);
106 // mm_player_stop should be executed outside the callback
108 EventOnEOSPtr eventEOS(new EventOnEOS());
109 if (this_->m_onEOSEmitter) {
110 this_->m_onEOSEmitter->emit(eventEOS);
112 LogError("EOS emitter not set");
117 case MM_MESSAGE_STATE_INTERRUPTED:
118 // since platform reports always param->union_type == 0, only what can be done is to use field code
119 // and pray it won't be changed right before demo
121 MMMessageParamType* type =
122 static_cast<MMMessageParamType*>(param);
123 LogInfo("Player callback message: " << std::hex << message);
124 if (type && (MM_MSG_UNION_CODE == type->union_type)) {
125 LogError("Code: " << std::hex << type->code);
126 if (MM_PLAYER_STATE_PAUSED == type->code) {
127 LogInfo("Sending pause event");
128 event->setPlayerState(EventOnStateChange::PAUSED);
137 LogInfo("Player callback message: " << std::hex << message);
138 MMMessageParamType* type =
139 static_cast<MMMessageParamType*>(param);
140 if (type && (MM_MSG_UNION_CODE == type->union_type)) {
141 LogInfo("Code: " << type->code);
147 DPL::Mutex::ScopedLock lock(&this_->m_emitterMtx);
148 if (this_->m_onStateChangeEmitter) {
149 this_->m_onStateChangeEmitter->emit(event);
156 void MMPlayer::init()
159 int err = mm_player_create(&m_player);
160 if (MM_ERROR_NONE != err || !m_player) {
161 LogError("Can't create player");
162 Throw(Commons::PlatformException);
165 err = mm_player_set_message_callback(m_player,
166 MMPlayer::onStateChange,
168 if (MM_ERROR_NONE != err) {
169 LogDebug("Can't set player's callback. Error code: " << std::hex << err);
170 mm_player_destroy(m_player);
171 ThrowMsg(Commons::PlatformException, "Can't set player's callback.");
173 //Set emmiter for EOS event
174 m_onEOSEmitter.Reset(new EventOnEOSEmitter());
175 m_onEOSEmitter->setListener(this);
178 void MMPlayer::finalize()
181 //if the music is playing, stop music.
182 if (MM_PLAYER_STATE_PLAYING == getState()) {
183 LogInfo("Sending stop request");
184 int err = mm_player_stop(m_player);
185 if (MM_ERROR_NONE != err) {
186 LogError("Can't stop player. Error code: " << std::hex << err);
190 int err = mm_player_set_message_callback(m_player, NULL, NULL);
191 if (MM_ERROR_NONE != err) {
192 LogDebug("Can't set player's callback. Error code: " << std::hex << err);
194 err = mm_player_destroy(m_player);
195 if (MM_ERROR_NONE != err) {
197 "There were some problems during player destruction. Error code: "
202 MMPlayerStateType MMPlayer::getState() const
204 MMPlayerStateType state;
205 int err = mm_player_get_state(m_player, &state);
206 if (MM_ERROR_NONE != err) {
207 LogError("Can't get player status. Error code: " << std::hex << err);
208 ThrowMsg(Commons::PlatformException, "Can't get player status.");
210 LogInfo("Current player state: " << static_cast<int>(state));
214 void MMPlayer::onAnswerReceived(const EventOnEOSPtr& /*event*/)
217 int err = mm_player_stop(m_player);
218 if (MM_ERROR_NONE != err) {
219 LogError("Can't stop player. Error code: " << std::hex << err);
221 LogInfo("Repeat " << m_repeatTimes << " more time" <<
222 ((m_repeatTimes == 1) ? "" : "s"));
223 if (m_repeatTimes > 0) {
225 int err = mm_player_start(m_player);
226 if (MM_ERROR_NONE != err) {
227 LogError("Can't start play. Error code: " << std::hex << err);
232 unsigned int MMPlayer::getRepeatTimes() const
234 return m_repeatTimes;
237 void MMPlayer::setRepeatTimes(unsigned int count)
239 m_repeatTimes = count;