1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//! Safe RAII ownership of a raw `*mut AVFormatContext`.
//!
//! [`FormatContext`] replaces the `is_input` + `is_set_callback` boolean pair on
//! the legacy `AVFormatContextBox` with a single typed [`Mode`] discriminant, so
//! the four mutually-exclusive teardown paths are selected by variant rather than
//! by a runtime boolean fan-out. The input-vs-output axis in particular is now a
//! type-level fact: `avformat_close_input` and `avformat_free_context` are not
//! interchangeable, and encoding the choice in the type removes the class of bug
//! where the wrong one is called.
//!
//! The teardown itself is **not** reimplemented here — [`Drop`] delegates to the
//! existing crate helpers [`in_fmt_ctx_free`] / [`out_fmt_ctx_free`], which own
//! the custom-IO ordering (capture `pb` before `avformat_close_input`, reclaim the
//! callback `Box` and AVIO buffer after). This is deliberately a thin ownership
//! wrapper, not a rewrite of the free logic.
use null_mut;
use AVFormatContext;
use crate;
/// Teardown discriminant for [`FormatContext`].
///
/// Each variant maps to exactly one of the four `(is_input, is_set_callback)`
/// combinations the legacy free helpers dispatch on:
///
/// | variant | free call |
/// |---|---|
/// | [`Mode::Input`] | `in_fmt_ctx_free(ptr, false)` |
/// | [`Mode::InputCustomIo`] | `in_fmt_ctx_free(ptr, true)` |
/// | [`Mode::Output`] | `out_fmt_ctx_free(ptr, false)` |
/// | [`Mode::OutputCustomIo`] | `out_fmt_ctx_free(ptr, true)` |
///
/// Shared with `FmtCtxGuard` (the open-time RAII guard in `crate::core::context`),
/// which dispatches its Drop on the same discriminant.
pub
/// Sole owner of a `*mut AVFormatContext`.
///
/// Move-only (no `Clone`/`Copy`): the compiler therefore guarantees a single owner
/// and thus a single [`Drop`], which is what makes the "no double-free" argument
/// hold by construction. Ownership is transferred by moving the value; there is no
/// path in the pilot that copies the raw pointer into a second owner.
pub
// SAFETY: same reasoning as `AVFormatContextBox`'s own `unsafe impl Send`. The
// pointer is only dereferenced from the thread that owns the `FormatContext`; the
// crate moves the value between threads but never shares it, and the pilot path
// installs no thread-affine callbacks. `Send` only, never `Sync` — concurrent
// access to the underlying context would be unsound.
unsafe