void FramelessMainWindow::reconnectMediaPlayer() { VlcMediaPlayer *player = VLC::_player; if ( !player ) return; connect( m_closeButton, SIGNAL( clicked() ), player, SLOT( stop() ) ); connect( player, SIGNAL( opening() ), this, SLOT( playbackStarted() ) ); connect( player, SIGNAL( opening() ), m_control, SLOT( onPlaying() ) ); connect( player, SIGNAL( stopped() ), this, SLOT( playbackStopped() ) ); connect( player, SIGNAL( stopped() ), m_hostApp, SLOT( cancelTorrent() ) ); connect( player, SIGNAL( stopped() ), m_control, SLOT( resetPlayback() ) ); connect( player, SIGNAL( stopped() ), m_control, SLOT( resetPlayback() ) ); }
void VideoControls::setPlayback(bool playing) { if (m_isPlaying != playing) { m_isPlaying = playing; if (m_isPlaying) { m_playButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaPause)); } else { m_playButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaPlay)); } m_nextButton->setEnabled(!m_isPlaying); m_prevButton->setEnabled(!m_isPlaying); m_frameSlider->setEnabled(!m_isPlaying); m_frameEdit->setEnabled(!m_isPlaying); playbackChanged(m_isPlaying); if (m_isPlaying) { playbackStarted(); } else { playbackPaused(); } } }
void Player::PlayOrPause() { //From pause to play if(_state==PLAYSTATE_STOPPED) { if(playFrame()==loopOut) setPlaybackFrame(loopIn); _state = PLAYSTATE_PLAYING; ui->playButton->setIcon(pauseIcon); timer.start((int)(1.0/fps()*1000.0)); emit playbackStarted(); } else //pause the playback { timer.stop(); _state = PLAYSTATE_STOPPED; ui->playButton->setIcon(playIcon); emit playbackPaused(); } }
QSGNode* OMX_MediaProcessorElement::updatePaintNode(QSGNode*, UpdatePaintNodeData*) { if (!m_texProvider) { m_texProvider = new OMX_TextureProviderQQuickItem(this); m_mediaProc = new OMX_MediaProcessor(m_texProvider); connect(m_mediaProc, SIGNAL(playbackCompleted()), this, SIGNAL(playbackCompleted())); connect(m_mediaProc, SIGNAL(playbackStarted()), this, SIGNAL(playbackStarted())); // Open if filepath is set. // TODO: Handle errors. if (!m_source.isNull()) { //if (QFile(m_source).exists()) { if (openMedia(m_source)) m_mediaProc->play(); //} //else { LOG_WARNING(LOG_TAG, "File does not exist."); //} } } return NULL; #if 0 QSGGeometryNode* node = 0; QSGGeometry* geometry = 0; if (!oldNode) { // Create the node. node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); // TODO: Who is freeing this? // TODO: I cannot know the texture size here. QSGOpaqueTextureMaterial* material = new QSGOpaqueTextureMaterial; m_sgtexture = new OMX_SGTexture(m_texture, QSize(1920, 1080)); material->setTexture(m_sgtexture); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); #ifdef ENABLE_VIDEO_PROCESSOR QPlatformNativeInterface* nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface(); Q_ASSERT(nativeInterface); EGLDisplay eglDisplay = nativeInterface->nativeResourceForIntegration("egldisplay"); EGLContext eglContext = nativeInterface->nativeResourceForContext( "eglcontext", QOpenGLContext::currentContext() ); #endif // Provider MUST be built in this thread. m_provider = new OMX_TextureProviderQQuickItem(this); #ifdef ENABLE_VIDEO_PROCESSOR m_videoProc = new OMX_VideoProcessor(eglDisplay, eglContext, m_provider); connect(m_videoProc, SIGNAL(textureReady(uint)), this, SLOT(onTextureChanged(uint))); if (!m_source.isNull()) m_videoProc->setVideoPath(m_source); if (m_playScheduled) { m_timer->start(30); m_videoProc->play(); } #elif ENABLE_MEDIA_PROCESSOR LOG_VERBOSE(LOG_TAG, "Starting video using media processor..."); m_mediaProc = new OMX_MediaProcessor(m_provider); m_mediaProc->setFilename("/home/pi/usb/Cars2.mkv", m_texture); //if (m_playScheduled) { m_timer->start(40); m_mediaProc->play(); //} #else LOG_VERBOSE(LOG_TAG, "Starting video..."); QtConcurrent::run(&startVideo, m_provider, this); m_timer->start(30); #endif } else { node = static_cast<QSGGeometryNode*>(oldNode); geometry = node->geometry(); geometry->allocate(4); // Update texture in the node if needed. QSGOpaqueTextureMaterial* material = (QSGOpaqueTextureMaterial*)node->material(); if (m_texture != (GLuint)material->texture()->textureId()) { // TODO: Does setTextureId frees the prev texture? // TODO: I should the given the texture size. LOG_ERROR(LOG_TAG, "Updating texture to %u!", m_texture); material = new QSGOpaqueTextureMaterial; m_sgtexture->setTexture(m_texture, QSize(1920, 1080)); } } // Create the vertices and map to texture. QRectF bounds = boundingRect(); QSGGeometry::TexturedPoint2D* vertices = geometry->vertexDataAsTexturedPoint2D(); vertices[0].set(bounds.x(), bounds.y() + bounds.height(), 0.0f, 0.0f); vertices[1].set(bounds.x() + bounds.width(), bounds.y() + bounds.height(), 1.0f, 0.0f); vertices[2].set(bounds.x(), bounds.y(), 0.0f, 1.0f); vertices[3].set(bounds.x() + bounds.width(), bounds.y(), 1.0f, 1.0f); return node; #endif }
/*------------------------------------------------------------------------------ | OMX_MediaProcessor::mediaDecoding +-----------------------------------------------------------------------------*/ void OMX_MediaProcessor::mediaDecoding() { LOG_VERBOSE(LOG_TAG, "Decoding thread started."); emit playbackStarted(); struct timespec starttime, endtime; while (!m_pendingStop) { // If a request is pending then consider done here. m_mutexPending.lock(); if (m_pendingPause) { m_waitPendingCommand.wakeAll(); m_pendingPause = false; } m_mutexPending.unlock(); // TODO: Use a semaphore instead. if (m_state == STATE_PAUSED) { OMXClock::OMXSleep(2); continue; } #if 0 // TODO: Reimplement? if (m_incr != 0 && !m_bMpeg) { int seek_flags = 0; double seek_pos = 0; double pts = 0; pts = m_av_clock->GetPTS(); seek_pos = (pts / DVD_TIME_BASE) + m_incr; seek_flags = m_incr < 0.0f ? AVSEEK_FLAG_BACKWARD : 0; seek_pos *= 1000.0f; m_incr = 0; if(m_omx_reader.SeekTime(seek_pos, seek_flags, &startpts)) FlushStreams(startpts); m_player_video->Close(); if(m_has_video && !m_player_video->Open(m_hints_video, m_av_clock, m_Deinterlace, m_bMpeg, m_hdmi_clock_sync, m_thread_player, m_display_aspect)) goto do_exit; } #endif // TODO: Better error handling. if (m_player_audio->Error()) { LOG_ERROR(LOG_TAG, "Audio player error. emergency exit!"); break; } if (false) { LOG_INFORMATION(LOG_TAG, "V : %8.02f %8d %8d A : %8.02f %8.02f Cv : %8d Ca : %8d", m_av_clock->OMXMediaTime(), m_player_video->GetDecoderBufferSize(), m_player_video->GetDecoderFreeSpace(), m_player_audio->GetCurrentPTS() / DVD_TIME_BASE, m_player_audio->GetDelay(), m_player_video->GetCached(), m_player_audio->GetCached()); } if (m_omx_reader.IsEof() && !m_omx_pkt) { if (!m_player_audio->GetCached() && !m_player_video->GetCached()) break; // Abort audio buffering, now we're on our own. if (m_buffer_empty) m_av_clock->OMXResume(); OMXClock::OMXSleep(10); continue; } /* when the audio buffer runs under 0.1 seconds we buffer up */ if (m_has_audio) { if (m_player_audio->GetDelay() < 0.1f && !m_buffer_empty) { if (!m_av_clock->OMXIsPaused()) { m_av_clock->OMXPause(); LOG_VERBOSE(LOG_TAG, "Buffering starts."); m_buffer_empty = true; clock_gettime(CLOCK_REALTIME, &starttime); } } if (m_player_audio->GetDelay() > (AUDIO_BUFFER_SECONDS * 0.75f) && m_buffer_empty) { if (m_av_clock->OMXIsPaused()) { m_av_clock->OMXResume(); LOG_VERBOSE(LOG_TAG, "Buffering ends."); m_buffer_empty = false; } } if (m_buffer_empty) { clock_gettime(CLOCK_REALTIME, &endtime); if ((endtime.tv_sec - starttime.tv_sec) > BUFFERING_TIMEOUT_S) { m_buffer_empty = false; m_av_clock->OMXResume(); LOG_WARNING(LOG_TAG, "Buffering timed out."); } } } if (!m_omx_pkt) m_omx_pkt = m_omx_reader.Read(); if (m_has_video && m_omx_pkt && m_omx_reader.IsActive(OMXSTREAM_VIDEO, m_omx_pkt->stream_index)) { if (m_player_video->AddPacket(m_omx_pkt)) m_omx_pkt = NULL; else OMXClock::OMXSleep(10); #if 0 // TODO: Reimplement? if(m_tv_show_info) { char response[80]; vc_gencmd(response, sizeof response, "render_bar 4 video_fifo %d %d %d %d", m_player_video->GetDecoderBufferSize()-m_player_video->GetDecoderFreeSpace(), 0 , 0, m_player_video->GetDecoderBufferSize()); vc_gencmd(response, sizeof response, "render_bar 5 audio_fifo %d %d %d %d", (int)(100.0*m_player_audio->GetDelay()), 0, 0, 100*AUDIO_BUFFER_SECONDS); } #endif } else if (m_has_audio && m_omx_pkt && m_omx_pkt->codec_type == AVMEDIA_TYPE_AUDIO) { if (m_player_audio->AddPacket(m_omx_pkt)) m_omx_pkt = NULL; else OMXClock::OMXSleep(10); } #ifdef ENABLE_SUBTITLES else if (m_omx_pkt && m_omx_reader.IsActive(OMXSTREAM_SUBTITLE, m_omx_pkt->stream_index)) { if (m_omx_pkt->size && ENABLE_SUBTITLES && (m_omx_pkt->hints.codec == CODEC_ID_TEXT || m_omx_pkt->hints.codec == CODEC_ID_SSA)) { if(m_player_subtitles->AddPacket(m_omx_pkt)) m_omx_pkt = NULL; else OMXClock::OMXSleep(10); } else { m_omx_reader.FreePacket(m_omx_pkt); m_omx_pkt = NULL; } } #endif else { if (m_omx_pkt) { m_omx_reader.FreePacket(m_omx_pkt); m_omx_pkt = NULL; } } } emit playbackCompleted(); cleanup(); }
/*------------------------------------------------------------------------------ | OMX_MediaProcessor::mediaDecoding +-----------------------------------------------------------------------------*/ void OMX_MediaProcessor::mediaDecoding() { // See description in the qmakefile. //#define ENABLE_PROFILE_MAIN_LOOP //#define ENABLE_PAUSE_FOR_BUFFERING LOG_VERBOSE(LOG_TAG, "Decoding thread started."); emit playbackStarted(); // Prealloc. #ifdef ENABLE_PAUSE_FOR_BUFFERING float stamp = 0; float audio_pts = 0; float video_pts = 0; float audio_fifo = 0; float video_fifo = 0; float threshold = 0; bool audio_fifo_low = false, video_fifo_low = false, audio_fifo_high = false, video_fifo_high = false; float m_threshold = 1.0f; //std::min(0.1f, audio_fifo_size * 0.1f); #endif // ENABLE_PAUSE_FOR_BUFFERING bool sentStarted = false; double last_seek_pos = 0; bool sendEos = false; double m_last_check_time = 0.0; m_av_clock->OMXReset(m_has_video, m_has_audio); m_av_clock->OMXStateExecute(); sentStarted = true; while (!m_pendingStop) { #ifdef ENABLE_PROFILE_MAIN_LOOP static qint64 tot = 0; static qint64 totNum = 0; static QElapsedTimer timer; static int count = 0; if (tot == 0) { timer.start(); tot++; } else tot += timer.restart(); totNum++; if ((count++)%30 == 0) { //LOG_VERBOSE(LOG_TAG, "Elapsed: %lld", timer.restart()); LOG_VERBOSE(LOG_TAG, "Average: %f.", (double)tot/totNum); } #endif double now = m_av_clock->GetAbsoluteClock(); bool update = false; if (m_last_check_time == 0.0 || m_last_check_time + DVD_MSEC_TO_TIME(20) <= now) { update = true; m_last_check_time = now; } // If a request is pending then consider done here. m_mutexPending.lock(); if (m_pendingPause) { m_waitPendingCommand.wakeAll(); m_pendingPause = false; } m_mutexPending.unlock(); // TODO: Use a semaphore instead. if (m_state == STATE_PAUSED) { OMXClock::OMXSleep(2); continue; } if (m_seekFlush || m_incr != 0) { double seek_pos = 0; double pts = m_av_clock->OMXMediaTime(); //seek_pos = (pts / DVD_TIME_BASE) + m_incr; seek_pos = (pts ? pts / DVD_TIME_BASE : last_seek_pos) + m_incr; last_seek_pos = seek_pos; seek_pos *= 1000.0; if(m_omx_reader->SeekTime((int)seek_pos, m_incr < 0.0f, &startpts)) { unsigned t = (unsigned)(startpts*1e-6); auto dur = m_omx_reader->GetStreamLength() / 1000; log_info("Seek to: %02d:%02d:%02d\n", (t/3600), (t/60)%60, t%60); flushStreams(startpts); } m_player_video->Close(); sentStarted = false; if (m_omx_reader->IsEof()) break; if (m_has_video && !m_player_video->Open( *m_hints_video, m_av_clock, m_textureData, VS_DEINTERLACEMODE_OFF, /* deinterlace */ OMX_ImageFilterAnaglyphNone, ENABLE_HDMI_CLOCK_SYNC, true, /* threaded */ 1.0, /* display aspect, unused */ 0, /* display */ 0, /* layer */ m_video_queue_size, m_video_fifo_size )) { m_incr = 0; break; } m_incr = 0; #ifdef ENABLE_PAUSE_FOR_BUFFERING m_av_clock->OMXPause(); #endif #ifdef ENABLE_SUBTITLES if (m_has_subtitle) m_player_subtitles.Resume(); #endif unsigned t = (unsigned)(startpts*1e-6); LOG_VERBOSE(LOG_TAG, "Seeked to: %02d:%02d:%02d\n", (t/3600), (t/60)%60, t%60); m_packetAfterSeek = false; m_seekFlush = false; } else if (m_packetAfterSeek && TRICKPLAY(m_av_clock->OMXPlaySpeed())) { double seek_pos = 0; double pts = 0; pts = m_av_clock->OMXMediaTime(); seek_pos = (pts/DVD_TIME_BASE); seek_pos *= 1000.0; #if 1 if (m_omx_reader->SeekTime((int)seek_pos, m_av_clock->OMXPlaySpeed() < 0, &startpts)) { ; //FlushStreams(DVD_NOPTS_VALUE); } #endif // 0 CLog::Log(LOGDEBUG, "Seeked %.0f %.0f %.0f\n", DVD_MSEC_TO_TIME(seek_pos), startpts, m_av_clock->OMXMediaTime()); //unsigned t = (unsigned)(startpts*1e-6); unsigned t = (unsigned)(pts*1e-6); printf("Seek to: %02d:%02d:%02d\n", (t/3600), (t/60)%60, t%60); m_packetAfterSeek = false; } // TODO: Better error handling. if (m_player_audio->Error()) { LOG_ERROR(LOG_TAG, "Audio player error. emergency exit!"); break; } if (update) { #ifdef ENABLE_PAUSE_FOR_BUFFERING /* when the video/audio fifos are low, we pause clock, when high we resume */ stamp = m_av_clock->OMXMediaTime(); audio_pts = m_player_audio->GetCurrentPTS(); video_pts = m_player_video->GetCurrentPTS(); if (0 && m_av_clock->OMXIsPaused()) { double old_stamp = stamp; if (audio_pts != DVD_NOPTS_VALUE && (stamp == 0 || audio_pts < stamp)) stamp = audio_pts; if (video_pts != DVD_NOPTS_VALUE && (stamp == 0 || video_pts < stamp)) stamp = video_pts; if (old_stamp != stamp) { m_av_clock->OMXMediaTime(stamp); stamp = m_av_clock->OMXMediaTime(); } } audio_fifo = audio_pts == DVD_NOPTS_VALUE ? 0.0f : audio_pts / DVD_TIME_BASE - stamp * 1e-6; video_fifo = video_pts == DVD_NOPTS_VALUE ? 0.0f : video_pts / DVD_TIME_BASE - stamp * 1e-6; threshold = min(0.1f, (float)m_player_audio->GetCacheTotal()*0.1f); #endif // ENABLE_PAUSE_FOR_BUFFERING #if 0 static int count; if ((count++ & 15) == 0) { LOG_VERBOSE(LOG_TAG, "M: %8.02f V : %8.02f %8d %8d A : %8.02f %8.02f/%8.02f Cv : %8d Ca : %8d \r", stamp, audio_fifo, m_player_video->GetDecoderBufferSize(), m_player_video->GetDecoderFreeSpace(), video_fifo, m_player_audio->GetDelay(), m_player_audio->GetCacheTotal(), m_player_video->GetCached(), m_player_audio->GetCached()); } #endif #if 0 if(m_tv_show_info) { static unsigned count; if ((count++ & 15) == 0) { char response[80]; if (m_player_video.GetDecoderBufferSize() && m_player_audio.GetCacheTotal()) vc_gencmd(response, sizeof response, "render_bar 4 video_fifo %d %d %d %d", (int)(100.0*m_player_video.GetDecoderBufferSize()-m_player_video.GetDecoderFreeSpace())/m_player_video.GetDecoderBufferSize(), (int)(100.0*video_fifo/m_player_audio.GetCacheTotal()), 0, 100); if (m_player_audio.GetCacheTotal()) vc_gencmd(response, sizeof response, "render_bar 5 audio_fifo %d %d %d %d", (int)(100.0*audio_fifo/m_player_audio.GetCacheTotal()), (int)(100.0*m_player_audio.GetDelay()/m_player_audio.GetCacheTotal()), 0, 100); vc_gencmd(response, sizeof response, "render_bar 6 video_queue %d %d %d %d", m_player_video.GetLevel(), 0, 0, 100); vc_gencmd(response, sizeof response, "render_bar 7 audio_queue %d %d %d %d", m_player_audio.GetLevel(), 0, 0, 100); } } #endif #ifdef ENABLE_PAUSE_FOR_BUFFERING if (audio_pts != DVD_NOPTS_VALUE) { audio_fifo_low = m_has_audio && audio_fifo < threshold; audio_fifo_high = !m_has_audio || (audio_pts != DVD_NOPTS_VALUE && audio_fifo > m_threshold); } if (video_pts != DVD_NOPTS_VALUE) { video_fifo_low = m_has_video && video_fifo < threshold; video_fifo_high = !m_has_video || (video_pts != DVD_NOPTS_VALUE && video_fifo > m_threshold); } // Enable this to enable pause for buffering. if (m_state != STATE_PAUSED && (m_omx_reader->IsEof() || m_omx_pkt || TRICKPLAY(m_av_clock->OMXPlaySpeed()) || (audio_fifo_high && video_fifo_high))) { if (m_av_clock->OMXIsPaused()) { CLog::Log(LOGDEBUG, "Resume %.2f,%.2f (%d,%d,%d,%d) EOF:%d PKT:%p\n", audio_fifo, video_fifo, audio_fifo_low, video_fifo_low, audio_fifo_high, video_fifo_high, m_omx_reader->IsEof(), m_omx_pkt); log_verbose("Pausing for buffering..."); //m_av_clock->OMXStateExecute(); m_av_clock->OMXResume(); } } else if (m_state == STATE_PAUSED || audio_fifo_low || video_fifo_low) { if (!m_av_clock->OMXIsPaused()) { if (m_state != STATE_PAUSED) m_threshold = std::min(2.0f*m_threshold, 16.0f); CLog::Log(LOGDEBUG, "Pause %.2f,%.2f (%d,%d,%d,%d) %.2f\n", audio_fifo, video_fifo, audio_fifo_low, video_fifo_low, audio_fifo_high, video_fifo_high, m_threshold); log_verbose("Buffering completed. Resuming..."); m_av_clock->OMXPause(); } } #endif } if (!sentStarted) { CLog::Log(LOGDEBUG, "COMXPlayer::HandleMessages - player started RESET"); m_av_clock->OMXReset(m_has_video, m_has_audio); m_av_clock->OMXStateExecute(); sentStarted = true; } if (!m_omx_pkt) m_omx_pkt = m_omx_reader->Read(); if (m_omx_pkt) sendEos = false; if (m_omx_reader->IsEof() && !m_omx_pkt) { // demuxer EOF, but may have not played out data yet if ((m_has_video && m_player_video->GetCached()) || (m_has_audio && m_player_audio->GetCached())) { OMXClock::OMXSleep(10); continue; } if (m_loop) { m_incr = m_loop_from - (m_av_clock->OMXMediaTime() ? m_av_clock->OMXMediaTime() / DVD_TIME_BASE : last_seek_pos); continue; } if (!sendEos && m_has_video) m_player_video->SubmitEOS(); if (!sendEos && m_has_audio) m_player_audio->SubmitEOS(); sendEos = true; if ((m_has_video && !m_player_video->IsEOS()) || (m_has_audio && !m_player_audio->IsEOS()) ) { OMXClock::OMXSleep(10); continue; } break; } if (!m_omx_pkt) m_omx_pkt = m_omx_reader->Read(); if(m_omx_pkt) sendEos = false; if(m_omx_reader->IsEof() && !m_omx_pkt) { // demuxer EOF, but may have not played out data yet if ( (m_has_video && m_player_video->GetCached()) || (m_has_audio && m_player_audio->GetCached()) ) { OMXClock::OMXSleep(10); continue; } if (!sendEos && m_has_video) m_player_video->SubmitEOS(); if (!sendEos && m_has_audio) m_player_audio->SubmitEOS(); sendEos = true; if ( (m_has_video && !m_player_video->IsEOS()) || (m_has_audio && !m_player_audio->IsEOS()) ) { OMXClock::OMXSleep(10); continue; } break; } if(m_has_video && m_omx_pkt && m_omx_reader->IsActive(OMXSTREAM_VIDEO, m_omx_pkt->stream_index)) { if (TRICKPLAY(m_av_clock->OMXPlaySpeed())) { m_packetAfterSeek = true; } if(m_player_video->AddPacket(m_omx_pkt)) m_omx_pkt = NULL; else OMXClock::OMXSleep(10); } else if(m_has_audio && m_omx_pkt && !TRICKPLAY(m_av_clock->OMXPlaySpeed()) && m_omx_pkt->codec_type == AVMEDIA_TYPE_AUDIO) { if(m_player_audio->AddPacket(m_omx_pkt)) m_omx_pkt = NULL; else OMXClock::OMXSleep(10); } #ifdef ENABLE_SUBTITLES else if(m_has_subtitle && m_omx_pkt && !TRICKPLAY(m_av_clock->OMXPlaySpeed()) && m_omx_pkt->codec_type == AVMEDIA_TYPE_SUBTITLE) { auto result = m_player_subtitles.AddPacket(m_omx_pkt, m_omx_reader.GetRelativeIndex(m_omx_pkt->stream_index)); if (result) m_omx_pkt = NULL; else OMXClock::OMXSleep(10); } #endif else { if(m_omx_pkt) { m_omx_reader->FreePacket(m_omx_pkt); m_omx_pkt = NULL; } else OMXClock::OMXSleep(10); } } LOG_VERBOSE(LOG_TAG, "Stopping OMX clock..."); //m_av_clock->OMXResume(); m_av_clock->OMXStop(); m_av_clock->OMXStateIdle(); //m_av_clock->OMXStateExecute(); //m_av_clock->OMXReset(m_has_video, m_has_audio); // Restart video player. It seems it is necessary to close // and open again. omxplayer does this also when seeking so // maybe there is no other way to restart it. m_player_video->Close(); if (m_has_video) if (!m_player_video->Open( *m_hints_video, m_av_clock, m_textureData, VS_DEINTERLACEMODE_OFF, /* deinterlace */ OMX_ImageFilterAnaglyphNone, ENABLE_HDMI_CLOCK_SYNC, true, /* threaded */ 1.0, /* display aspect, unused */ 0, /* display, unused */ 0, /* layer */ m_video_queue_size, m_video_fifo_size )) { LOG_ERROR(LOG_TAG, "Failed to reopen media."); } // TODO: Handle failure. setState(STATE_STOPPED); emit playbackCompleted(); // Actually change the state here and reset flags. m_mutexPending.lock(); if (m_pendingStop) { m_pendingStop = false; m_waitPendingCommand.wakeAll(); } m_mutexPending.unlock(); }
CarPI::CarPI(QObject * parent): QObject(parent) { qDebug() << "CarPI: Starting"; _sourceCurrent = sourceUnknown; _sourcePaused = false; /* Kontroler płyty głównej urządzenia */ _mainboard = MainBoard::getInstance(); /* Emulator wyświetlacza radia */ _displayEmulator = DisplayEmulator::getInstance(); /* Emulator zmieniarki CD */ _changerEmulator = ChangerEmulator::getInstance(); /* Kontroler modułu bluetooth */ _bluetooth = Bluetooth::getInstance(); /* Odtwarzacz MP3 */ _mp3Player = MP3Player::getInstance(); /* Nawigacja */ _navit = Navit::getInstance(); /* Interfejs OBD II */ _elm327 = Elm327::getInstance(); _atmosphericPressure = 100; /* Zakładamy ciśnienie 1000hPa */ connect(_mainboard, SIGNAL(radioPowerChanged(bool)), _displayEmulator, SLOT(radioPowerChanged(bool))); connect(_mainboard, SIGNAL(keyStateChanged(int)), this, SLOT(_pilotKeyStateChanged(int))); connect(_mainboard, SIGNAL(ignitionChanged(bool)), this, SLOT(_ignitionStateChanged(bool))); connect(_mainboard, SIGNAL(shutdown()), this, SLOT(shutdown())); connect(_displayEmulator, SIGNAL(displayTextChanged(QString)), this, SLOT(_displayTextChanged(QString))); connect(_displayEmulator, SIGNAL(displayIconsChanged(int)), this, SLOT(_displayIconsChanged(int))); connect(_displayEmulator, SIGNAL(displayMenuShow(int)), this, SLOT(_displayMenuShow(int))); connect(_displayEmulator, SIGNAL(displayMenuHide()), this, SLOT(_displayMenuHide())); connect(_displayEmulator, SIGNAL(displayMenuItemUpdate(int,QString,bool)), this, SLOT(_displayMenuSetItem(int,QString,bool))); connect(this, SIGNAL(radioNewKeyEvent(int)), _displayEmulator, SLOT(sendKeyEvent(int))); connect(_bluetooth, SIGNAL(connectionStateChanged(bool)), this, SLOT(_bluetoothConnectionStateChanged(bool))); connect(_bluetooth, SIGNAL(callStateChanged(BluetoothCallState,QString)), this, SLOT(_bluetoothCallStateChanged(BluetoothCallState,QString))); connect(_changerEmulator, SIGNAL(playbackStarted()), _mp3Player, SLOT(play())); connect(_changerEmulator, SIGNAL(playbackPaused()), _mp3Player, SLOT(pause())); connect(_changerEmulator, SIGNAL(playbackStopped()), _mp3Player, SLOT(stop())); connect(_changerEmulator, SIGNAL(nextTrack()), _mp3Player, SLOT(nextTrack())); connect(_changerEmulator, SIGNAL(prevTrack()), _mp3Player, SLOT(prevTrack())); connect(_changerEmulator, SIGNAL(loadCD(int)), this, SLOT(_changerEmulatorLoadCD(int))); connect(_mp3Player, SIGNAL(textChanged(QString)), this, SLOT(_mp3PlayerTextChanged(QString))); connect(this, SIGNAL(mp3PlayerNextAlbum()), _mp3Player, SLOT(nextAlbum())); connect(this, SIGNAL(mp3PlayerPrevAlbum()), _mp3Player, SLOT(prevAlbum())); connect(this, SIGNAL(mp3PlayerSwitchDisplayMode()), _mp3Player, SLOT(switchDisplayMode())); connect(_elm327, SIGNAL(pidValueChanged(int,QVector<int>)), this, SLOT(_elm327PidChanged(int,QVector<int>))); connect(_elm327, SIGNAL(voltageChanged(double)), this, SLOT(_elm327VoltageChanged(double))); connect(this, SIGNAL(elm327addWatchPid(int)), _elm327, SLOT(addWatchPid(int))); connect(this, SIGNAL(elm327start()), _elm327, SLOT(start())); connect(this, SIGNAL(elm327stop()), _elm327, SLOT(stop())); _mainboard->readState(); emit elm327addWatchPid(0x05); /* Temperatura wody */ emit elm327addWatchPid(0x04); /* Obciążenie silnika */ emit elm327addWatchPid(0x0B); /* Ciśnienie absolutne w kolektorze dolotowym */ emit elm327addWatchPid(0x0F); /* Temperatura powietrza w dolocie */ emit elm327addWatchPid(0x23); /* Ciśnienie paliwa */ }