MediaPlayer.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // MediaPlayer.cpp
  2. #include "MediaPlayer.h"
  3. #include "Unused.h"
  4. #include <string>
  5. #include <QTime>
  6. #include <fstream>
  7. #include <iostream>
  8. #define FOV_IMAGE_HEIGHT 600
  9. using namespace std;
  10. // PRIVATE SLOTS:
  11. void MediaPlayer::HandleTimerTick()
  12. {
  13. if (m_state==StoppedState || m_state==PausedState)
  14. return;
  15. // if the timer is fire due to main thread blocking, skip the frames of the delay
  16. if (m_startPlayMs < 0) // player starts after pause
  17. {
  18. m_startPlayMs =m_time.elapsed();
  19. m_startPlayFrame = m_curFrame+1;
  20. LoadFrame(++m_startPlayFrame);
  21. }
  22. else // it means the player was already playing
  23. {
  24. int curTime =m_time.elapsed();
  25. int framesElapsed = (int)(((curTime-m_startPlayMs)*m_videoParams.GetFrameRate())/1000.0 + 0.5); // round to pcloser frame
  26. framesElapsed = framesElapsed<1? 1: framesElapsed;
  27. LoadFrame(m_startPlayFrame+framesElapsed);
  28. }
  29. qint64 newTime = (qint64)(1000.0*m_curFrame/m_videoParams.GetFrameRate());
  30. // notify that frame has changed
  31. emit positionChanged(newTime);
  32. }
  33. // PUBLIC:
  34. MediaPlayer::MediaPlayer(QObject *parent) : QObject(parent), m_startPlayFrame(0), m_startPlayMs(-1), m_state(StoppedState), m_curFrame(0), m_bVideoAv(false), m_pEqToFov(NULL)
  35. {
  36. m_pFpsTimer = new QTimer(this); // timer hasn't started yet
  37. connect(m_pFpsTimer, SIGNAL(timeout()), this, SLOT(HandleTimerTick()));
  38. m_time.start();
  39. }
  40. MediaPlayer::~MediaPlayer()
  41. {
  42. delete m_pFpsTimer;
  43. }
  44. void MediaPlayer::setPosition(qint64 position)
  45. {
  46. int frameNum = (int)((double)position*m_videoParams.GetFrameRate()/1000.0);
  47. LoadFrame(frameNum);
  48. }
  49. bool MediaPlayer::setMedia(QUrl videoFile)
  50. {
  51. string sVideoFile = videoFile.toString().toStdString();
  52. if (!VideoExtractor::IsVideoExtracted(sVideoFile.c_str()))
  53. {
  54. if (!VideoExtractor::ExtractFrames(sVideoFile))
  55. {
  56. cerr << "Could not open video file: " << sVideoFile << endl;
  57. return false;
  58. }
  59. }
  60. string paramsFile = VideoExtractor::GetParamsname();
  61. bool res = VideoExtractor::LoadVideoParams(paramsFile, m_videoParams);
  62. UNUSED(res);
  63. // after knowing video is extracted, load first frame
  64. LoadFrame(0);
  65. m_bVideoAv = true;
  66. // and start timer with correct tick interval
  67. int interval = (int)(1000.0/m_videoParams.GetFrameRate());
  68. m_pFpsTimer->start(interval);
  69. return true;
  70. }
  71. void MediaPlayer::play()
  72. {
  73. m_state = PlayingState;
  74. }
  75. void MediaPlayer::pause()
  76. {
  77. m_state = PausedState;
  78. m_startPlayMs = -1;
  79. }
  80. MediaPlayer::State MediaPlayer::state() const
  81. {
  82. return m_state;
  83. }
  84. qint64 MediaPlayer::duration()
  85. {
  86. qint64 duration = (qint64)(m_videoParams.numOfFrames*1000.0/m_videoParams.GetFrameRate());
  87. return duration;
  88. }
  89. bool MediaPlayer::isVideoAvailable() const
  90. {
  91. return m_bVideoAv;
  92. }
  93. void MediaPlayer::Paint(QPainter *painter, QSize size)
  94. {
  95. QRect sourceRect = QRect(QPoint(0,0), m_image.size());
  96. double videoAspectRatio = (double)m_image.width()/(double)m_image.height();
  97. double areaAspectRatio = (double)size.width()/(double)size.height();
  98. int width, height, xDisp, yDisp;
  99. if (videoAspectRatio > areaAspectRatio){
  100. width = size.width();
  101. xDisp = 0;
  102. height = width/videoAspectRatio;
  103. yDisp = (size.height()-height)/2;
  104. }
  105. else{
  106. height = size.height();
  107. yDisp = 0;
  108. width = height*videoAspectRatio;
  109. xDisp = (size.width()-width)/2;
  110. }
  111. QRect targetRect = QRect(xDisp, yDisp, width, height);
  112. painter->drawImage(targetRect, m_image, sourceRect);
  113. }
  114. void MediaPlayer::SetConverter(EquirectangularToFovVideo *pEqToFov)
  115. {
  116. m_pEqToFov = pEqToFov;
  117. LoadFrame(m_curFrame);
  118. }
  119. // PRIVATE:
  120. void MediaPlayer::LoadFrame(int frameNum)
  121. {
  122. // check if frame number is within the video
  123. frameNum = frameNum<0? 0: frameNum;
  124. frameNum = frameNum>=m_videoParams.numOfFrames? m_videoParams.numOfFrames-1: frameNum;
  125. long int frameTime = (long int)(1000000.0*frameNum/m_videoParams.GetFrameRate());
  126. string framePath = VideoExtractor::GetFramename(frameNum);
  127. if (m_pEqToFov)
  128. {
  129. bool res = m_tmpImage.load(framePath.c_str());
  130. UNUSED(res);
  131. if (m_image.height() != FOV_IMAGE_HEIGHT)
  132. {
  133. int height = FOV_IMAGE_HEIGHT;
  134. double aspectRatio = m_pEqToFov->GetAspectRatio();
  135. int width = height * aspectRatio;
  136. m_image = QImage(width, height, m_tmpImage.format());
  137. }
  138. m_pEqToFov->Convert(&m_tmpImage, frameTime, &m_image);
  139. }
  140. else
  141. {
  142. bool res = m_image.load(framePath.c_str());
  143. UNUSED(res);
  144. }
  145. m_curFrame = frameNum;
  146. }