Ticket #3355: stick_rew_ffw_dvd.diff
| File stick_rew_ffw_dvd.diff, 12.1 KB (added by , 18 years ago) |
|---|
-
libmythtv/NuppelVideoPlayer.cpp
1238 1238 { 1239 1239 bool stopFFREW = false; 1240 1240 1241 if (ringBuffer->isDVD()) 1242 GetDecoder()->UpdateDVDFramesPlayed(); 1243 1241 1244 if (ffrew_skip > 0) 1242 1245 { 1243 1246 long long delta = GetDecoder()->GetFramesRead() - framesPlayed; … … 1255 1258 bool toBegin = -curFrame > ffrew_skip; 1256 1259 long long real_skip = (toBegin) ? -curFrame : ffrew_skip; 1257 1260 GetDecoder()->DoRewind(curFrame + real_skip, false); 1258 stopFFREW = framesPlayed <= keyframedist;1259 1261 if (ringBuffer->isDVD()) 1260 1262 stopFFREW = (ringBuffer->DVD()->GetCurrentTime() < 2); 1263 else 1264 stopFFREW = framesPlayed <= keyframedist; 1261 1265 } 1262 1266 1263 1267 if (stopFFREW) … … 3835 3839 #endif 3836 3840 3837 3841 GetDecoder()->setExactSeeks(exactseeks && ffrew_skip == 1); 3838 if (!ringBuffer->isDVD()) 3839 GetDecoder()->DoRewind(framesPlayed); 3842 GetDecoder()->DoRewind(framesPlayed); 3840 3843 ClearAfterSeek(); 3841 3844 } 3842 3845 … … 4022 4025 else if (behind - ff <= maxtime * 2) 4023 4026 ret = behind - maxtime * 2; 4024 4027 4025 if (ringBuffer->isDVD()) 4028 if (ringBuffer->isDVD() && 4029 ringBuffer->DVD()->TitleTimeLeft() < 5) 4026 4030 { 4027 if (ringBuffer->DVD()->GetCurrentTime() > 4028 ringBuffer->DVD()->GetTotalTimeOfTitle() - 5) 4029 { 4030 ret = 0; 4031 } 4031 ret = 0; 4032 4032 } 4033 4033 } 4034 4034 } -
libmythtv/DVDRingBuffer.cpp
55 55 jumptotitle(true), 56 56 seekpos(0), seekwhence(0), 57 57 dvdname(NULL), serialnumber(NULL), 58 seeking(false), seek Time(0),58 seeking(false), seektime(0), 59 59 currentTime(0), 60 60 parent(0) 61 61 { 62 62 memset(&dvdMenuButton, 0, sizeof(AVSubtitle)); 63 uint def[8] = { 3, 5, 10, 20, 30, 60, 120, 180 }; 64 uint seekValues[8] = { 1, 2, 4, 8, 10, 15, 20, 60 }; 65 66 for (uint i = 0; i < 8; i++) 67 seekSpeedMap.insert(def[i], seekValues[i]); 63 68 } 64 69 65 70 DVDRingBufferPriv::~DVDRingBufferPriv() … … 93 98 94 99 long long DVDRingBufferPriv::Seek(long long time) 95 100 { 96 seekTime = (uint64_t)time; 101 dvdnav_status_t dvdRet = DVDNAV_STATUS_OK; 102 97 103 uint searchToCellStart = 1; 104 int seekSpeed = 0; 98 105 int ffrewSkip = 1; 99 106 if (parent) 100 107 ffrewSkip = parent->GetFFRewSkip(); 101 if (ffrewSkip != 1) 102 searchToCellStart = 0; 103 dvdnav_status_t dvdRet = 104 dvdnav_time_search(this->dvdnav, seekTime, searchToCellStart); 108 109 if (ffrewSkip != 1 && time != 0) 110 { 111 QMapConstIterator<uint, uint> it = seekSpeedMap.find(labs(time)); 112 seekSpeed = it.data(); 113 if (time < 0) 114 seekSpeed = -seekSpeed; 115 dvdRet = dvdnav_time_search_within_cell(this->dvdnav, seekSpeed); 116 } 117 else 118 { 119 seektime = (uint64_t)time; 120 dvdRet = dvdnav_time_search(this->dvdnav, seektime, searchToCellStart); 121 } 122 105 123 if (dvdRet == DVDNAV_STATUS_ERR) 106 124 { 107 125 VERBOSE(VB_PLAYBACK, LOC_ERR + … … 406 424 currentTime = cellStart + 407 425 (uint)(dvdnav_convert_time(&timeFromCellStart)); 408 426 currentpos = GetReadPosition(); 409 427 410 428 if (seeking) 411 429 { 412 uint relativeTime = (uint)((seekTime - currentTime)/ 90000); 413 if (relativeTime == 0) 430 431 int relativetime = (int)((seektime - currentTime)/ 90000); 432 if (relativetime <= 0) 414 433 { 415 434 seeking = false; 416 seek Time = 0;435 seektime = 0; 417 436 } 418 437 else 419 dvdnav_time_search_within_cell(dvdnav, relative Time);438 dvdnav_time_search_within_cell(dvdnav, relativetime * 2); 420 439 } 421 440 422 441 if (blockBuf != dvdBlockWriteBuf) 423 442 { 424 443 dvdnav_free_cache_block(dvdnav, blockBuf); … … 1310 1330 #endif 1311 1331 } 1312 1332 1333 /**\brief returns seconds left in the title 1334 */ 1335 uint DVDRingBufferPriv::TitleTimeLeft(void) 1336 { 1337 return (GetTotalTimeOfTitle() - 1338 GetCurrentTime()); 1339 } 1340 1313 1341 /** \brief converts palette values from YUV to RGB 1314 1342 */ 1315 1343 void DVDRingBufferPriv::guess_palette(uint32_t *rgba_palette,uint8_t *palette, -
libmythtv/DVDRingBuffer.h
95 95 int NumMenuButtons(void) const; 96 96 void IgnoreStillOrWait(bool skip) { skipstillorwait = skip; } 97 97 uint GetCurrentTime(void) { return (currentTime / 90000); } 98 uint TitleTimeLeft(void); 98 99 void SetTrack(uint type, int trackNo); 99 100 int GetTrack(uint type); 100 101 uint8_t GetNumAudioChannels(int id); … … 162 163 QString dvdname; 163 164 QString serialnumber; 164 165 bool seeking; 165 uint64_t seek Time;166 uint64_t seektime; 166 167 uint currentTime; 168 QMap<uint, uint> seekSpeedMap; 167 169 168 170 NuppelVideoPlayer *parent; 169 171 -
libmythtv/decoderbase.cpp
549 549 .arg(desiredFrame).arg(framesPlayed) 550 550 .arg((discardFrames) ? "do" : "don't")); 551 551 552 if (ringBuffer->isDVD() && 553 ringBuffer->DVD()->TitleTimeLeft() < 5) 554 { 555 return false; 556 } 552 557 // Rewind if we have already played the desiredFrame. The +1 is for 553 558 // MPEG4 NUV files, which need to decode an extra frame sometimes. 554 559 // This shouldn't effect how this works in general because this is … … 723 728 int diffTime = 0; 724 729 long long desiredTimePos; 725 730 int ffrewSkip = 1; 731 int current_speed = 0; 726 732 if (GetNVP()) 733 { 727 734 ffrewSkip = GetNVP()->GetFFRewSkip(); 735 current_speed = (int)GetNVP()->GetNextPlaySpeed(); 736 } 737 728 738 if (ffrewSkip == 1) 729 739 { 730 740 diffTime = (int)ceil((desiredFrame - framesPlayed) / fps); … … 737 747 738 748 if (desiredTimePos < 0) 739 749 desiredTimePos = 0; 750 return (desiredTimePos * 90000LL); 740 751 } 741 else 742 desiredTimePos = (long long)ceil(desiredFrame / fps); 743 return (desiredTimePos * 90000LL); 752 return current_speed; 744 753 } 745 754 746 755 -
libmythdvdnav/searching.c
83 83 } else { 84 84 vobu_start = next_vobu; 85 85 } 86 address ++;86 address++; 87 87 } 88 88 } 89 89 else { 90 90 found = 0; 91 91 first_address = 0; 92 92 last_address = admap->last_byte >> 2; 93 while ( (!found) &&first_address <= last_address)93 while (first_address <= last_address) 94 94 { 95 95 address = (first_address + last_address) / 2; 96 96 next_vobu = admap->vobu_start_sectors[address]; 97 vobu_start = next_vobu; 97 98 if (seekto_block > next_vobu) 98 99 first_address = address + 1; 99 100 else if (seekto_block < next_vobu) … … 103 104 } 104 105 } 105 106 found = 1; 106 vobu_start = next_vobu; 107 if (next_vobu > seekto_block) 108 vobu_start = admap->vobu_start_sectors[last_address - 1]; 107 109 } 108 110 if(found) { 109 111 *vobu = vobu_start; … … 640 642 return DVDNAV_STATUS_OK; 641 643 } 642 644 645 /** \brief Seeks the nearest VOBU to the relative_time within the cell 646 * relative_time is in seconds * 2. 647 * If you want 5 seconds ahead relative time = +10. 648 * If relative_time is negative, then 649 * look backwards within the cell. 650 */ 643 651 dvdnav_status_t dvdnav_time_search_within_cell(dvdnav_t *this, 644 uint relative_time)652 int relative_time) 645 653 { 646 654 if(!this) { 647 655 printerr("Passed a NULL pointer."); … … 649 657 } 650 658 651 659 uint32_t cur_vobu, new_vobu, start, offset; 652 int current_cell, i; 660 uint32_t first_cell_nr, last_cell_nr, cell_nr; 661 cell_playback_t *cell; 662 int i, length, scan_admap; 653 663 654 664 dsi_t * dsi; 655 665 dvd_state_t *state; 656 666 int stime[19] = { 240, 120, 60, 20, 15, 14, 13, 12, 11, 657 667 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; 658 668 pthread_mutex_lock(&this->vm_lock); 669 length = relative_time; 670 state = &(this->vm->state); 671 cell_nr = state->cellN -1; 672 cell = &(state->pgc->cell_playback[cell_nr]); 659 673 cur_vobu = this->vobu.vobu_start; 660 for (i = 0; i <= 19; i++) { 661 if (stime[i]/2.0 <= relative_time) { 662 dsi = dvdnav_get_current_nav_dsi(this); 663 offset = dsi->vobu_sri.fwda[i]; 664 if (offset >> 31) 665 new_vobu = cur_vobu + (dsi->vobu_sri.fwda[i] & 0xfffff); 666 else 667 new_vobu = cur_vobu; 668 break; 674 scan_admap = 0; 675 676 if (this->pgc_based) { 677 first_cell_nr = 0; 678 last_cell_nr = state->pgc->nr_of_cells - 1; 679 } else { 680 printerr("dvdnav_time_search_within_cell: works only if pgc_based is enabled"); 681 return DVDNAV_STATUS_ERR; 682 } 683 684 if (length != 0) 685 { 686 dsi = dvdnav_get_current_nav_dsi(this); 687 if (length > 0) { 688 for (i = 0; i <= 19; i++) { 689 if (stime[i]/2.0 <= length/2.0) { 690 offset = dsi->vobu_sri.fwda[i]; 691 if (offset >> 31) { 692 new_vobu = cur_vobu + (offset & 0xffff); 693 } else { 694 if (cell_nr == last_cell_nr) { 695 offset = state->pgc->cell_playback[last_cell_nr].last_sector; 696 scan_admap = 1; 697 } else { 698 cell_nr++; 699 new_vobu = state->pgc->cell_playback[cell_nr].first_sector; 700 } 701 } 702 break; 703 } 704 } 705 } else { 706 for (i = 0; i <= 19; i++) { 707 if (stime[18 - i]/2.0 >= abs(length)/2.0) 708 { 709 offset = dsi->vobu_sri.bwda[i]; 710 if (offset >> 31) { 711 new_vobu = cur_vobu - (offset & 0xffff); 712 } else { 713 if (cell_nr == first_cell_nr) { 714 new_vobu = 0; 715 } else { 716 cell_nr--; 717 offset = state->pgc->cell_playback[cell_nr].last_sector; 718 scan_admap = 1; 719 } 720 } 721 break; 722 } 723 } 669 724 } 670 725 } 671 672 state = &(this->vm->state); 673 current_cell = state->cellN; 674 start = state->pgc->cell_playback[current_cell-1].first_sector; 675 if (vm_jump_cell_block(this->vm, state->cellN, new_vobu - start)) { 726 727 if (scan_admap) 728 { 729 if (dvdnav_scan_admap(this, state->domain, offset, &new_vobu) == DVDNAV_STATUS_ERR) 730 return DVDNAV_STATUS_ERR; 731 } 732 start = state->pgc->cell_playback[cell_nr].first_sector; 733 if (vm_jump_cell_block(this->vm, cell_nr+1, new_vobu - start)) { 676 734 this->vm->hop_channel += HOP_SEEK; 677 735 } 678 736 pthread_mutex_unlock(&this->vm_lock); 679 737 return DVDNAV_STATUS_OK; 680 738 } 739 -
libmythdvdnav/dvdnav.h
369 369 dvdnav_status_t dvdnav_time_search(dvdnav_t *self, 370 370 uint64_t time, uint search_to_nearest_cell); 371 371 372 /* Seeks the nearest VOBU to the relative_time within the cell 373 * relative_time is in seconds 374 */ 375 dvdnav_status_t dvdnav_time_search_within_cell(dvdnav_t *self, 376 uint relative_time); 372 int dvdnav_time_search_within_cell(dvdnav_t *self, 373 int relative_time); 377 374 /* 378 375 * Stop playing current position and play the "GoUp"-program chain. 379 376 * (which generally leads to the title menu or a higer-level menu). 380 377 */ 381 378 dvdnav_status_t dvdnav_go_up(dvdnav_t *self); 382 383 379 /* 384 380 * Stop playing the current position and start playback at the 385 381 * previous program (if it exists).
