|
MythTV
0.26-pre
|
00001 #include "bdringbuffer.h" 00002 #include "avformatdecoderbd.h" 00003 #include "mythbdplayer.h" 00004 00005 #define LOC QString("BDPlayer: ") 00006 00007 MythBDPlayer::MythBDPlayer(PlayerFlags flags) 00008 : MythPlayer(flags), m_stillFrameShowing(false) 00009 { 00010 } 00011 00012 void MythBDPlayer::PreProcessNormalFrame(void) 00013 { 00014 DisplayMenu(); 00015 } 00016 00017 bool MythBDPlayer::GoToMenu(QString str) 00018 { 00019 if (player_ctx->buffer->BD() && videoOutput) 00020 { 00021 int64_t pts = 0; 00022 VideoFrame *frame = videoOutput->GetLastShownFrame(); 00023 if (frame) 00024 pts = (int64_t)(frame->timecode * 90); 00025 return player_ctx->buffer->BD()->GoToMenu(str, pts); 00026 } 00027 return false; 00028 } 00029 00030 void MythBDPlayer::DisplayMenu(void) 00031 { 00032 if (!player_ctx->buffer->IsBD()) 00033 return; 00034 00035 osdLock.lock(); 00036 BDOverlay *overlay = NULL; 00037 while (osd && (NULL != (overlay = player_ctx->buffer->BD()->GetOverlay()))) 00038 osd->DisplayBDOverlay(overlay); 00039 osdLock.unlock(); 00040 } 00041 00042 void MythBDPlayer::DisplayPauseFrame(void) 00043 { 00044 if (player_ctx->buffer->IsBD() && 00045 player_ctx->buffer->BD()->IsInStillFrame()) 00046 { 00047 SetScanType(kScan_Progressive); 00048 } 00049 DisplayMenu(); 00050 MythPlayer::DisplayPauseFrame(); 00051 } 00052 00053 bool MythBDPlayer::VideoLoop(void) 00054 { 00055 if (!player_ctx->buffer->IsBD()) 00056 { 00057 SetErrored("RingBuffer is not a Blu-Ray disc."); 00058 return !IsErrored(); 00059 } 00060 00061 int nbframes = videoOutput ? videoOutput->ValidVideoFrames() : 0; 00062 00063 // completely drain the video buffers for certain situations 00064 bool drain = player_ctx->buffer->BD()->BDWaitingForPlayer() && 00065 (nbframes > 0); 00066 00067 if (drain) 00068 { 00069 if (nbframes < 2 && videoOutput) 00070 videoOutput->UpdatePauseFrame(disp_timecode); 00071 00072 // if we go below the pre-buffering limit, the player will pause 00073 // so do this 'manually' 00074 DisplayNormalFrame(false); 00075 return !IsErrored(); 00076 } 00077 00078 // clear the mythtv imposed wait state 00079 if (player_ctx->buffer->BD()->BDWaitingForPlayer()) 00080 { 00081 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Clearing Mythtv BD wait state"); 00082 player_ctx->buffer->BD()->SkipBDWaitingForPlayer(); 00083 return !IsErrored(); 00084 } 00085 00086 if (player_ctx->buffer->BD()->IsInStillFrame()) 00087 { 00088 if (nbframes > 1 && !m_stillFrameShowing) 00089 { 00090 videoOutput->UpdatePauseFrame(disp_timecode); 00091 DisplayNormalFrame(false); 00092 return !IsErrored(); 00093 } 00094 00095 if (!m_stillFrameShowing) 00096 needNewPauseFrame = true; 00097 00098 // we are in a still frame so pause video output 00099 if (!videoPaused) 00100 { 00101 PauseVideo(); 00102 return !IsErrored(); 00103 } 00104 00105 // flag if we have no frame 00106 if (nbframes == 0) 00107 { 00108 LOG(VB_PLAYBACK, LOG_WARNING, LOC + 00109 "Warning: In BD Still but no video frames in queue"); 00110 usleep(10000); 00111 return !IsErrored(); 00112 } 00113 00114 if (!m_stillFrameShowing) 00115 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Entering still frame."); 00116 m_stillFrameShowing = true; 00117 } 00118 else 00119 { 00120 if (videoPaused && m_stillFrameShowing) 00121 { 00122 UnpauseVideo(); 00123 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Exiting still frame."); 00124 } 00125 m_stillFrameShowing = false; 00126 } 00127 00128 return MythPlayer::VideoLoop(); 00129 } 00130 00131 void MythBDPlayer::EventStart(void) 00132 { 00133 player_ctx->LockPlayingInfo(__FILE__, __LINE__); 00134 if (player_ctx->playingInfo) 00135 { 00136 QString name; 00137 QString serialid; 00138 if (player_ctx->playingInfo->GetTitle().isEmpty() && 00139 player_ctx->buffer->BD()->GetNameAndSerialNum(name, serialid)) 00140 { 00141 player_ctx->playingInfo->SetTitle(name); 00142 } 00143 } 00144 player_ctx->UnlockPlayingInfo(__FILE__, __LINE__); 00145 00146 MythPlayer::EventStart(); 00147 } 00148 00149 int MythBDPlayer::GetNumChapters(void) 00150 { 00151 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 00152 return player_ctx->buffer->BD()->GetNumChapters(); 00153 return -1; 00154 } 00155 00156 int MythBDPlayer::GetCurrentChapter(void) 00157 { 00158 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 00159 return player_ctx->buffer->BD()->GetCurrentChapter() + 1; 00160 return -1; 00161 } 00162 00163 int64_t MythBDPlayer::GetChapter(int chapter) 00164 { 00165 uint total = GetNumChapters(); 00166 if (!total) 00167 return -1; 00168 00169 return (int64_t)player_ctx->buffer->BD()->GetChapterStartFrame(chapter-1); 00170 } 00171 00172 void MythBDPlayer::GetChapterTimes(QList<long long> ×) 00173 { 00174 uint total = GetNumChapters(); 00175 if (!total) 00176 return; 00177 00178 for (uint i = 0; i < total; i++) 00179 times.push_back(player_ctx->buffer->BD()->GetChapterStartTime(i)); 00180 } 00181 00182 int MythBDPlayer::GetNumTitles(void) const 00183 { 00184 if (player_ctx->buffer->BD()->IsHDMVNavigation()) 00185 return 0; 00186 00187 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 00188 return player_ctx->buffer->BD()->GetNumTitles(); 00189 return 0; 00190 } 00191 00192 int MythBDPlayer::GetNumAngles(void) const 00193 { 00194 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 00195 return player_ctx->buffer->BD()->GetNumAngles(); 00196 return 0; 00197 } 00198 00199 int MythBDPlayer::GetCurrentTitle(void) const 00200 { 00201 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 00202 return player_ctx->buffer->BD()->GetCurrentTitle(); 00203 return -1; 00204 } 00205 00206 int MythBDPlayer::GetCurrentAngle(void) const 00207 { 00208 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 00209 return player_ctx->buffer->BD()->GetCurrentAngle(); 00210 return -1; 00211 } 00212 00213 int MythBDPlayer::GetTitleDuration(int title) const 00214 { 00215 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen() && 00216 title >= 0 && title < GetNumTitles()) 00217 { 00218 return player_ctx->buffer->BD()->GetTitleDuration(title); 00219 } 00220 return 0; 00221 } 00222 00223 QString MythBDPlayer::GetTitleName(int title) const 00224 { 00225 if (title >= 0 && title < GetNumTitles()) 00226 { 00227 int secs = GetTitleDuration(title); 00228 // BD doesn't provide title names, so show title number and duration 00229 int hours = secs / 60 / 60; 00230 int minutes = (secs / 60) - (hours * 60); 00231 secs = secs % 60; 00232 QString name = QString("%1 (%2:%3:%4)").arg(title+1) 00233 .arg(hours, 2, 10, QChar(48)).arg(minutes, 2, 10, QChar(48)) 00234 .arg(secs, 2, 10, QChar(48)); 00235 return name; 00236 } 00237 return QString(); 00238 } 00239 00240 QString MythBDPlayer::GetAngleName(int angle) const 00241 { 00242 if (angle >= 0 && angle < GetNumAngles()) 00243 { 00244 QString name = QObject::tr("Angle %1").arg(angle+1); 00245 return name; 00246 } 00247 return QString(); 00248 } 00249 00250 bool MythBDPlayer::SwitchTitle(int title) 00251 { 00252 if (player_ctx->buffer->BD()->IsHDMVNavigation()) 00253 return false; 00254 00255 uint total = GetNumTitles(); 00256 if (!total || title == GetCurrentTitle() || title >= (int)total) 00257 return false; 00258 00259 Pause(); 00260 00261 bool ok = false; 00262 if (player_ctx->buffer->BD()->SwitchTitle(title)) 00263 { 00264 ResetCaptions(); 00265 if (OpenFile() != 0) 00266 { 00267 SetErrored(QObject::tr("Failed to switch title.")); 00268 } 00269 else 00270 { 00271 ok = true; 00272 forcePositionMapSync = true; 00273 } 00274 } 00275 00276 Play(); 00277 return ok; 00278 } 00279 00280 bool MythBDPlayer::NextTitle(void) 00281 { 00282 if (player_ctx->buffer->BD()->IsHDMVNavigation()) 00283 return false; 00284 00285 uint total = GetNumTitles(); 00286 int next = GetCurrentTitle() + 1; 00287 if (!total || next >= (int)total) 00288 return false; 00289 00290 return SwitchTitle(next); 00291 } 00292 00293 bool MythBDPlayer::PrevTitle(void) 00294 { 00295 if (player_ctx->buffer->BD()->IsHDMVNavigation()) 00296 return false; 00297 00298 uint total = GetNumTitles(); 00299 int prev = GetCurrentTitle() - 1; 00300 if (!total || prev < 0) 00301 return false; 00302 00303 return SwitchTitle(prev); 00304 } 00305 00306 bool MythBDPlayer::SwitchAngle(int angle) 00307 { 00308 uint total = GetNumAngles(); 00309 if (!total || angle == GetCurrentAngle()) 00310 return false; 00311 00312 if (angle >= (int)total) 00313 angle = 0; 00314 00315 return player_ctx->buffer->BD()->SwitchAngle(angle); 00316 } 00317 00318 bool MythBDPlayer::NextAngle(void) 00319 { 00320 uint total = GetNumAngles(); 00321 int next = GetCurrentAngle() + 1; 00322 if (!total) 00323 return false; 00324 00325 if (next >= (int)total) 00326 next = 0; 00327 00328 return SwitchAngle(next); 00329 } 00330 00331 bool MythBDPlayer::PrevAngle(void) 00332 { 00333 uint total = GetNumAngles(); 00334 int prev = GetCurrentAngle() - 1; 00335 if (!total || total == 1) 00336 return false; 00337 00338 if (prev < 0) 00339 prev = total; 00340 00341 return SwitchAngle(prev); 00342 } 00343 00344 void MythBDPlayer::CreateDecoder(char *testbuf, int testreadsize) 00345 { 00346 if (AvFormatDecoderBD::CanHandle(testbuf, player_ctx->buffer->GetFilename(), 00347 testreadsize)) 00348 { 00349 SetDecoder(new AvFormatDecoderBD(this, *player_ctx->playingInfo, 00350 playerFlags)); 00351 } 00352 }
1.7.6.1