Ticket #511: dvd_seeking3.patch
File dvd_seeking3.patch, 15.3 KB (added by , 18 years ago) |
---|
-
NuppelVideoPlayer.cpp
4762 4767 } 4763 4768 } 4764 4769 4770 void NuppelVideoPlayer::ChangeDVDTrack(bool ffw) 4771 { 4772 if ( !ringBuffer->isDVD()) 4773 return; 4774 4775 GetDecoder()->ChangeDVDTrack(ffw); 4776 usleep(100000); 4777 ClearAfterSeek(); 4778 } 4779 -
NuppelVideoPlayer.h
249 249 void CheckTVChain(); 250 250 void FileChangedCallback(); 251 251 252 // DVD public stuff 253 void ChangeDVDTrack(bool ffw); 254 252 255 protected: 253 256 void DisplayPauseFrame(void); 254 257 void DisplayNormalFrame(void); -
decoderbase.cpp
88 88 // Overwrites current positionmap with entire contents of database 89 89 QMap<long long, long long> posMap; 90 90 91 92 if ((positionMapType == MARK_UNSET) || 91 if (ringBuffer->isDVD()) 92 { 93 keyframedist = 15; 94 if (fps < 26 && fps > 24) 95 keyframedist = 12; 96 long long totframes =(long long) (ringBuffer->GetTotalTimeOfTitle() * fps); 97 posMap[totframes] = ringBuffer->GetTotalReadPosition(); 98 } 99 else if ((positionMapType == MARK_UNSET) || 93 100 (keyframedist == -1)) 94 101 { 95 102 m_playbackinfo->GetPositionMap(posMap, MARK_GOP_BYFRAME); … … 296 303 bool ret_val = m_positionMap.size() > old_posmap_size; 297 304 if (ret_val && keyframedist > 0) 298 305 { 299 long long totframes = 300 m_positionMap[m_positionMap.size()-1].index * keyframedist; 301 int length = (int)((totframes * 1.0) / fps); 306 long long totframes; 307 int length; 308 if (ringBuffer->isDVD()) 309 { 310 totframes = m_positionMap[m_positionMap.size()-1].index; 311 length = ringBuffer->GetTotalTimeOfTitle(); 312 } 313 else 314 { 315 totframes = 316 m_positionMap[m_positionMap.size()-1].index * keyframedist; 317 length = (int)((totframes * 1.0) / fps); 318 } 302 319 GetNVP()->SetFileLength(length, totframes); 303 320 GetNVP()->SetKeyframeDistance(keyframedist); 304 321 posmapStarted = true; … … 392 409 if (m_positionMap.empty()) 393 410 return false; 394 411 395 // Find keyframe <= desiredFrame, store in lastKey (frames) 396 int pos_idx1, pos_idx2; 412 if (ringBuffer->isDVD()) 413 { 414 long long pos = DVDFindPosition(desiredFrame); 415 ringBuffer->Seek(pos,SEEK_SET); 416 lastKey = desiredFrame+1; 417 } 418 else 419 { 420 // Find keyframe <= desiredFrame, store in lastKey (frames) 421 int pos_idx1, pos_idx2; 397 422 398 FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2);423 FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2); 399 424 400 int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2;425 int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2; 401 426 402 if (hasKeyFrameAdjustTable)403 lastKey = m_positionMap[pos_idx].adjFrame;404 else405 lastKey = m_positionMap[pos_idx].index * keyframedist;406 407 long long keyPos = m_positionMap[pos_idx].pos;408 long long curPosition = ringBuffer->GetReadPosition();409 long long diff = keyPos - curPosition;410 411 // Don't rewind further than we have space to store video412 while (keyPos <= 0)413 {414 pos_idx++;415 if (pos_idx >= (int)m_positionMap.size())416 {417 diff = 0;418 return false;419 }420 427 if (hasKeyFrameAdjustTable) 421 428 lastKey = m_positionMap[pos_idx].adjFrame; 422 429 else 423 430 lastKey = m_positionMap[pos_idx].index * keyframedist; 424 keyPos = m_positionMap[pos_idx].pos;425 431 426 diff = keyPos - curPosition; 432 long long keyPos = m_positionMap[pos_idx].pos; 433 long long curPosition = ringBuffer->GetReadPosition(); 434 long long diff = keyPos - curPosition; 435 436 // Don't rewind further than we have space to store video 437 while (keyPos <= 0) 438 { 439 pos_idx++; 440 if (pos_idx >= (int)m_positionMap.size()) 441 { 442 diff = 0; 443 return false; 444 } 445 if (hasKeyFrameAdjustTable) 446 lastKey = m_positionMap[pos_idx].adjFrame; 447 else 448 lastKey = m_positionMap[pos_idx].index * keyframedist; 449 keyPos = m_positionMap[pos_idx].pos; 450 451 diff = keyPos - curPosition; 452 } 453 454 ringBuffer->Seek(diff, SEEK_CUR); 427 455 } 428 456 429 ringBuffer->Seek(diff, SEEK_CUR);430 431 457 framesPlayed = lastKey; 432 458 framesRead = lastKey; 433 459 … … 455 481 if (desiredFrame < framesPlayed) 456 482 return DoRewind(desiredFrame, doflush); 457 483 484 458 485 bool oldrawstate = getrawframes; 459 486 getrawframes = false; 460 487 461 488 long long last_frame = 0; 462 if (!m_positionMap.empty()) 489 if (ringBuffer->isDVD()) 490 last_frame = m_positionMap[m_positionMap.size()-1].index; 491 else if (!m_positionMap.empty()) 463 492 last_frame = m_positionMap[m_positionMap.size()-1].index * keyframedist; 464 493 465 494 if (desiredFrame > last_frame) … … 474 503 475 504 bool needflush = false; 476 505 506 if (ringBuffer->isDVD()) 507 last_frame = m_positionMap[m_positionMap.size()-1].index; 477 508 if (!m_positionMap.empty()) 478 509 last_frame = m_positionMap[m_positionMap.size()-1].index * keyframedist; 479 510 … … 506 537 if (m_positionMap.empty()) 507 538 return false; 508 539 509 // Find keyframe >= desiredFrame, store in lastKey 510 // if exactseeks, use keyframe <= desiredFrame 511 int pos_idx1, pos_idx2; 512 FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2); 540 if (ringBuffer->isDVD()) 541 { 542 long long pos = DVDFindPosition(desiredFrame); 543 ringBuffer->Seek(pos,SEEK_SET); 544 lastKey = desiredFrame+1; 545 framesPlayed = lastKey; 546 framesRead = lastKey; 547 } 548 else 549 { 550 // Find keyframe >= desiredFrame, store in lastKey 551 // if exactseeks, use keyframe <= desiredFrame 552 int pos_idx1, pos_idx2; 553 FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2); 513 554 514 int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2;555 int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2; 515 556 516 if (hasKeyFrameAdjustTable)517 lastKey = m_positionMap[pos_idx].adjFrame;518 else519 lastKey = m_positionMap[pos_idx].index * keyframedist;557 if (hasKeyFrameAdjustTable) 558 lastKey = m_positionMap[pos_idx].adjFrame; 559 else 560 lastKey = m_positionMap[pos_idx].index * keyframedist; 520 561 521 long long keyPos = m_positionMap[pos_idx].pos;562 long long keyPos = m_positionMap[pos_idx].pos; 522 563 523 if (framesPlayed < lastKey)524 {525 long long diff = keyPos - ringBuffer->GetReadPosition();564 if (framesPlayed < lastKey) 565 { 566 long long diff = keyPos - ringBuffer->GetReadPosition(); 526 567 527 ringBuffer->Seek(diff, SEEK_CUR); 528 needflush = true; 529 530 framesPlayed = lastKey; 531 framesRead = lastKey; 568 ringBuffer->Seek(diff, SEEK_CUR); 569 needflush = true; 570 571 framesPlayed = lastKey; 572 framesRead = lastKey; 573 } 532 574 } 533 575 534 576 int normalframes = desiredFrame - framesPlayed; … … 577 619 waitingForChange = true; 578 620 } 579 621 622 void DecoderBase::ChangeDVDTrack(bool ffw) 623 { 624 bool result = true; 625 if (!ringBuffer->isDVD()) 626 return; 627 628 uint prevcellstart = ringBuffer->GetCellStart(); 629 630 if (ffw) 631 result = ringBuffer->nextTrack(); 632 else 633 ringBuffer->prevTrack(); 634 635 if (result) 636 { 637 638 if ((prevcellstart == 0 && ffw) || (prevcellstart != 0 )) 639 { 640 while (prevcellstart == ringBuffer->GetCellStart()) 641 { 642 usleep(10000); 643 } 644 } 645 646 uint elapsed = ringBuffer->GetCellStart(); 647 648 if (elapsed == 0) 649 SeekReset(framesPlayed,0,true); 650 651 // update frames played 652 long long played = (int) (elapsed * fps); 653 654 framesPlayed = played; 655 GetNVP()->getVideoOutput()->SetFramesPlayed(played+1); 656 GetNVP()->SetFramesPlayed(played+1); 657 } 658 } 659 660 long long DecoderBase::DVDFindPosition(long long desiredFrame) 661 { 662 if ( !ringBuffer->isDVD()) 663 return 0; 664 665 int size = m_positionMap.size() - 1; 666 int multiplier = m_positionMap[size].pos / m_positionMap[size].index ; 667 return (long long) (desiredFrame * multiplier); 668 } -
decoderbase.h
85 85 void SetWaitForChange(void); 86 86 void SetReadAdjust(long long adjust); 87 87 88 // DVD public stuff 89 void ChangeDVDTrack(bool ffw); 90 long long DVDFindPosition(long long desiredFrame); 91 88 92 protected: 89 93 void FileChanged(void); 90 94 -
RingBuffer.h
77 77 bool isDVD(void) const { return dvdPriv; } 78 78 void getPartAndTitle(int &title, int &part); 79 79 void getDescForPos(QString &desc); 80 voidnextTrack(void);80 bool nextTrack(void); 81 81 void prevTrack(void); 82 uint GetTotalTimeOfTitle(void); 83 uint GetCellStart(void); 84 long long GetTotalReadPosition(void); 82 85 83 86 long long SetAdjustFilesize(void); 84 87 -
RingBuffer.cpp
1112 1112 /** \fn RingBuffer::nextTrack(void) 1113 1113 * \brief Calls DVDRingBufferPriv::nextTrack(void) 1114 1114 */ 1115 voidRingBuffer::nextTrack(void)1115 bool RingBuffer::nextTrack(void) 1116 1116 { 1117 1117 if (dvdPriv) 1118 dvdPriv->nextTrack(); 1118 return dvdPriv->nextTrack(); 1119 return false; 1119 1120 } 1120 1121 1121 1122 /** \fn RingBuffer::prevTrack(void) … … 1127 1128 dvdPriv->prevTrack(); 1128 1129 } 1129 1130 1131 /** \fn RingBuffer::GetTotalTimeOfTitle(void) 1132 * \brief Calls DVDRingBufferPriv::GetTotalTimeOfTitle(void) 1133 */ 1134 uint RingBuffer::GetTotalTimeOfTitle(void) 1135 { 1136 if (dvdPriv) 1137 return dvdPriv->GetTotalTimeOfTitle(); 1138 return 0; 1139 } 1140 1141 /** \fn RingBuffer::GetCellStart(void) 1142 * \brief Calls DVDRingBufferPriv::GetCellStart(void) 1143 */ 1144 uint RingBuffer::GetCellStart(void) 1145 { 1146 if (dvdPriv) 1147 return dvdPriv->GetCellStart(); 1148 return 0; 1149 } 1150 1151 /** \fn RingBuffer::GetTotalReadPosition(void) 1152 * \brief Calls DVDRingBufferPriv::GetTotalReadPosition(void) 1153 */ 1154 long long RingBuffer::GetTotalReadPosition(void) 1155 { 1156 if (dvdPriv) 1157 return dvdPriv->GetTotalReadPosition(); 1158 return 0; 1159 } 1160 1161 -
DVDRingBuffer.cpp
326 327 return tot; 327 328 } 328 329 329 voidDVDRingBufferPriv::nextTrack(void)330 bool DVDRingBufferPriv::nextTrack(void) 330 331 { 331 332 int newPart = part + 1; 332 if (newPart < maxPart) 333 if (newPart < maxPart) 334 { 333 335 dvdnav_part_play(dvdnav, title, newPart); 336 return true; 337 } 338 return false; 334 339 } 335 340 336 341 void DVDRingBufferPriv::prevTrack(void) 337 342 { 338 343 int newPart = part - 1; 339 if (newPart < 0) 340 newPart = 0; 344 if (newPart > 0) 345 dvdnav_part_play(dvdnav, title, newPart); 346 else 347 Seek(0,SEEK_SET); // May cause picture to become jumpy. 348 } 341 349 342 dvdnav_part_play(dvdnav, title, newPart); 350 uint DVDRingBufferPriv::GetTotalTimeOfTitle(void) 351 { 352 return pgcLength/90000; // 90000 ticks = 1 second 343 353 } 344 354 355 uint DVDRingBufferPriv::GetCellStart(void) 356 { 357 return cellStart/90000; 358 } 359 345 360 #endif // HAVE_DVDNAV -
DVDRingBuffer.h
2 2 #ifndef DVD_RING_BUFFER_H_ 3 3 #define DVD_RING_BUFFER_H_ 4 4 5 #define DVD_BLOCK_SIZE 2048 5 #define DVD_BLOCK_SIZE 2048LL 6 6 #define DVD_MENU_MAX 7 7 7 8 8 #include <qstring.h> … … 58 59 void GetDescForPos(QString &desc) const; 59 60 void GetPartAndTitle(int &_part, int &_title) const 60 61 { _part = part; _title = _title; } 62 uint GetTotalTimeOfTitle(void); 63 uint GetCellStart(void); 61 64 62 65 // commands 63 66 bool OpenFile(const QString &filename); 64 67 void close(void); 65 voidnextTrack(void);68 bool nextTrack(void); 66 69 void prevTrack(void); 67 70 int safe_read(void *data, unsigned sz); 68 71 long long Seek(long long pos, int whence); -
tv_play.cpp
2027 2027 { 2028 2028 if (prbuffer->isDVD()) 2029 2029 { 2030 prbuffer->prevTrack();2030 nvp->ChangeDVDTrack(0); 2031 2031 UpdateOSDSeekMessage(tr("Previous Chapter"), 2032 2032 osd_general_timeout); 2033 2033 } … … 2040 2040 { 2041 2041 if (prbuffer->isDVD()) 2042 2042 { 2043 prbuffer->nextTrack();2043 nvp->ChangeDVDTrack(1); 2044 2044 UpdateOSDSeekMessage(tr("Next Chapter"), osd_general_timeout); 2045 2045 } 2046 2046 else … … 2320 2320 { 2321 2321 if (prbuffer->isDVD()) 2322 2322 { 2323 prbuffer->prevTrack();2323 nvp->ChangeDVDTrack(0); 2324 2324 UpdateOSDSeekMessage(tr("Previous Chapter"), 2325 2325 osd_general_timeout); 2326 2326 } … … 2333 2333 { 2334 2334 if (prbuffer->isDVD()) 2335 2335 { 2336 prbuffer->nextTrack();2336 nvp->ChangeDVDTrack(1); 2337 2337 UpdateOSDSeekMessage(tr("Next Chapter"), 2338 2338 osd_general_timeout); 2339 2339 } … … 2554 2554 return; 2555 2555 2556 2556 oset = GetOSD()->GetSet("status"); 2557 if ((oset) && (oset->Displaying()) && !prbuffer->isDVD()) 2558 { 2559 InfoMap infoMap; 2560 pbinfoLock.lock(); 2561 playbackinfo->ToMap(infoMap); 2562 pbinfoLock.unlock(); 2563 GetOSD()->HideSet("status"); 2564 GetOSD()->ClearAllText("program_info"); 2565 GetOSD()->SetText("program_info", infoMap, osd_prog_info_timeout); 2566 } 2567 else 2568 { 2569 QString desc = ""; 2570 int pos = nvp->calcSliderPos(desc); 2571 GetOSD()->HideSet("program_info"); 2572 GetOSD()->StartPause(pos, false, tr("Position"), desc, 2573 osd_prog_info_timeout); 2574 update_osd_pos = true; 2575 } 2557 QString desc = ""; 2558 int pos = nvp->calcSliderPos(desc); 2559 GetOSD()->HideSet("program_info"); 2560 GetOSD()->StartPause(pos, false, tr("Position"), desc, 2561 osd_prog_info_timeout); 2562 update_osd_pos = true; 2563 2576 2564 } 2577 2565 2578 2566 bool TV::DoNVPSeek(float time) … … 3330 3318 if (activenvp != nvp) 3331 3319 return; 3332 3320 3321 if (prbuffer->isDVD()) 3322 usleep(100000); 3323 3333 3324 QString desc = ""; 3334 3325 int pos = nvp->calcSliderPos(desc); 3335 3326 bool slidertype = StateIsLiveTV(GetState());