You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 12e689e
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/docs/multimodal-table/video.mdx
+51-8Lines changed: 51 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -83,10 +83,32 @@ to write complete videos and their logical frame rows.
83
83
84
84
Each logical value is a `VideoFrameDescriptor`: its URI range identifies one complete encoded
85
85
video and its frame ordinal selects a frame inside that video. On write, a `.video` data region
86
-
concatenates raw video payloads without ordinary BLOB entry wrappers. Four embedded delta-varint
87
-
indexes record physical video lengths, logical run lengths, run-to-video references, and the first
88
-
frame ordinal of each run. Consecutive frames therefore need one run entry rather than one index
89
-
entry per row. NULL and data-evolution placeholders use negative run references.
86
+
concatenates raw video payloads without ordinary BLOB entry wrappers. Compact indexes map rows to
87
+
videos and frame ordinals. Version 2 additionally stores compressed keyframe indices and PTS values
88
+
once per physical video, not per-frame mappings. Consecutive frames share one run entry; NULL and data-evolution
89
+
placeholders use negative run references.
90
+
91
+
<pre>
92
+
.video (version 2, in file order)
93
+
├─ Complete encoded videos A, B, ...
94
+
├─ <strong>NEW: Keyframe index blocks A, B, ...</strong>
95
+
│ └─ Compressed keyframe indices and PTS values
96
+
├─ Video payload lengths
97
+
├─ <strong>NEW: Keyframe index block lengths</strong>
98
+
├─ Consecutive-row counts
99
+
├─ Video references for those rows
100
+
├─ Starting frame ordinals for those rows
101
+
└─ Footer
102
+
├─ Byte lengths of the five index arrays above
103
+
│ └─ <strong>NEW: Length of the keyframe-block-length index</strong>
104
+
└─ Magic and format version
105
+
</pre>
106
+
107
+
Each video has its own index block; blocks follow payload order. Their lengths locate individual
108
+
blocks without reading the other videos' indexes. The footer locates the index arrays, not individual
109
+
frames. Row indexes select a video and target frame; keyframe indexes select where decoding starts.
110
+
Index generation and indexed reads use the first video stream. Its stream index and PTS time base
111
+
are obtained from the original container, not stored in the index.
90
112
91
113
## Reuse, Rolling, and Compaction
92
114
@@ -102,9 +124,10 @@ together. The resulting file group remains row-aligned and a single large episod
102
124
configured target.
103
125
104
126
When BLOB compaction is enabled, it byte-copies the complete encoded-video ranges into a new self-contained `.video` pack
105
-
and rebuilds the embedded indexes; it does not decode or re-encode frames. The aligned normal data
127
+
and rebuilds the embedded indexes; it does not decode or re-encode frames. Persisted keyframe indexes
128
+
are copied into the new pack. The aligned normal data
106
129
file contains only application columns such as `episode_id`, state, and action. Paimon stores the
107
-
frame mapping in the `.video` descriptor/index path.
130
+
keyframe index in the `.video` descriptor/index path.
108
131
`blob-compaction.enabled` defaults to `false`; ordinary normal-file compaction can
109
132
leave the video packs unchanged. See [Data Evolution Maintenance](./data-evolution-maintenance#ordinary-compaction).
110
133
@@ -115,8 +138,7 @@ leave the video packs unchanged. See [Data Evolution Maintenance](./data-evoluti
115
138
`.blob`.
116
139
- Non-null writes must be exact descriptor-backed `BlobRef` values containing a
117
140
`VideoFrameDescriptor`. Inline bytes and ordinary `BlobDescriptor` values are rejected.
118
-
- Version 1 addresses frames by zero-based presentation-order ordinal with stride one. It does not
119
-
store PTS values or parse codec/container metadata.
141
+
- Version 1 remains readable but has no persisted keyframe index.
120
142
- A `BlobConsumer` callback is not supported for the video field.
121
143
122
144
## Read Frames
@@ -130,6 +152,27 @@ not contain decoded image pixels. Read behavior differs by API:
130
152
| PyPaimon reads of `.video` fields | Return serialized `VideoFrameDescriptor` values even when `blob-as-descriptor=false`. |
131
153
| Java internal-row API |`row.getBlob(position)` returns a descriptor-backed `BlobRef`; call `toDescriptor()` to access the frame descriptor. `toData()` reads the complete video payload. |
132
154
155
+
PyPaimon decodes supported videos once during ingestion to record accurate keyframe ordinals.
156
+
PyAV reuses this sparse index: seek to an indexed start, verify its timestamp, and count decoded
157
+
frames to the target. Missing indexes use the existing scan path. Explicitly selecting TorchCodec
158
+
keeps its exact mode, including its initialization scan; it does not consume the sparse index.
159
+
Indexed TorchCodec reads also require PyAV to resolve the first video stream from the container header.
160
+
161
+
```text
162
+
Table row
163
+
→ Video A, target frame 1003
164
+
→ A's keyframe index: preceding keyframe 1000, PTS t
165
+
→ Seek and verify the decoded start against the index
0 commit comments