summaryrefslogtreecommitdiffstats
path: root/player/playloop.c
Commit message (Collapse)AuthorAgeFilesLines
* player: update cache state only if requestedwm42014-08-281-1/+6
| | | | | | | | | Add a mechanism to the client API code, which allows the player core to query whether a client API event is needed at all. Use it for the cache update. In this case, this is probably a pure microoptimization; but the mechanism will be useful for other things too.
* player: simplify chapter display name codeBen Boeckel2014-08-281-3/+2
| | | | | The display name is always recomputed, so we can always toss the input name.
* player: dynamically change cache wait timeswm42014-08-271-1/+12
| | | | | | | | | | | Remove the hardcoded wait time of 2 seconds. Instead, adjust the wait time each time we unpause: if downloading the data took longer than its estimated playback time, increase the amount of data we wait for. If it's shorter, decrease it. The +/- is supposed to avoid oscillating between two values if the elapsed time and the wait time are similar. It's not sure if this actually helps with anything, but it can't harm.
* player: slightly better cache underrun detectionwm42014-08-271-5/+2
| | | | | | | | | | | | | | | | | | Use the "native" underrun detection, instead of guessing by a low cache duration. The new underrun detection (which was added with the original commit) might have the problem that it's easy for the playloop to miss the underrun event. The underrun is actually not stored as state, so if the demuxer thread adds a new packet before the playloop happens to see the state, it's as if it never happened. On the other hand, this means that network was fast enough, so it should be just fine. Also, should it happen that we don't know the cached range (the ts_duration < 0 case), just wait until the demuxer goes idle (i.e. read_packet() decides to stop). This pretty much should affect broken or unusual files only, and there might be various things that could go wrong. But it's more robust in the normal case: this situation also happens when no packets have been read yet, and we don't want to consider this as reason to resume playback.
* player: better cache status on status linewm42014-08-271-9/+5
| | | | | | | | | | | | | | The cache percentage was useless. It showed how much of the total stream cache was in use, but since the cache size is something huge and unrelated to the bitrate or network speed, the information content of the percentage was rather low. Replace this with printing the duration of the demuxer-cached data, and the size of the stream cache in KB. I'm not completely sure about the formatting; suggestions are welcome. Note that it's not easy to know how much playback time the stream cache covers, so it's always in bytes.
* player: fix basic playbackwm42014-08-271-6/+6
| | | | | | | | | | | | | The "buffering" logic was active even if the stream cache was disabled. This is contrary to what the manpage says. It also breaks playback because of another bug: the demuxer cache is smaller than 2 seconds, and thus the resume condition never becomes true. Explicitly run this code only if the stream cache is enabled. Also, fix the underlying problem of the breakage, and resume when the demuxer thread stops reading in any case, not just on EOF. Broken by previous commit. Unbreaks playback of local files.
* player: redo how stream caching and pausing on low cache workswm42014-08-271-21/+33
| | | | | | | | | | | | | | | | | | | Add the --cache-secs option, which literally overrides the value of --demuxer-readahead-secs if the stream cache is active. The default value is very high (10 seconds), which means it can act as network cache. Remove the old behavior of trying to pause once the byte cache runs low. Instead, do something similar wit the demuxer cache. The nice thing is that we can guess how many seconds of video it has cached, and we can make better decisions. But for now, apply a relatively naive heuristic: if the cache is below 0.5 secs, pause, and wait until at least 2 secs are available. Note that due to timestamp reordering, the estimated cached duration of video might be inaccurate, depending on the file format. If the file format has DTS, it's easy, otherwise the duration will seemingly jump back and forth.
* player: fix weird behavior when framestepping over format changeswm42014-08-261-1/+1
| | | | | | | | | | When video format changes, the frame before the frame with the new format sets video_status briefly to STATUS_DRAINING. This caused the code to handle the EOF case to kick in, which just pauses the player when trying to step past the last frame. As a result, trying to framestep over format changes resulted in pausing the player. Fix by testing against the correct status.
* audio: minor improvements to timeline switchingwm42014-08-231-4/+4
| | | | | | | | In theory, timestamps can be negative, so we shouldn't just return -1 as special value. Remove the separate code for clearing decode buffers; use the same code that is used for normal seek reset.
* player: some more debugging outputwm42014-08-221-0/+2
|
* player: don't clobber playback position on video endwm42014-08-221-5/+3
| | | | | | | | If video reaches EOF, and audio is also EOF (or is otherwise not meaningful, like audio disabled), then the playback position was briefly set to 0. Fix this by not trying to use a bogus audio PTS. CC: @mpv-player/stable (maybe)
* video: get rid of video_next_pts fieldwm42014-08-221-3/+1
| | | | | | Not really needed anymore. Code should be mostly equivalent. Also get rid of some other now-unused or outdated things.
* video: don't assume query_format is thread-safewm42014-08-201-1/+1
| | | | Although it's probably safe for most VOs, there's no guarantee.
* player: never print status messages before playback beginswm42014-08-181-1/+1
| | | | | | | | | | | | | | | | | | After a new file is loaded, playback never starts instantly. Rather, it takes some playloop iterations until initial audio and video have been decoded, and the outputs have been (lazily) initialized. This means you will get status line updates between the messages that inform of the initialized outputs. This is a bit annoying and clutters the terminal output needlessly. Fix this by never printing the status line before playback isn't fully initialized. Do this by reusing the --term-playing-msg code (which prints a message once playback is initialized). This also makes sure the status line _is_ shown during playback restart when doing seeks. It's possible that the change will make the output more confusing if for some reason is stuck forever initializing playback, but that seems like an obscure corner case that never happens, so forget about it.
* player: remove unneeded callwm42014-08-181-4/+0
| | | | | | | | print_status() is called at a later point anyway (and before sleeping), so this code has little effect. This code was added in commit a4f7a3df5, and I can't observe any problems with idle mode anymore. Now print_status() is called from a single place only, within osd.c.
* player: cosmetics: make code more compactwm42014-08-161-5/+2
|
* video: add VO framedropping modewm42014-08-151-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | This mostly uses the same idea as with vo_vdpau.c, but much simplified. On X11, it tries to get the display framerate with XF86VM, and limits the frequency of new video frames against it. Note that this is an old extension, and is confirmed not to work correctly with multi-monitor setups. But we're using it because it was already around (it is also used by vo_vdpau). This attempts to predict the next vsync event by using the time of the last frame and the display FPS. Even if that goes completely wrong, the results are still relatively good. On other systems, or if the X11 code doesn't return a display FPS, a framerate of 1000 is assumed. This is infinite for all practical purposes, and means that only frames which are definitely too late are dropped. This probably has worse results, but is still useful. "--framedrop=yes" is basically replaced with "--framedrop=decoder". The old framedropping mode is kept around, and should perhaps be improved. Dropping on the decoder level is still useful if decoding itself is too slow.
* player: use virtual time for --audio-file with ordered chapterswm42014-08-151-1/+2
| | | | | | | | | Apparently users prefer this behavior. It was used for subtitles too, so move the code to calculate the video offset into a separate function. Seeking also needs to be fixed. Fixes #1018.
* player: don't quit with --loop-filewm42014-08-131-0/+1
| | | | | | Fixes #1009. CC: @mpv-player/stable
* video: fix and simplify video format changes and last frame displaywm42014-08-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | The previous commit broke these things, and fixing them is separate in this commit in order to reduce the volume of changes. Move the image queue from the VO to the playback core. The image queue is a remnant of the old way how vdpau was implemented, and increasingly became more and more an artifact. In the end, it did only one thing: computing the duration of the current frame. This was done by taking the PTS difference between the current and the future frame. We keep this, but by moving it out of the VO, we don't have to special-case format changes anymore. This simplifies the code a lot. Since we need the queue to compute the duration only, a queue size larger than 2 makes no sense, and we can hardcode that. Also change how the last frame is handled. The last frame is a bit of a problem, because video timing works by showing one frame after another, which makes it a special case. Make the VO provide a function to notify us when the frame is done, instead. The frame duration is used for that. This is not perfect. For example, changing playback speed during the last frame doesn't update the end time. Pausing will not stop the clock that times the last frame. But I don't think this matters for such a corner case.
* video: move display and timing to a separate threadwm42014-08-121-25/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The VO is run inside its own thread. It also does most of video timing. The playloop hands the image data and a realtime timestamp to the VO, and the VO does the rest. In particular, this allows the playloop to do other things, instead of blocking for video redraw. But if anything accesses the VO during video timing, it will block. This also fixes vo_sdl.c event handling; but that is only a side-effect, since reimplementing the broken way would require more effort. Also drop --softsleep. In theory, this option helps if the kernel's sleeping mechanism is too inaccurate for video timing. In practice, I haven't ever encountered a situation where it helps, and it just burns CPU cycles. On the other hand it's probably actively harmful, because it prevents the libavcodec decoder threads from doing real work. Side note: Originally, I intended that multiple frames can be queued to the VO. But this is not done, due to problems with OSD and other certain features. OSD in particular is simply designed in a way that it can be neither timed nor copied, so you do have to render it into the video frame before you can draw the next frame. (Subtitles have no such restriction. sd_lavc was even updated to fix this.) It seems the right solution to queuing multiple VO frames is rendering on VO-backed framebuffers, like vo_vdpau.c does. This requires VO driver support, and is out of scope of this commit. As consequence, the VO has a queue size of 1. The existing video queue is just needed to compute frame duration, and will be moved out in the next commit.
* player: don't delay OSD redraw when pausedwm42014-08-101-2/+4
| | | | We want this heuristic to trigger during normal playback only.
* player: some further playloop cleanupswm42014-08-031-45/+33
| | | | | | | | | | | | | Handle --term-playing-msg at a better place. Move MPV_EVENT_TICK hack into a separate function. Also add some words to the client API that you shouldn't use it. (But better leave breaking it for later.) Handle --frames and frame_step differently. Remove the mess from the playloop, and do it after frame display. Give up on the weird semantics for audio-only mode (they didn't make sense anyway), and adjust the manpage accordingly.
* player: make quit exit immediatelywm42014-08-031-3/+3
| | | | | Stopping playback canceled waiting, but executed the remainder of the playloop, including things like executing pointless seeks.
* player: allow redrawing screen during seekswm42014-08-031-6/+12
| | | | | | | | If seeks take very long, it's better not to freeze up the display. (This doesn't handle the case when decoding video frames is extremely slow; just if hr-seek is used, or the demuxer is threaded and blocks on network I/O.)
* player: don't ignore first chapterwm42014-07-311-1/+1
| | | | | It's a mystery why this was done this way. If the first chapter starts later than the current position, we do have to return -1.
* client API: make "cache" property and similar observablewm42014-07-311-0/+12
| | | | | | Achieve this by polling. Will be used by the OSC. Basically a bad hack - but the point is that the mpv core itself is in the best position to improve this later.
* player: rename a variablewm42014-07-301-3/+3
| | | | | Make it clear that this condition happens when switching to a new timeline segment. It doesn't even need to coincide with a chapter.
* player: move video display code out of the playloopwm42014-07-301-316/+9
| | | | | | | | | | Basically move the code from playloop.c to video.c. The new function write_video() now contains the code that was part of run_playloop(). There are no functional changes, except handling "new_frame_shown" slightly differently. This is done so that we don't need new a new MPContext field or a return value for write_video() to signal this condition. Instead, it's handled indirectly.
* player: split seek_reset()wm42014-07-301-30/+12
| | | | | | | | This also reduces some code duplication with other parts of the code. The changfe is mostly cosmetic, although there are also some subtle changes in behavior. At least one change is that the big desync message is now printed after every seek.
* player: fix time display wheen seeking past EOF with --keep-openwm42014-07-301-17/+16
| | | | | | | | | | | | | | Regression since commit 261506e3. Internally speaking, playback was often not properly terminated, and the main part of handle_keep_open() was just executed once, instead of any time the user tries to seek. This means playback_pts was not set, and the "current time" was determined by the seek target PTS. So fix this aspect of video EOF handling, and also remove the now unnecessary eof_reached field. The pause check before calling pause_player() is a lazy workaround for a strange event feedback loop that happens on EOF with --keep-open.
* player: let explicitly imprecise seeks cancel precise seekswm42014-07-291-0/+3
| | | | | | | | | | | If an imprecise seek is issues while a precise seek is ongoing, don't wait up to 300ms (herustistic which usually improves user experience), but instead let it cancel the seek. Improves responsiveness of the OSC after the previous commit. Note that we don't do this on "default-precise" seeks, because we don't know if they're going to be precise or not.
* player: remove a pointless fieldwm42014-07-291-3/+4
|
* player: disable hr-seek in .ts fileswm42014-07-291-0/+1
| | | | | | | | Seeking in .ts files (and some other formats) is too unreliable, so there's a separate code path for this case. But it breaks hr-seek. Maybe hr-seek could actually be enabled in this case if we're careful enough about timestamp resets, but for now nothing changes.
* player: allow precise seeking with percent seekswm42014-07-291-2/+1
| | | | I'm not sure why this was explicitly disabled. It's from mplayer2 times.
* player: update playback position on seekwm42014-07-291-0/+2
| | | | | | | If the actual PTS is not known yet right after a seek, the "time-pos" property will just return the seek target PTS. For this purpose, trigger a change event to make the client API update the "time-pos" and related properties. (MPV_EVENT_TICK triggers this update.)
* player: logically speed up seek logicwm42014-07-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | Commit 261506e3 made constant seeking feel slower, because a subtle change in the restart logic makes it now waste time showing another video frame. The slowdown is about 20%. (Background: the seek logic explicitly waits until a video frame is displayed, because this makes it easier for the user to search for something in the video. Without this logic, the display would freeze until the user stops giving seek commands.) Fix this by letting the seek logic issue another seek as soon as the first video frame is displayed. This will prevent it from showing a (useless, slow) second frame. Now it seems to be as fast as before the change. One side-effect is that the next seek happens after the first video frame, but _before_ audio is restarted. Seeking is now silent. I guess this is ok, so we don't do anything about it. Actually, I think whether this happens is probably random; the seeking logic simply doesn't make this explicit, so anything can happen.
* audio: change playback restart and resyncingwm42014-07-281-100/+91
| | | | | | | | | | | | | | | | | | | | | This commit makes audio decoding non-blocking. If e.g. the network is too slow the playloop will just go to sleep, instead of blocking until enough data is available. For video, this was already done with commit 7083f88c. For audio, it's unfortunately much more complicated, because the audio decoder was used in a blocking manner. Large changes are required to get around this. The whole playback restart mechanism must be turned into a statemachine, especially since it has close interactions with video restart. Lots of video code is thus also changed. (For the record, I don't think switching this code to threads would make this conceptually easier: the code would still have to deal with external input while blocked, so these in-between states do get visible [and thus need to be handled] anyway. On the other hand, it certainly should be possible to modularize this code a bit better.) This will probably cause a bunch of regressions.
* player: fix idle mode event handlingwm42014-07-221-2/+2
|
* player: don't sleep after seekswm42014-07-211-0/+1
|
* player: simplify a conditionwm42014-07-201-7/+8
| | | | | | | Move a condition somewhere else, which makes it conceptually simpler. Also, the assignment to full_audio_buffers removed with this commit was dead, and its value never used.
* player: simplify logic on video errorswm42014-07-201-1/+1
| | | | | | | | | Fatal errors in the vidoe chain (such as failing to initialize the video chain) disable video decoding. Restart the playloop, instead of just continuing the current iteration. The resulting behavior should be the same, but it gets rid of possible corner cases.
* player: don't wait forever with --cache-pause-below behaviorwm42014-07-201-0/+1
| | | | | | | Commit dc00b146, which disables polling by default, missed another instance of polling: when the player pauses automatically on low cache. This could lead to apparent freezes when playing network streams.
* video: use symbolic constants instead of magic integerswm42014-07-181-7/+7
| | | | | | | | | In my opinion this is not really necessary, since there's only a single user of update_video(), but others reading this code would probably hate me for using magic integer values instead of symbolic constants. This should be a purely cosmetic commit; any changes in behavior are bugs.
* video: don't block when reading video packetswm42014-07-181-3/+6
| | | | | | | | | | | | Instead of blocking on the demuxer when reading a packet, let packets be read asynchronously. Basically, it polls whether a packet is available, and if not, the playloop goes to sleep until the demuxer thread wakes it up. Note that the player will still block for I/O, because audio is still read synchronously. It's much harder to do the same change for audio (because of the design of the audio decoding path and especially initialization), so audio will have to be done later.
* player: remove the last instances of pollingwm42014-07-181-30/+27
| | | | | | | | | | | | | | | | | Mouse cursor handling, --heartbeat-cmd, and OSD messages basically relied on polling. For this reason, the playloop always used a small timeout (not more than 500ms). Fix these cases, and raise the timeout to 100 seconds. There is no reason behind this number; for this specific purpose it's as close to infinity as any other number. On MS Windows, or if vo_sdl is used, the timeout remains very small. In these cases the GUI code doesn't do proper event handling in the first place, and fixing it requires much more effort. getch2_poll() still does polling, because as far as I'm aware no event- based way to detect this state change exists.
* demux: add a demuxer threadwm42014-07-161-19/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds a thread to the demuxer which reads packets asynchronously. It will do so until a configurable minimum packet queue size is reached. (See options.rst additions.) For now, the thread is disabled by default. There are some corner cases that have to be fixed, such as fixing cache behavior with webradios. Note that most interaction with the demuxer is still blocking, so if e.g. network dies, the player will still freeze. But this change will make it possible to remove most causes for freezing. Most of the new code in demux.c actually consists of weird caches to compensate for thread-safety issues (with the previously single-threaded design), or to avoid blocking by having to wait on the demuxer thread. Most of the changes in the player are due to the fact that we must not access the source stream directly. the demuxer thread already accesses it, and the stream stuff is not thread-safe. For timeline stuff (like ordered chapters), we enable the thread for the current segment only. We also clear its packet queue on seek, so that the remaining (unconsumed) readahead buffer doesn't waste memory. Keep in mind that insane subtitles (such as ASS typesetting muxed into mkv files) will practically disable the readahead, because the total queue size is considered when checking whether the minimum queue size was reached.
* Revert "Remove DVD and Bluray support"wm42014-07-151-0/+2
| | | | | | This reverts commit 4b93210e0c244a65ef10a566abed2ad25ecaf9a1. *shrug*
* Remove DVD and Bluray supportwm42014-07-141-2/+0
| | | | It never worked well. Just remux your DVD and BD images to mkv.
* player: remove some inactive codewm42014-07-131-8/+1
| | | | | | | demux_seek() actually doesn't return seek success. Instead, it fails if the demuxer is flagged as unseekable (but this is