feat: retain streaming media and add opt-in automatic quality
This commit is contained in:
+15
-4
@@ -182,6 +182,7 @@ struct Player {
|
||||
|
||||
// Decoders, timeline and output are worker-owned; network readers exclusively own demux I/O.
|
||||
AVFormatContext *format = nullptr;
|
||||
playback::StreamCacheBudget cacheBudget;
|
||||
std::array<std::unique_ptr<playback::NetworkInput>, 2> inputs;
|
||||
bool network = false;
|
||||
bool canSeek = false;
|
||||
@@ -337,8 +338,17 @@ struct Player {
|
||||
(videoFinished ? audioEnd : std::min(audioEnd, videoEnd));
|
||||
}
|
||||
end = std::min(end, duration);
|
||||
if (!std::isfinite(end) || end <= position) return;
|
||||
state.buffered_start = position;
|
||||
if (!std::isfinite(end) || end < position) return;
|
||||
double start = 0;
|
||||
for (int slot = 0; slot < 2; ++slot) {
|
||||
const auto &track = tracks[slot];
|
||||
if (!track.codec) continue;
|
||||
double cached = track.input ? track.input->bufferedStart(slot) : NAN;
|
||||
if (!std::isfinite(cached) && slot == 0 && audioDrained()) cached = this->audioEnd();
|
||||
start = std::max(start, std::isfinite(cached) ? std::clamp(cached, 0.0, position) : position);
|
||||
}
|
||||
if (end <= start) return;
|
||||
state.buffered_start = start;
|
||||
state.buffered_end = end;
|
||||
}
|
||||
|
||||
@@ -359,6 +369,7 @@ struct Player {
|
||||
return (command.action == Action::Seek || command.action == Action::Step) &&
|
||||
command.epoch == activeEpoch;
|
||||
});
|
||||
for (auto &input : inputs) if (input) input->updatePosition(position);
|
||||
publishBufferedRange();
|
||||
state.video_aspect_ratio = 0;
|
||||
if (const auto *video = tracks[1].codec; video && video->width > 0 && video->height > 0) {
|
||||
@@ -475,7 +486,7 @@ struct Player {
|
||||
}
|
||||
|
||||
playback::NetworkInput *openNetworkInput(int slot, const std::string &url, const std::string &headers) {
|
||||
inputs[slot] = std::make_unique<playback::NetworkInput>(stopping, requestedEpoch, activeEpoch, wake);
|
||||
inputs[slot] = std::make_unique<playback::NetworkInput>(stopping, requestedEpoch, activeEpoch, wake, cacheBudget);
|
||||
auto &input = *inputs[slot];
|
||||
input.format = avformat_alloc_context();
|
||||
if (!input.format) throw std::bad_alloc();
|
||||
@@ -608,7 +619,7 @@ struct Player {
|
||||
std::array<int, 2> indices{-1, -1};
|
||||
for (int slot = 0; slot < 2; ++slot)
|
||||
if (tracks[slot].input == input.get()) indices[slot] = tracks[slot].index;
|
||||
input->start(indices, origin);
|
||||
input->start(indices, origin, canSeek);
|
||||
}
|
||||
}
|
||||
status = PLAYER_PAUSED;
|
||||
|
||||
Reference in New Issue
Block a user