@@ -35,65 +35,13 @@ void clean_up_dict(AVDictionary* p) {
35
35
}
36
36
}
37
37
38
- namespace {
39
-
40
- // https://github.com/FFmpeg/FFmpeg/blob/4e6debe1df7d53f3f59b37449b82265d5c08a172/doc/APIchanges#L252-L260
41
- // Starting from libavformat 59 (ffmpeg 5),
42
- // AVInputFormat is const and related functions expect constant.
43
- #if LIBAVFORMAT_VERSION_MAJOR >= 59
44
- #define AVINPUT_FORMAT_CONST const
45
- #else
46
- #define AVINPUT_FORMAT_CONST
47
- #endif
48
-
49
- } // namespace
50
-
51
38
// //////////////////////////////////////////////////////////////////////////////
52
39
// AVFormatContext
53
40
// //////////////////////////////////////////////////////////////////////////////
54
41
void AVFormatContextDeleter::operator ()(AVFormatContext* p) {
55
42
avformat_close_input (&p);
56
43
};
57
44
58
- AVFormatContextPtr get_input_format_context (
59
- const std::string& src,
60
- const c10::optional<std::string>& device,
61
- const OptionDict& option,
62
- AVIOContext* io_ctx) {
63
- AVFormatContext* pFormat = avformat_alloc_context ();
64
- if (!pFormat) {
65
- throw std::runtime_error (" Failed to allocate AVFormatContext." );
66
- }
67
- if (io_ctx) {
68
- pFormat->pb = io_ctx;
69
- }
70
-
71
- auto * pInput = [&]() -> AVINPUT_FORMAT_CONST AVInputFormat* {
72
- if (device.has_value ()) {
73
- std::string device_str = device.value ();
74
- AVINPUT_FORMAT_CONST AVInputFormat* p =
75
- av_find_input_format (device_str.c_str ());
76
- if (!p) {
77
- std::ostringstream msg;
78
- msg << " Unsupported device/format: \" " << device_str << " \" " ;
79
- throw std::runtime_error (msg.str ());
80
- }
81
- return p;
82
- }
83
- return nullptr ;
84
- }();
85
-
86
- AVDictionary* opt = get_option_dict (option);
87
- int ret = avformat_open_input (&pFormat, src.c_str (), pInput, &opt);
88
- clean_up_dict (opt);
89
-
90
- if (ret < 0 )
91
- throw std::runtime_error (
92
- " Failed to open the input \" " + src + " \" (" + av_err2string (ret) +
93
- " )." );
94
- return AVFormatContextPtr (pFormat);
95
- }
96
-
97
45
AVFormatContextPtr::AVFormatContextPtr (AVFormatContext* p)
98
46
: Wrapper<AVFormatContext, AVFormatContextDeleter>(p) {}
99
47
@@ -162,136 +110,6 @@ void AVCodecContextDeleter::operator()(AVCodecContext* p) {
162
110
avcodec_free_context (&p);
163
111
};
164
112
165
- namespace {
166
- const AVCodec* get_decode_codec (
167
- enum AVCodecID codec_id,
168
- const c10::optional<std::string>& decoder_name) {
169
- const AVCodec* pCodec = !decoder_name.has_value ()
170
- ? avcodec_find_decoder (codec_id)
171
- : avcodec_find_decoder_by_name (decoder_name.value ().c_str ());
172
-
173
- if (!pCodec) {
174
- std::stringstream ss;
175
- if (!decoder_name.has_value ()) {
176
- ss << " Unsupported codec: \" " << avcodec_get_name (codec_id) << " \" , ("
177
- << codec_id << " )." ;
178
- } else {
179
- ss << " Unsupported codec: \" " << decoder_name.value () << " \" ." ;
180
- }
181
- throw std::runtime_error (ss.str ());
182
- }
183
- return pCodec;
184
- }
185
-
186
- } // namespace
187
-
188
- AVCodecContextPtr get_decode_context (
189
- enum AVCodecID codec_id,
190
- const c10::optional<std::string>& decoder_name) {
191
- const AVCodec* pCodec = get_decode_codec (codec_id, decoder_name);
192
-
193
- AVCodecContext* pCodecContext = avcodec_alloc_context3 (pCodec);
194
- if (!pCodecContext) {
195
- throw std::runtime_error (" Failed to allocate CodecContext." );
196
- }
197
- return AVCodecContextPtr (pCodecContext);
198
- }
199
-
200
- #ifdef USE_CUDA
201
- enum AVPixelFormat get_hw_format (
202
- AVCodecContext* ctx,
203
- const enum AVPixelFormat* pix_fmts) {
204
- const enum AVPixelFormat* p = nullptr ;
205
- AVPixelFormat pix_fmt = *static_cast <AVPixelFormat*>(ctx->opaque );
206
- for (p = pix_fmts; *p != -1 ; p++) {
207
- if (*p == pix_fmt) {
208
- return *p;
209
- }
210
- }
211
- TORCH_WARN (" Failed to get HW surface format." );
212
- return AV_PIX_FMT_NONE;
213
- }
214
-
215
- const AVCodecHWConfig* get_cuda_config (const AVCodec* pCodec) {
216
- for (int i = 0 ;; ++i) {
217
- const AVCodecHWConfig* config = avcodec_get_hw_config (pCodec, i);
218
- if (!config) {
219
- break ;
220
- }
221
- if (config->device_type == AV_HWDEVICE_TYPE_CUDA &&
222
- config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) {
223
- return config;
224
- }
225
- }
226
- std::stringstream ss;
227
- ss << " CUDA device was requested, but the codec \" " << pCodec->name
228
- << " \" is not supported." ;
229
- throw std::runtime_error (ss.str ());
230
- }
231
- #endif
232
-
233
- void init_codec_context (
234
- AVCodecContext* pCodecContext,
235
- AVCodecParameters* pParams,
236
- const c10::optional<std::string>& decoder_name,
237
- const OptionDict& decoder_option,
238
- const torch::Device& device,
239
- AVBufferRefPtr& pHWBufferRef) {
240
- const AVCodec* pCodec = get_decode_codec (pParams->codec_id , decoder_name);
241
-
242
- int ret = avcodec_parameters_to_context (pCodecContext, pParams);
243
- if (ret < 0 ) {
244
- throw std::runtime_error (
245
- " Failed to set CodecContext parameter: " + av_err2string (ret));
246
- }
247
-
248
- #ifdef USE_CUDA
249
- // Enable HW Acceleration
250
- if (device.type () == c10::DeviceType::CUDA) {
251
- const AVCodecHWConfig* config = get_cuda_config (pCodec);
252
- // TODO: check how to log
253
- // C10_LOG << "Decoder " << pCodec->name << " supports device " <<
254
- // av_hwdevice_get_type_name(config->device_type);
255
-
256
- // https://www.ffmpeg.org/doxygen/trunk/hw__decode_8c_source.html#l00221
257
- // 1. Set HW pixel format (config->pix_fmt) to opaue pointer.
258
- static thread_local AVPixelFormat pix_fmt = config->pix_fmt ;
259
- pCodecContext->opaque = static_cast <void *>(&pix_fmt);
260
- // 2. Set pCodecContext->get_format call back function which
261
- // will retrieve the HW pixel format from opaque pointer.
262
- pCodecContext->get_format = get_hw_format;
263
- // 3. Create HW device context and set to pCodecContext.
264
- AVBufferRef* hw_device_ctx = nullptr ;
265
- ret = av_hwdevice_ctx_create (
266
- &hw_device_ctx,
267
- AV_HWDEVICE_TYPE_CUDA,
268
- std::to_string (device.index ()).c_str (),
269
- nullptr ,
270
- 0 );
271
- if (ret < 0 ) {
272
- throw std::runtime_error (
273
- " Failed to create CUDA device context: " + av_err2string (ret));
274
- }
275
- assert (hw_device_ctx);
276
- pCodecContext->hw_device_ctx = av_buffer_ref (hw_device_ctx);
277
- pHWBufferRef.reset (hw_device_ctx);
278
- }
279
- #endif
280
-
281
- AVDictionary* opts = get_option_dict (decoder_option);
282
- ret = avcodec_open2 (pCodecContext, pCodec, &opts);
283
- clean_up_dict (opts);
284
-
285
- if (ret < 0 ) {
286
- throw std::runtime_error (
287
- " Failed to initialize CodecContext: " + av_err2string (ret));
288
- }
289
-
290
- if (pParams->codec_type == AVMEDIA_TYPE_AUDIO && !pParams->channel_layout )
291
- pParams->channel_layout =
292
- av_get_default_channel_layout (pCodecContext->channels );
293
- }
294
-
295
113
AVCodecContextPtr::AVCodecContextPtr (AVCodecContext* p)
296
114
: Wrapper<AVCodecContext, AVCodecContextDeleter>(p) {}
297
115
0 commit comments