void QOpenSLESAudioOutput::start(QIODevice *device) { Q_ASSERT(device); destroyPlayer(); m_pullMode = true; if (!preparePlayer()) return; m_audioSource = device; setState(QAudio::ActiveState); setError(QAudio::NoError); // Attempt to fill buffers first. for (int i = 0; i != BUFFER_COUNT; ++i) { const int index = i * m_bufferSize; const qint64 readSize = m_audioSource->read(m_buffers + index, m_bufferSize); if (readSize && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf, m_buffers + index, readSize)) { setError(QAudio::FatalError); destroyPlayer(); return; } m_processedBytes += readSize; } // Change the state to playing. // We need to do this after filling the buffers or processedBytes might get corrupted. if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) { setError(QAudio::FatalError); destroyPlayer(); } }
TEST_F( VideoPlayerZIndex, video_overlayed ) { ASSERT_TRUE( _player->setProperty( "src", util::getImageName("video.mp4") )); ASSERT_TRUE( _player->setProperty( "bounds", canvas::Rect(0,0,100,100) )); player::Player* imgPlayer1 = createPlayer( player::type::image ); ASSERT_TRUE ( imgPlayer1->setProperty( "src", util::getImageName("image.png") ) ); ASSERT_TRUE ( imgPlayer1->setProperty( "bounds", canvas::Rect(0,0,720,576) ) ); ASSERT_TRUE ( imgPlayer1->setProperty( "fit","fill" ) ); ASSERT_TRUE ( imgPlayer1->setProperty( "zIndex", 0 ) ); ASSERT_TRUE ( imgPlayer1->play() ); player::Player* imgPlayer2 = createPlayer( player::type::image ); ASSERT_TRUE ( imgPlayer2->setProperty( "src", util::getImageName("red_100_100.jpg") ) ); ASSERT_TRUE ( imgPlayer2->setProperty( "bounds", canvas::Rect(0,0,360,288) ) ); ASSERT_TRUE ( imgPlayer2->setProperty( "fit","fill" ) ); ASSERT_TRUE ( imgPlayer2->setProperty( "zIndex", 1 ) ); ASSERT_TRUE ( imgPlayer2->play() ); player::Player* imgPlayer3 = createPlayer( player::type::image ); ASSERT_TRUE ( imgPlayer3->setProperty( "src", util::getImageName("green.jpg") ) ); ASSERT_TRUE ( imgPlayer3->setProperty( "bounds", canvas::Rect(360,288,360,288) ) ); ASSERT_TRUE ( imgPlayer3->setProperty( "fit","fill" ) ); ASSERT_TRUE ( imgPlayer3->setProperty( "zIndex", 3 ) ); ASSERT_TRUE ( imgPlayer3->play() ); ASSERT_TRUE ( _player->setProperty( "bounds", canvas::Rect(240,192,240,192) ) ); ASSERT_TRUE ( _player->setProperty( "zIndex", 2 ) ); ASSERT_TRUE ( _player->play() ); ASSERT_TRUE ( util::compareImages( canvas(), getExpectedPath("video_overlayed")) ); destroyPlayer( imgPlayer1 ); destroyPlayer( imgPlayer2 ); destroyPlayer( imgPlayer3 ); }
void QOpenSLESAudioOutput::bufferAvailable(quint32 count, quint32 playIndex) { Q_UNUSED(count); Q_UNUSED(playIndex); if (m_state == QAudio::StoppedState) return; if (!m_pullMode) { // We're in push mode. // Signal that there is a new open slot in the buffer and return m_availableBuffers.fetchAndAddRelease(1); return; } // We're in pull mode. const int index = m_nextBuffer * m_bufferSize; const qint64 readSize = m_audioSource->read(m_buffers + index, m_bufferSize); if (1 > readSize) return; if (SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf, m_buffers + index, readSize)) { setError(QAudio::FatalError); destroyPlayer(); return; } m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT; QMetaObject::invokeMethod(this, "onBytesProcessed", Qt::QueuedConnection, Q_ARG(qint64, readSize)); }
void QOpenSLESAudioOutput::startPlayer() { if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) { setError(QAudio::FatalError); destroyPlayer(); } }
void PlayerManager::doFrame(Ogre::Real fracSec, GUI* gui) { if(!mDestroyQueue.empty()) { DestroyQueue::iterator idq; for(idq = mDestroyQueue.begin(); idq != mDestroyQueue.end(); ++idq) { if(playerExists((Ogre::String)(*idq))) { destroyPlayer((Ogre::String)*idq); } } mDestroyQueue.clear(); } PlayerMap::iterator i; for(i = mPlayerMap.begin(); i != mPlayerMap.end(); ++i) { ControllerPlayer* cp = (ControllerPlayer*)i->second; if(cp->controller) { cp->controller->doFrame(fracSec); } cp->player->doFrame(fracSec); if(!cp->controller) continue; SmartController* c = dynamic_cast<SmartController*>(cp->controller); if(c) { gui->displayStats(cp->player->getName(), c->getStateString(), c->hasTarget() ? c->getTarget()->getName() : "NONE"); } //gui->displayStats(cp->player->getName(), cp->player->getActualInertialSpeed(), //cp->player->getInertialPitch(), cp->player->getInertialYaw(), //cp->player->getInertialRoll()); } }
qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len) { if (!len || !m_availableBuffers.load()) return 0; if (len > m_bufferSize) len = m_bufferSize; const int index = m_nextBuffer * m_bufferSize; ::memcpy(m_buffers + index, data, len); const SLuint32 res = (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf, m_buffers + index, len); if (res == SL_RESULT_BUFFER_INSUFFICIENT) return 0; if (res != SL_RESULT_SUCCESS) { setError(QAudio::FatalError); destroyPlayer(); return -1; } m_processedBytes += len; m_availableBuffers.fetchAndAddRelaxed(-1); setState(QAudio::ActiveState); setError(QAudio::NoError); m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT; return len; }
void QOpenSLESAudioOutput::bufferAvailable(quint32 count, quint32 playIndex) { Q_UNUSED(count); Q_UNUSED(playIndex); if (m_state == QAudio::StoppedState) return; if (!m_pullMode) { m_availableBuffers.fetchAndAddRelaxed(1); return; } const int index = m_nextBuffer * m_bufferSize; const qint64 readSize = m_audioSource->read(m_buffers + index, m_bufferSize); if (1 > readSize) return; if (SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf, m_buffers + index, readSize)) { setError(QAudio::FatalError); destroyPlayer(); return; } m_processedBytes += readSize; m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT; }
void QOpenSLESAudioOutput::stop() { if (m_state == QAudio::StoppedState) return; destroyPlayer(); setError(QAudio::NoError); }
void PlayerManager::removePlayer(const uint64& guid) { auto iter = _players.find(guid); if (iter != _players.end()) { Player* player = iter->second; destroyPlayer(player); _players.erase(guid); } }
QIODevice *QOpenSLESAudioOutput::start() { destroyPlayer(); m_pullMode = false; if (!preparePlayer()) return Q_NULLPTR; m_audioSource = new SLIODevicePrivate(this); m_audioSource->open(QIODevice::WriteOnly | QIODevice::Unbuffered); // Change the state to playing if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) { setError(QAudio::FatalError); destroyPlayer(); } setState(QAudio::IdleState); return m_audioSource; }
void QOpenSLESAudioOutput::suspend() { if (m_state != QAudio::ActiveState && m_state != QAudio::IdleState) return; if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PAUSED)) { setError(QAudio::FatalError); destroyPlayer(); return; } setState(QAudio::SuspendedState); setError(QAudio::NoError); }
TEST_F( VideoPlayerLocation, move_topleft_to_bottomright_out_of_bounds ) { ASSERT_TRUE( _player->setProperty( "src", util::getImageName("video.mp4") )); ASSERT_TRUE( _player->setProperty( "bounds", canvas::Rect(0,0,100,100) )); player::Player* imgPlayer = createPlayer( player::type::image ); impl::setBackgroundImg(imgPlayer); ASSERT_TRUE( _player->play() ); ASSERT_TRUE ( util::compareImages( canvas(), getExpectedPath("before_moving")) ); ASSERT_FALSE ( _player->setProperty( "bounds", canvas::Rect(700,500,100,100) )); ASSERT_TRUE ( util::compareImages( canvas(), getExpectedPath("before_moving") ) ); destroyPlayer(imgPlayer); }
TEST_F( VideoPlayerLocation, move_and_resize) { ASSERT_TRUE( _player->setProperty( "src", util::getImageName("video.mp4") )); ASSERT_TRUE( _player->setProperty( "bounds", canvas::Rect(0,0,100,100) )); player::Player* imgPlayer = createPlayer( player::type::image ); impl::setBackgroundImg(imgPlayer); ASSERT_TRUE( _player->play() ); ASSERT_TRUE ( util::compareImages( canvas(), getExpectedPath("before_moving")) ); ASSERT_TRUE ( _player->setProperty( "bounds", canvas::Rect(520,376,200,200) )); ASSERT_TRUE ( util::compareImages( canvas(), getExpectedPath("after_moving_and_resizeing") ) ); destroyPlayer(imgPlayer); }
qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len) { if (!len) return 0; if (len > m_bufferSize) len = m_bufferSize; // Acquire one slot in the buffer const int before = m_availableBuffers.fetchAndAddAcquire(-1); // If there where no vacant slots, then we just overdrew the buffer account... if (before < 1) { m_availableBuffers.fetchAndAddRelease(1); return 0; } const int index = m_nextBuffer * m_bufferSize; ::memcpy(m_buffers + index, data, len); const SLuint32 res = (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf, m_buffers + index, len); // If we where unable to enqueue a new buffer, give back the acquired slot. if (res == SL_RESULT_BUFFER_INSUFFICIENT) { m_availableBuffers.fetchAndAddRelease(1); return 0; } if (res != SL_RESULT_SUCCESS) { setError(QAudio::FatalError); destroyPlayer(); return -1; } m_processedBytes += len; setState(QAudio::ActiveState); setError(QAudio::NoError); m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT; return len; }
TunnelRenderer::~TunnelRenderer() { destroyPlayer(); }
QOpenSLESAudioOutput::~QOpenSLESAudioOutput() { destroyPlayer(); }
void authentificationThread() { // initialisation de la structure sockaddr_in d'ecoute. AccountsList *list = loadAccountsFromFile(ACCOUNTS_FILE); // ajouter la détection de l'existence du fichier. if(list == NULL) { errorMessage("Accounts file is corrupted"); return; } struct sockaddr_in server; initServerSocketAddress(&server); int listen_socket = createServerListenSocket(&server); ConnectionList connection_list; connection_list.nb_connections = 0; // initialisation de la fine d'attente des joueurs à charger sur la map et des joueurs déconnectés. PlayersQueue players_queues[2]; initPlayersQueue(&players_queues[0]); initPlayersQueue(&players_queues[1]); PlayersQueue *new_players_queue = players_queues; PlayersQueue *disconnected_players_queue = &players_queues[1]; // lancement du thread s'occupant de la gestion du déroulement du jeu. #ifdef RUN_GAME_MANAGEMENT_THREAD runGameManagementThread(players_queues); #endif int _continue, return_value; char *login, *password; Player *player; Connection * current_connection; int connection_index, account_index; GenericPacket packet; Buffer recv_buffer, send_buffer; initBuffer(&recv_buffer); initBuffer(&send_buffer); // utilise pour rendr le thread inactif pendant un certain temps. int no_activity = 0; struct timespec wait_time = {0, 150000}, sleep_return; long last_save_time = getTime(); char save_needed = FALSE; while(1) { no_activity = TRUE; acceptNewConnections(listen_socket, &connection_list); /// il reste a traiter les packets éventuels de chaque connexion. for(connection_index = 0; connection_index < connection_list.nb_connections; connection_index++) { current_connection = & connection_list.connections[connection_index]; _continue = TRUE; while(_continue) { return_value = recvPacket(current_connection, &packet, &recv_buffer); if(return_value == 1) // traitement du packet recu. { no_activity = FALSE; if(packet.type == AUTHENTIFICATION_REQUEST) { if(extractLoginAndPassword(&packet, &recv_buffer, &login, &password) < 0) // si la forme des donnees du paquet est incorrecte, on rejette la demande d'authentification. sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION); else if(!isCorrectLoginOrPassword(login)) // si le login est syntaxiquement incorrecte, on rejette la demande d'authentification. { debugMessage("Authentication has failed : login \"%s\" is syntactically false", login); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else if(!isCorrectLoginOrPassword(password)) // si le mot de passe est syntaxiquement incorrecte, on rejette la demande d'authentification. { debugMessage("Authentication has failed : password \"%s\" is syntactically false", password); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else if((account_index = getAccountPosition(list, login)) < 0) // Si le login ne correspond à aucun compte, on rejette la demande d'authentification. { debugMessage("Authentication has failed : none account matching with login \"%s\".", login); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else if(list->accounts[account_index].opened) // Si le compte correspondant au login est deja ouvert, on rejette la demande d'authentification. { debugMessage("Authentication has failed : account \"%s\" is already opened.", login); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else if(list->accounts[account_index].opened) // Si le compte correspondant est deja utilise, on rejette la demande d'authentification. { debugMessage("Authentication has failed : account \"%s\" is already opened.", password, login); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else if(strcmp(password, list->accounts[account_index].password)) // Si le compte correspondant au login a un mot de passe different de celui recu, on rejette la demande d'authentification. { debugMessage("Authentication has failed : password \"%s\" is incorrect for account \"%s\".", password, login); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else // l'authentification a reussi, on supprime donc la connection du service de comptes. { if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, ACCEPT_AUTHENTIFICATION)) == -2) warningMessage("Current connection is lost."); if(addPlayerToQueue(new_players_queue, (player = createPlayerForAccount(& list->accounts[account_index], current_connection))) < 0) // Si la file d'attente des noueaux joueurs en attente de chargement sur la map est pleine, on rejette la demande d'authentification. { destroyPlayer(player); debugMessage("Authentication has failed : new players queue is full."); if((return_value = sendAuthentificationAnswer(current_connection, &send_buffer, REJECT_AUTHENTIFICATION)) == -2) { warningMessage("Current connection is lost."); removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } else { removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; list->accounts[account_index].opened = TRUE; debugMessage("player %s is authenticated", login); } } } else // le type du paquet ne concerne pas le service de comptes, donc on l'ignore. warningMessage("packet received is not for account management : type is %d", packet.type); } else if(return_value == 0) // aucun nouveau paquet recu, donc on traite l'eventuelle connexion suivante. _continue = FALSE; else if(return_value == -1) _continue = FALSE; else // la connexion est perdue, donc on la supprime de la liste des connexions et on traite l'eventuelle connexion suivante. { no_activity = FALSE; removeConnectionFromList(& connection_list, connection_index); connection_index--; _continue = FALSE; } } } // on traite l'ensemble des joueurs deconnectes. while((player = removePlayerFromQueue(disconnected_players_queue)) != NULL) { no_activity = FALSE; account_index = getAccountPosition(list, player->login); // on recupere l'indice du compte associe au joueur 'player' if(account_index >= 0) // si le compte est retrouve, on le met a jour. { list->accounts[account_index].opened = FALSE; list->accounts[account_index].pos_x = player->position.x; list->accounts[account_index].pos_y = player->position.y; save_needed = TRUE; } destroyPlayer(player); } if(save_needed && getTime() - last_save_time > 30000000) // sauvegarde des comptes toutes les 30 secondes. { saveAccountsFile(ACCOUNTS_FILE, list); save_needed = FALSE; last_save_time = getTime(); } // si aucune activite (reception de paquet ou demande de connexion) n'a eu lieu, alors on rend le thread inactif pendant un certain temps afin de limiter la consommation des ressouces processeur. if(no_activity == TRUE) nanosleep(&wait_time, &sleep_return); } }
bool QOpenSLESAudioOutput::preparePlayer() { if (m_startRequiresInit) destroyPlayer(); else return true; SLEngineItf engine = QOpenSLESEngine::instance()->slEngine(); if (!engine) { qWarning() << "No engine"; setError(QAudio::FatalError); return false; } SLDataLocator_BufferQueue bufferQueueLocator = { SL_DATALOCATOR_BUFFERQUEUE, BUFFER_COUNT }; SLDataFormat_PCM pcmFormat = QOpenSLESEngine::audioFormatToSLFormatPCM(m_format); SLDataSource audioSrc = { &bufferQueueLocator, &pcmFormat }; // OutputMix if (SL_RESULT_SUCCESS != (*engine)->CreateOutputMix(engine, &m_outputMixObject, 0, Q_NULLPTR, Q_NULLPTR)) { qWarning() << "Unable to create output mix"; setError(QAudio::FatalError); return false; } if (SL_RESULT_SUCCESS != (*m_outputMixObject)->Realize(m_outputMixObject, SL_BOOLEAN_FALSE)) { qWarning() << "Unable to initialize output mix"; setError(QAudio::FatalError); return false; } SLDataLocator_OutputMix outputMixLocator = { SL_DATALOCATOR_OUTPUTMIX, m_outputMixObject }; SLDataSink audioSink = { &outputMixLocator, Q_NULLPTR }; #ifndef ANDROID const int iids = 2; const SLInterfaceID ids[iids] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME }; const SLboolean req[iids] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; #else const int iids = 3; const SLInterfaceID ids[iids] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME, SL_IID_ANDROIDCONFIGURATION }; const SLboolean req[iids] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; #endif // ANDROID // AudioPlayer if (SL_RESULT_SUCCESS != (*engine)->CreateAudioPlayer(engine, &m_playerObject, &audioSrc, &audioSink, iids, ids, req)) { qWarning() << "Unable to create AudioPlayer"; setError(QAudio::OpenError); return false; } #ifdef ANDROID // Set profile/category SLAndroidConfigurationItf playerConfig; if (SL_RESULT_SUCCESS == (*m_playerObject)->GetInterface(m_playerObject, SL_IID_ANDROIDCONFIGURATION, &playerConfig)) { (*playerConfig)->SetConfiguration(playerConfig, SL_ANDROID_KEY_STREAM_TYPE, &m_streamType, sizeof(SLint32)); } #endif // ANDROID if (SL_RESULT_SUCCESS != (*m_playerObject)->Realize(m_playerObject, SL_BOOLEAN_FALSE)) { qWarning() << "Unable to initialize AudioPlayer"; setError(QAudio::OpenError); return false; } // Buffer interface if (SL_RESULT_SUCCESS != (*m_playerObject)->GetInterface(m_playerObject, SL_IID_BUFFERQUEUE, &m_bufferQueueItf)) { setError(QAudio::FatalError); return false; } if (SL_RESULT_SUCCESS != (*m_bufferQueueItf)->RegisterCallback(m_bufferQueueItf, bufferQueueCallback, this)) { setError(QAudio::FatalError); return false; } // Play interface if (SL_RESULT_SUCCESS != (*m_playerObject)->GetInterface(m_playerObject, SL_IID_PLAY, &m_playItf)) { setError(QAudio::FatalError); return false; } if (SL_RESULT_SUCCESS != (*m_playItf)->RegisterCallback(m_playItf, playCallback, this)) { setError(QAudio::FatalError); return false; } if (m_notifyInterval && SL_RESULT_SUCCESS == (*m_playItf)->SetPositionUpdatePeriod(m_playItf, m_notifyInterval)) { m_eventMask |= SL_PLAYEVENT_HEADATNEWPOS; } if (SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, m_eventMask)) { setError(QAudio::FatalError); return false; } // Volume interface if (SL_RESULT_SUCCESS != (*m_playerObject)->GetInterface(m_playerObject, SL_IID_VOLUME, &m_volumeItf)) { setError(QAudio::FatalError); return false; } setVolume(m_volume); // Buffer size if (m_bufferSize <= 0) { m_bufferSize = m_format.bytesForDuration(DEFAULT_PERIOD_TIME_MS * 1000); } else { const int minimumBufSize = m_format.bytesForDuration(MINIMUM_PERIOD_TIME_MS * 1000); if (m_bufferSize < minimumBufSize) m_bufferSize = minimumBufSize; } m_periodSize = m_bufferSize; if (!m_buffers) m_buffers = new char[BUFFER_COUNT * m_bufferSize]; m_clockStamp.restart(); setError(QAudio::NoError); m_startRequiresInit = false; return true; }
void QOpenSLESAudioOutput::reset() { destroyPlayer(); }
/* Desc: Called upon to cleanup memory used up by the game. Args: Ret: Nothing. */ void clean(player * p, enemy1 * e) { destroyPlayer(p); destroyEnemies(e); }