nvidia-codec 0.0.23__tar.gz → 0.0.24__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nvidia_codec-0.0.23/src/nvidia_codec.egg-info → nvidia_codec-0.0.24}/PKG-INFO +1 -1
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/setup.cfg +1 -1
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/utils/decode.py +16 -8
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/utils/demux.py +6 -1
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24/src/nvidia_codec.egg-info}/PKG-INFO +1 -1
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/tests/test_smoke.py +23 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/LICENSE +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/README.md +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/pyproject.toml +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/__init__.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/common.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/core/__init__.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/core/common.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/core/cuda.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/core/cuviddec.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/core/decode.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/core/nvcuvid.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/__init__.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/adapt.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/common.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/include/__init__.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/include/libavcodec.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/include/libavformat.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/include/libavutil.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/libavcodec.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/libavformat.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/libavutil.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/ffmpeg/test.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/utils/__init__.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/utils/color.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/utils/compat.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec/utils/player.py +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec.egg-info/SOURCES.txt +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec.egg-info/dependency_links.txt +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec.egg-info/requires.txt +0 -0
- {nvidia_codec-0.0.23 → nvidia_codec-0.0.24}/src/nvidia_codec.egg-info/top_level.txt +0 -0
|
@@ -273,12 +273,17 @@ class Decoder(BaseDecoder):
|
|
|
273
273
|
frame we hand back is up to a GOP late. (ffmpeg's CLI papers over this
|
|
274
274
|
with a fixed 3/23 s dts heuristic.)
|
|
275
275
|
|
|
276
|
-
Peek at the landing packet; if it isn't a keyframe
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
Peek at the landing packet; if it isn't a keyframe — OR it is one but
|
|
277
|
+
its PTS is past the target (dts-space seek with B-frames: a keyframe's
|
|
278
|
+
dts precedes its pts by video_delay frames, so for a target inside
|
|
279
|
+
that window the seek picks a keyframe whose first displayed frame is
|
|
280
|
+
already too late; the on-screen frame belongs to the previous GOP) —
|
|
281
|
+
back off by a growing number of frame-durations and retry. Landing on
|
|
282
|
+
an earlier keyframe than strictly needed only costs decode-forward
|
|
283
|
+
time, so overshooting backwards is safe. The peek consumes a packet,
|
|
284
|
+
so the final seek re-runs to restore the position. Raises AVException
|
|
285
|
+
if the container can't seek at all (caller falls back to the
|
|
286
|
+
in-memory index).
|
|
282
287
|
"""
|
|
283
288
|
fc, stream = self.track.fc, self.track.stream
|
|
284
289
|
tb = self.track._time_base
|
|
@@ -289,8 +294,11 @@ class Decoder(BaseDecoder):
|
|
|
289
294
|
for _ in range(max_tries):
|
|
290
295
|
fc.seek_file(stream, ts, min_ts=-(2**63), max_ts=ts)
|
|
291
296
|
first = next(fc.read_packets(stream), None)
|
|
292
|
-
if first is None
|
|
293
|
-
break #
|
|
297
|
+
if first is None:
|
|
298
|
+
break # EOF — nothing to fix
|
|
299
|
+
pts_ok = first.av.pts == AV_NOPTS_VALUE or first.av.pts <= target_pts
|
|
300
|
+
if first.av.flags & AV_PKT_FLAG_KEY and pts_ok:
|
|
301
|
+
break # keyframe that displays at/before target
|
|
294
302
|
landed = first.av.dts if first.av.dts != AV_NOPTS_VALUE else first.av.pts
|
|
295
303
|
if landed == AV_NOPTS_VALUE:
|
|
296
304
|
break # can't reason about position
|
|
@@ -246,7 +246,12 @@ class VideoTrack:
|
|
|
246
246
|
return default if r == AVColorRange.UNSPECIFIED else r
|
|
247
247
|
|
|
248
248
|
def time2pts(self, time: timedelta):
|
|
249
|
-
|
|
249
|
+
"""timedelta -> track pts (floor). Exact rational arithmetic: timedelta has
|
|
250
|
+
microsecond resolution, so 1.16 s is 1160000 us and lands on pts 14848 in a
|
|
251
|
+
1/12800 base; via float it is 14847.999... and int() would floor to the
|
|
252
|
+
PREVIOUS frame for any target exactly on a frame boundary."""
|
|
253
|
+
us = time // timedelta(microseconds=1)
|
|
254
|
+
return int(Fraction(us, 1_000_000) / self._time_base) + self._start_time
|
|
250
255
|
|
|
251
256
|
def pts2time(self, pts: int):
|
|
252
257
|
if pts == AV_NOPTS_VALUE:
|
|
@@ -133,10 +133,33 @@ def test_mpegts_start_time_and_first_gop(clip):
|
|
|
133
133
|
assert abs(t.total_seconds() - 1.0) < 1 / FPS + 1e-3
|
|
134
134
|
pts0, _ = next(iter(p.frames(torch.uint8, start=timedelta(seconds=1))))
|
|
135
135
|
assert abs(p.track.pts2time(pts0).total_seconds() - 1.0) < 1 / FPS + 1e-3
|
|
136
|
+
# DTS-vs-PTS window: with B-frames the GOP-2 keyframe (pts 0.96 s) has
|
|
137
|
+
# dts ~0.88 s. A target in between must still yield the previous GOP's
|
|
138
|
+
# frame, not the keyframe (which displays after the target).
|
|
139
|
+
for target in (0.90, 0.94):
|
|
140
|
+
expect = int(target * FPS + 1e-6) / FPS
|
|
141
|
+
t, _ = p.screenshot(timedelta(seconds=target), torch.uint8, accurate=True)
|
|
142
|
+
assert abs(t.total_seconds() - expect) < 1e-3, (target, t)
|
|
143
|
+
pts0, _ = next(iter(p.frames(torch.uint8, start=timedelta(seconds=target))))
|
|
144
|
+
assert abs(p.track.pts2time(pts0).total_seconds() - expect) < 1e-3, (target, pts0)
|
|
136
145
|
finally:
|
|
137
146
|
shutil.rmtree(d, ignore_errors=True)
|
|
138
147
|
|
|
139
148
|
|
|
149
|
+
def test_time2pts_exact_on_frame_boundaries(clip):
|
|
150
|
+
"""time2pts must not floor a target that is exactly on a frame boundary to
|
|
151
|
+
the previous frame (float 1.16 * 12800 = 14847.999...)."""
|
|
152
|
+
with Player(clip) as p:
|
|
153
|
+
tb = p.track._time_base
|
|
154
|
+
for i in range(FPS * SECONDS):
|
|
155
|
+
td = timedelta(seconds=i / FPS)
|
|
156
|
+
expect = int(round(float(td.total_seconds() / tb))) + p.track._start_time
|
|
157
|
+
assert p.track.time2pts(td) == expect, i
|
|
158
|
+
# between two frames the pts lands strictly between their pts values
|
|
159
|
+
a, b = p.track.time2pts(timedelta(seconds=1.16)), p.track.time2pts(timedelta(seconds=1.20))
|
|
160
|
+
assert a < p.track.time2pts(timedelta(seconds=1.17)) < b
|
|
161
|
+
|
|
162
|
+
|
|
140
163
|
def test_pixel_format_enum_values():
|
|
141
164
|
from nvidia_codec.ffmpeg.include.libavutil import AVPixelFormat
|
|
142
165
|
assert AVPixelFormat.YUV420P == 0 and AVPixelFormat.RGB24 == 2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|