@@ -266,6 +266,14 @@ static int64_t seek_file(void *opaque, int64_t offset, int whence) {
266
266
}
267
267
}
268
268
269
+ void clean_avformat_context (AVFormatContext **p) {
270
+ if (*p && (*p)->flags & AVFMT_FLAG_CUSTOM_IO) {
271
+ if (*p && (*p)->pb ) av_freep (&(*p)->pb ->buffer );
272
+ avio_context_free (&(*p)->pb );
273
+ }
274
+ avformat_close_input (p);
275
+ }
276
+
269
277
VideoFile& VideoLoader::get_or_open_file (const std::string &filename) {
270
278
static VideoFile empty_file = {};
271
279
auto & file = open_files_[filename];
@@ -299,12 +307,16 @@ VideoFile& VideoLoader::get_or_open_file(const std::string &filename) {
299
307
// if avformat_open_input fails it frees raw_fmt_ctx so we can release it from unique_ptr
300
308
int ret = avformat_open_input (&tmp_raw_fmt_ctx, NULL , NULL , NULL );
301
309
if (ret < 0 ) {
310
+ // avio_ctx->ctx_ is nullified so we need to free the memory here instead of the
311
+ // AVFormatContext destructor which cannot access it through avio_ctx->ctx_ anymore
312
+ av_freep (&avio_ctx->buffer );
313
+ avio_context_free (&avio_ctx);
302
314
DALI_WARN (make_string (" Failed to open video file " , filename, " because of " ,
303
315
av_err2str (ret)));
304
316
open_files_.erase (filename);
305
317
return empty_file;
306
318
}
307
- file.fmt_ctx_ = make_unique_av<AVFormatContext>(tmp_raw_fmt_ctx, avformat_close_input );
319
+ file.fmt_ctx_ = make_unique_av<AVFormatContext>(tmp_raw_fmt_ctx, clean_avformat_context );
308
320
LOG_LINE << " File open " << filename << std::endl;
309
321
310
322
LOG_LINE << " File info fetched for " << filename << std::endl;
@@ -398,6 +410,8 @@ VideoFile& VideoLoader::get_or_open_file(const std::string &filename) {
398
410
if (pkt.stream_index == file.vid_stream_idx_ ) break ;
399
411
av_packet_unref (&pkt);
400
412
}
413
+ auto pkt_duration = pkt.duration ;
414
+ av_packet_unref (&pkt);
401
415
402
416
if (ret < 0 ) {
403
417
DALI_WARN (make_string (" Unable to read frame from file :" , filename));
@@ -406,10 +420,9 @@ VideoFile& VideoLoader::get_or_open_file(const std::string &filename) {
406
420
}
407
421
408
422
DALI_ENFORCE (skip_vfr_check_ ||
409
- almost_equal (av_q2d (file.frame_base_ ), pkt. duration * av_q2d (file.stream_base_ ), 2 ),
423
+ almost_equal (av_q2d (file.frame_base_ ), pkt_duration * av_q2d (file.stream_base_ ), 2 ),
410
424
" Variable frame rate videos are unsupported. This heuristic can yield false positives. "
411
425
" The check can be disabled via the skip_vfr_check flag. Check failed for file: " + filename);
412
- av_packet_unref (&pkt);
413
426
// empty the read buffer from av_read_frame to save the memory usage
414
427
avformat_flush (file.fmt_ctx_ .get ());
415
428
0 commit comments