/*------------------------------------------------------------------------------ | OMX_MediaProcessor::stop +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::stop() { LOG_VERBOSE(LOG_TAG, "Stop"); QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; switch (m_state) { case STATE_INACTIVE: return false; case STATE_PAUSED: case STATE_PLAYING: case STATE_STOPPED: break; m_state = STATE_STOPPED; return true; default: return false; } m_pendingStop = true; m_state = STATE_STOPPED; // Wait for command completion. m_mutexPending.lock(); if (m_pendingStop) { LOG_VERBOSE(LOG_TAG, "Waiting for the stop command to finish."); m_waitPendingCommand.wait(&m_mutexPending); } m_mutexPending.unlock(); LOG_INFORMATION(LOG_TAG, "Stop command issued."); return true; }
/*------------------------------------------------------------------------------ | OMX_MediaProcessor::pause +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::pause() { LOG_VERBOSE(LOG_TAG, "Pause"); QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; switch (m_state) { case STATE_INACTIVE: case STATE_STOPPED: return false; case STATE_PAUSED: case STATE_PLAYING: break; default: return false; } m_state = STATE_PAUSED; setSpeed(OMX_PLAYSPEED_PAUSE); m_av_clock->OMXPause(); // Wait for command completion. m_mutexPending.lock(); if (m_pendingPause) { LOG_VERBOSE(LOG_TAG, "Waiting for the pause command to finish."); m_waitPendingCommand.wait(&m_mutexPending); } m_mutexPending.unlock(); LOG_INFORMATION(LOG_TAG, "Pause command issued."); return true; }
/*------------------------------------------------------------------------------ | OMX_MediaProcessor::play +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::play() { // I need to invoke this in another thread (this object is owned by another // thread). LOG_VERBOSE(LOG_TAG, "Play"); QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; switch (m_state) { case STATE_INACTIVE: return false; case STATE_PAUSED: m_state = STATE_PLAYING; setSpeed(OMX_PLAYSPEED_NORMAL); m_av_clock->OMXResume(); return true; case STATE_PLAYING: return true; case STATE_STOPPED: { LOG_VERBOSE(LOG_TAG, "Starting thread."); m_state = STATE_PLAYING; m_av_clock->OMXStart(); return QMetaObject::invokeMethod(this, "mediaDecoding"); } default: return false; } }
/*------------------------------------------------------------------------------ | OMX_MediaProcessor::play +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::play() { // I need to invoke this in another thread (this object is owned by another // thread). LOG_VERBOSE(LOG_TAG, "Play"); QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; switch (m_state) { case STATE_INACTIVE: return true; case STATE_PAUSED: break; case STATE_PLAYING: return true; case STATE_STOPPED: { setState(STATE_PLAYING); #if 1 if (!m_omx_reader->SeekTime(0, true, &startpts)) { LOG_WARNING(LOG_TAG, "Failed to seek to the beginning."); return false; } flushStreams(startpts); #endif //m_av_clock->OMXStart(0.0); m_av_clock->OMXPause(); m_av_clock->OMXStateExecute(); m_av_clock->OMXResume(); //m_av_clock->OMXMediaTime(0.0D); LOG_VERBOSE(LOG_TAG, "Starting thread."); return QMetaObject::invokeMethod(this, "mediaDecoding"); } default: return false; } setState(STATE_PLAYING); if (m_av_clock->OMXPlaySpeed() != DVD_PLAYSPEED_NORMAL && m_av_clock->OMXPlaySpeed() != DVD_PLAYSPEED_PAUSE) { LOG_VERBOSE(LOG_TAG, "resume\n"); m_playspeedCurrent = playspeed_normal; setSpeed(playspeeds[m_playspeedCurrent]); m_seekFlush = true; } setSpeed(playspeeds[m_playspeedCurrent]); m_av_clock->OMXResume(); #ifdef ENABLE_SUBTITLES if (m_has_subtitle) m_player_subtitles.Resume(); #endif LOG_INFORMATION(LOG_TAG, "Play command issued."); return true; }
/** * @brief OMX_MediaProcessor::setFilename Sets the filename and returns the texture * data that will be used. * @param filename * @param textureData * @return */ bool OMX_MediaProcessor::setFilename(QString filename, OMX_TextureData*& textureData) { QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; return setFilenameInt(filename, textureData); }
/*------------------------------------------------------------------------------ | OMX_MediaProcessor::pause +-----------------------------------------------------------------------------*/ bool OMX_MediaProcessor::pause() { LOG_VERBOSE(LOG_TAG, "Pause"); QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; switch (m_state) { case STATE_INACTIVE: case STATE_STOPPED: return true; case STATE_PAUSED: return true; case STATE_PLAYING: break; default: return false; } #ifdef ENABLE_SUBTITLES if (m_has_subtitle) m_player_subtitles.Pause(); #endif setState(STATE_PAUSED); setSpeed(playspeeds[m_playspeedCurrent]); m_av_clock->OMXPause(); // Wait for command completion. m_mutexPending.lock(); if (m_pendingPause) { LOG_VERBOSE(LOG_TAG, "Waiting for the pause command to finish."); m_waitPendingCommand.wait(&m_mutexPending); } m_mutexPending.unlock(); LOG_INFORMATION(LOG_TAG, "Pause command issued."); return true; }
/** * @brief OMX_MediaProcessor::setFilename Sets the filename and returns the texture * data that will be used. * @param filename * @param textureData * @return */ bool OMX_MediaProcessor::setFilename(QString filename, OMX_TextureData*& textureData) { QMutexLocker locker(&m_sendCmd); if (!checkCurrentThread()) return false; switch (m_state) { case STATE_INACTIVE: case STATE_STOPPED: break; case STATE_PAUSED: case STATE_PLAYING: return false; // TODO: Reimplement. } LOG_VERBOSE(LOG_TAG, "Opening video file..."); if (!m_omx_reader.Open(filename.toStdString(), true)) return false; m_filename = filename; m_bMpeg = m_omx_reader.IsMpegVideo(); m_has_video = m_omx_reader.VideoStreamCount(); m_has_audio = m_omx_reader.AudioStreamCount(); #ifdef ENABLE_SUBTITLES m_has_subtitle = m_omx_reader.SubtitleStreamCount(); #endif LOG_VERBOSE(LOG_TAG, "Initializing OMX clock..."); if (!m_av_clock->OMXInitialize(m_has_video, m_has_audio)) return false; if (ENABLE_HDMI_CLOCK_SYNC && !m_av_clock->HDMIClockSync()) return false; m_omx_reader.GetHints(OMXSTREAM_AUDIO, m_hints_audio); m_omx_reader.GetHints(OMXSTREAM_VIDEO, m_hints_video); // Set audio stream to use. // TODO: Implement a way to change it runtime. #if 0 m_omx_reader.SetActiveStream(OMXSTREAM_AUDIO, m_audio_index_use); #endif // Seek on start? #if 0 if (m_seek_pos !=0 && m_omx_reader.CanSeek()) { printf("Seeking start of video to %i seconds\n", m_seek_pos); m_omx_reader.SeekTime(m_seek_pos * 1000.0f, 0, &startpts); // from seconds to DVD_TIME_BASE } #endif LOG_VERBOSE(LOG_TAG, "Opening video using OMX..."); if (m_has_video) if (!m_player_video->Open( m_hints_video, m_av_clock, textureData, false, /* deinterlace */ m_bMpeg, ENABLE_HDMI_CLOCK_SYNC, true, /* threaded */ 1.0 /* display aspect, unused */ )) return false; m_textureData = textureData; emit textureReady(textureData); #ifdef ENABLE_SUBTITLES LOG_VERBOSE(LOG_TAG, "Opening subtitles using OMX..."); if (m_has_subtitle) if (!m_player_subtitles->Open(FONT_PATH, FONT_SIZE, CENTERED, m_av_clock)) return false; // This is an upper bound check on the subtitle limits. When we pulled the subtitle // index from the user we check to make sure that the value is larger than zero, but // we couldn't know without scanning the file if it was too high. If this is the case // then we replace the subtitle index with the maximum value possible. if (m_has_subtitle && m_subtitle_index > (m_omx_reader.SubtitleStreamCount() - 1)) m_subtitle_index = m_omx_reader.SubtitleStreamCount() - 1; #endif m_omx_reader.GetHints(OMXSTREAM_AUDIO, m_hints_audio); LOG_VERBOSE(LOG_TAG, "Opening audio using OMX..."); if (m_has_audio) if (!m_player_audio->Open( m_hints_audio, m_av_clock, &m_omx_reader, "omx:hdmi", /* TODO: implement way to change */ false, /* TODO: passthrough */ false, /* TODO: hw decode */ false, /* TODO: downmix boost */ true /* threaded */ )) return false; LOG_VERBOSE(LOG_TAG, "Executing clock..."); m_av_clock->SetSpeed(DVD_PLAYSPEED_NORMAL); /* TODO: Implement speed */ m_av_clock->OMXStateExecute(); m_state = STATE_STOPPED; return true; }