summaryrefslogtreecommitdiffstats
path: root/demux/demux_raw.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-05-20 02:18:59 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:04 +0200
commit5b4ae42328b75b2f7683d04736d3c07108b0bcc3 (patch)
tree41faf7cf2842b497c87bc60b442a18f858213423 /demux/demux_raw.c
parent5d69dcfb892f63f0a749713f8293dcdf11e7d532 (diff)
downloadmpv-5b4ae42328b75b2f7683d04736d3c07108b0bcc3.tar.bz2
mpv-5b4ae42328b75b2f7683d04736d3c07108b0bcc3.tar.xz
demux_raw: fix operation with demuxer cache and backward playback
Raw audio formats can be accessed sample-wise, and logically audio packets demuxed from it would contain only 1 sample. This is inefficient, so raw audio demuxers typically "bundle" multiple samples in one packet. The problem for the demuxer cache and backward playback is that they need properly aligned packets to make seeking "deterministic". The requirement is that if you read some packets, and then seek back, you eventually see the same packets again. demux_raw basically allowed to seek into the middle of a previously returned packet, which makes it impossible to make the transition seamless. (Unless you'd be aware of the packet data format and cut them to make it seamless, which is too complex for such a use case.) Solve this by always aligning seeks to packet boundaries. This reduces the seek accuracy to the arbitrarily chosen packet size. But you can use hr-seek to fix this. The gain from not making raw audio an awful special case pays in exchange for this "stupid" suggestion to use hr-seek. It appears this also fixes that it could and did seek into the middle of the frame (not sure if this code was ever tested - it goes back to removing the code duplication between the former demux_rawaudio.c and demux_rawvideo.c). If you really cared, you could introduce a seek flag that controls whether the seek is aligned or not. Then code which requires "deterministic" demuxing could set it. But this isn't really useful for us, and we'd always set the flag anyway, unless maybe the caching were forced disabled. libavformat's wav demuxer exhibits the same issue. We can't fix it (it would require the unpleasant experience of contributing to FFmpeg), so document this in otions.rst. In theory, this also affects seek range joining, but the only bad effect should be that cached data is discarded.
Diffstat (limited to 'demux/demux_raw.c')
-rw-r--r--demux/demux_raw.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/demux/demux_raw.c b/demux/demux_raw.c
index 2b47ebfedf..7469d80c5e 100644
--- a/demux/demux_raw.c
+++ b/demux/demux_raw.c
@@ -301,7 +301,9 @@ static void raw_seek(demuxer_t *demuxer, double seek_pts, int flags)
stream_t *s = demuxer->stream;
int64_t end = 0;
stream_control(s, STREAM_CTRL_GET_SIZE, &end);
- int64_t pos = seek_pts * p->frame_rate * p->frame_size;
+ int64_t frame_nr = seek_pts * p->frame_rate;
+ frame_nr = frame_nr - (frame_nr % p->read_frames);
+ int64_t pos = frame_nr * p->frame_size;
if (flags & SEEK_FACTOR)
pos = end * seek_pts;
if (pos < 0)