| 1021 | void NuppelVideoPlayer::PredictFrameSkip(FrameScanType scan) |
| 1022 | { |
| 1023 | m_frame_show.clear(); |
| 1024 | |
| 1025 | if (play_speed <= 1 || play_speed > 2 || scan != kScan_Progressive) |
| 1026 | return; |
| 1027 | |
| 1028 | // For every frame shown, what percent should be skipped? |
| 1029 | |
| 1030 | switch ((int)(play_speed * 100.0 + 0.5)) |
| 1031 | { |
| 1032 | case 105: |
| 1033 | m_frame_show.push_back(20); // skip 5%, 20:1 |
| 1034 | break; |
| 1035 | case 110: |
| 1036 | m_frame_show.push_back(10); // skip 10%, 10:1 |
| 1037 | break; |
| 1038 | case 115: |
| 1039 | m_frame_show.push_back(7); // skip 15% |
| 1040 | m_frame_show.push_back(7); // 20:3 |
| 1041 | m_frame_show.push_back(6); |
| 1042 | break; |
| 1043 | case 120: |
| 1044 | m_frame_show.push_back(5); // skip 20%, 5:1 |
| 1045 | break; |
| 1046 | case 125: |
| 1047 | m_frame_show.push_back(4); // skip 25%, 4:1 |
| 1048 | break; |
| 1049 | case 130: |
| 1050 | m_frame_show.push_back(4); // skip 30% |
| 1051 | m_frame_show.push_back(3); // 10:3 |
| 1052 | m_frame_show.push_back(3); |
| 1053 | break; |
| 1054 | case 135: |
| 1055 | m_frame_show.push_back(4); // skip 35% |
| 1056 | m_frame_show.push_back(3); // 20:7 |
| 1057 | m_frame_show.push_back(3); // round down 10:3 |
| 1058 | break; |
| 1059 | case 140: |
| 1060 | m_frame_show.push_back(3); // skip 40% |
| 1061 | m_frame_show.push_back(2); // 5:2 |
| 1062 | break; |
| 1063 | case 145: |
| 1064 | m_frame_show.push_back(3); // skip 45% |
| 1065 | m_frame_show.push_back(2); // 20:9, round down 5:2 |
| 1066 | break; |
| 1067 | case 150: |
| 1068 | m_frame_show.push_back(2); // skip 50%, 2:1 |
| 1069 | break; |
| 1070 | case 155: |
| 1071 | m_frame_show.push_back(2); // skip 55%, 20:11, round down 2:1 |
| 1072 | break; |
| 1073 | case 160: |
| 1074 | m_frame_show.push_back(2); // skip 60% |
| 1075 | m_frame_show.push_back(2); // 5:3 |
| 1076 | m_frame_show.push_back(1); |
| 1077 | break; |
| 1078 | case 165: |
| 1079 | m_frame_show.push_back(2); // skip 65% |
| 1080 | m_frame_show.push_back(2); // 20:13 |
| 1081 | m_frame_show.push_back(1); // round down 5:3 |
| 1082 | break; |
| 1083 | case 170: |
| 1084 | m_frame_show.push_back(2); // skip 70% |
| 1085 | m_frame_show.push_back(2); // 10:7 |
| 1086 | m_frame_show.push_back(1); // round down 5:3 |
| 1087 | break; |
| 1088 | case 175: |
| 1089 | m_frame_show.push_back(2); // skip 75% |
| 1090 | m_frame_show.push_back(1); // 4:3 |
| 1091 | m_frame_show.push_back(1); |
| 1092 | break; |
| 1093 | case 180: |
| 1094 | m_frame_show.push_back(2); // skip 80% |
| 1095 | m_frame_show.push_back(1); // 5:4 |
| 1096 | m_frame_show.push_back(1); |
| 1097 | m_frame_show.push_back(1); |
| 1098 | break; |
| 1099 | case 185: |
| 1100 | m_frame_show.push_back(2); // skip 85% |
| 1101 | m_frame_show.push_back(1); // 20:17 |
| 1102 | m_frame_show.push_back(1); // round down 5:4 |
| 1103 | m_frame_show.push_back(1); |
| 1104 | break; |
| 1105 | case 190: |
| 1106 | m_frame_show.push_back(2); // skip 90% |
| 1107 | m_frame_show.push_back(1); // 10:9 |
| 1108 | m_frame_show.push_back(1); // round down 5:4 |
| 1109 | m_frame_show.push_back(1); |
| 1110 | break; |
| 1111 | case 195: |
| 1112 | m_frame_show.push_back(2); // skip 95% |
| 1113 | m_frame_show.push_back(1); // 20:19, round down 10:9, again 5:4 |
| 1114 | m_frame_show.push_back(1); |
| 1115 | m_frame_show.push_back(1); |
| 1116 | break; |
| 1117 | case 200: |
| 1118 | m_frame_show.push_back(1); // skip 100%, 1:1 |
| 1119 | break; |
| 1120 | } |
| 1121 | |
| 1122 | QString msg = QString("PredictFrameSkip: speed %1 ").arg(play_speed); |
| 1123 | bool delim = false; |
| 1124 | |
| 1125 | for (m_frame_show_iter = m_frame_show.begin(); |
| 1126 | m_frame_show_iter != m_frame_show.end(); ++m_frame_show_iter) |
| 1127 | { |
| 1128 | msg += QString("%1%2").arg(delim ? ":" : "").arg(*m_frame_show_iter); |
| 1129 | delim = true; |
| 1130 | } |
| 1131 | |
| 1132 | VERBOSE(VB_PLAYBACK, msg); |
| 1133 | |
| 1134 | m_frame_show_iter = m_frame_show.begin(); |
| 1135 | m_frame_show_idx = 0; |
| 1136 | } |
| 1137 | |
2389 | | // Reset A/V Sync |
2390 | | lastsync = true; |
2391 | | |
2392 | | if (buffer && !using_null_videoout && |
2393 | | videoOutput->hasHWAcceleration() && |
2394 | | !videoOutput->IsSyncLocked()) |
2395 | | { |
2396 | | // If we are using certain hardware decoders, so we've already done |
2397 | | // the decoding; display the frame, but don't wait for A/V Sync. |
2398 | | // Excludes HW decoder/render methods that are locked to |
2399 | | // the vertical sync (e.g. VDPAU) |
2400 | | videoOutput->PrepareFrame(buffer, kScan_Intr2ndField); |
2401 | | videoOutput->Show(kScan_Intr2ndField); |
2402 | | VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait."); |
2403 | | } |
2404 | | else |
| 2506 | if (!m_frame_show.empty()) |
| 2507 | { |
| 2508 | if (m_frame_show_idx++ == *m_frame_show_iter) |
2425 | | VERBOSE(VB_IMPORTANT, "NVP: Error condition detected " |
2426 | | "in videoOutput after Show(), aborting playback."); |
2427 | | SetErrored(QObject::tr("Serious error detected in Video Output")); |
2428 | | return; |
| 2522 | dropframe = true; |
| 2523 | // If video is way behind of audio, adjust for it... |
| 2524 | QString dbg = QString("Video is %1 frames behind audio (too slow), ") |
| 2525 | .arg(-diverge); |
| 2526 | |
| 2527 | // Reset A/V Sync |
| 2528 | lastsync = true; |
| 2529 | |
| 2530 | if (buffer && !using_null_videoout && |
| 2531 | videoOutput->hasHWAcceleration() && |
| 2532 | !videoOutput->IsSyncLocked()) |
| 2533 | { |
| 2534 | // If we are using certain hardware decoders, so we've already done |
| 2535 | // the decoding; display the frame, but don't wait for A/V Sync. |
| 2536 | // Excludes HW decoder/render methods that are locked to |
| 2537 | // the vertical sync (e.g. VDPAU) |
| 2538 | videoOutput->PrepareFrame(buffer, kScan_Intr2ndField); |
| 2539 | videoOutput->Show(kScan_Intr2ndField); |
| 2540 | VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait."); |
| 2541 | } |
| 2542 | else |
| 2543 | { |
| 2544 | // If we are using software decoding, skip this frame altogether. |
| 2545 | VERBOSE(VB_PLAYBACK, LOC + dbg + "dropping frame to catch up."); |
| 2546 | } |
2433 | | //second stage of deinterlacer processing |
2434 | | ps = (kScan_Intr2ndField == ps) ? |
2435 | | kScan_Interlaced : kScan_Intr2ndField; |
2436 | | |
2437 | | if (m_double_process && ps != kScan_Progressive) |
2438 | | { |
2439 | | videofiltersLock.lock(); |
2440 | | if (player_ctx->buffer->isDVD() && |
2441 | | player_ctx->buffer->DVD()->InStillFrame() && |
2442 | | videoOutput->ValidVideoFrames() < 3) |
2443 | | { |
2444 | | videoOutput->ProcessFrame(buffer, NULL, NULL, |
2445 | | pip_players, ps); |
2446 | | } |
2447 | | else |
| 2550 | // if we get here, we're actually going to do video output |
| 2551 | if (buffer) |
| 2552 | videoOutput->PrepareFrame(buffer, ps); |
| 2553 | |
| 2554 | VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2") |
| 2555 | .arg(avsync_adjustment).arg(m_double_framerate)); |
| 2556 | videosync->WaitForFrame(avsync_adjustment + repeat_delay); |
| 2557 | VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); |
| 2558 | if (!resetvideo) |
| 2559 | videoOutput->Show(ps); |
| 2560 | |
| 2561 | if (videoOutput->IsErrored()) |
| 2562 | { |
| 2563 | VERBOSE(VB_IMPORTANT, "NVP: Error condition detected " |
| 2564 | "in videoOutput after Show(), aborting playback."); |
| 2565 | SetErrored(QObject::tr("Serious error detected in Video Output")); |
| 2566 | return; |
| 2567 | } |
| 2568 | |
| 2569 | if (m_double_framerate) |
| 2570 | { |
| 2571 | //second stage of deinterlacer processing |
| 2572 | ps = (kScan_Intr2ndField == ps) ? |
| 2573 | kScan_Interlaced : kScan_Intr2ndField; |
| 2574 | |
| 2575 | if (m_double_process && ps != kScan_Progressive) |
2449 | | videoOutput->ProcessFrame( |
2450 | | buffer, osd, videoFilters, pip_players, ps); |
| 2577 | videofiltersLock.lock(); |
| 2578 | if (player_ctx->buffer->isDVD() && |
| 2579 | player_ctx->buffer->DVD()->InStillFrame() && |
| 2580 | videoOutput->ValidVideoFrames() < 3) |
| 2581 | { |
| 2582 | videoOutput->ProcessFrame(buffer, NULL, NULL, |
| 2583 | pip_players, ps); |
| 2584 | } |
| 2585 | else |
| 2586 | { |
| 2587 | videoOutput->ProcessFrame |
| 2588 | (buffer, osd, videoFilters, pip_players, ps); |
| 2589 | } |
| 2590 | videofiltersLock.unlock(); |