From 7b86eff6d2dae6679f31b9b4923306cccf603458 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 11 Jun 2020 10:04:05 +0800 Subject: [PATCH] [mod_av] fix some leaks in error cases --- src/mod/applications/mod_av/avformat.c | 18 ++++--- .../applications/mod_av/test/test_avformat.c | 52 +++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 7c82913d55..f748968202 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1173,7 +1173,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h /** Get information on the input file (number of streams etc.). */ if ((error = avformat_find_stream_info(context->fc, opts ? &opts : NULL)) < 0) { char ebuf[255] = ""; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not open find stream info (error '%s')\n", get_error_text(error, ebuf, sizeof(ebuf))); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not find stream info in file: %s, error = %s)\n", filename, get_error_text(error, ebuf, sizeof(ebuf))); if (opts) av_dict_free(&opts); switch_goto_status(SWITCH_STATUS_FALSE, err); } @@ -1345,16 +1345,20 @@ GCC_DIAG_ON(deprecated-declarations) err: if (context->fc) { + int nb_streams = context->fc->nb_streams; + + if (nb_streams > 2) nb_streams = 2; + + if (context->has_video) close_stream(context->fc, &context->video_st); + + for (i = 0; i < nb_streams; i++) { + close_stream(context->fc, &context->audio_st[i]); + } + avformat_free_context(context->fc); context->fc = NULL; } - /* - if (context->has_video) close_stream(context->fc, &context->video_st); - if (context->has_audio) close_stream(context->fc, &context->audio_st); - - if (context->fc) avformat_close_input(&context->fc); - */ return status; } diff --git a/src/mod/applications/mod_av/test/test_avformat.c b/src/mod/applications/mod_av/test/test_avformat.c index 2304ca8c59..2c8949472f 100644 --- a/src/mod/applications/mod_av/test/test_avformat.c +++ b/src/mod/applications/mod_av/test/test_avformat.c @@ -197,6 +197,58 @@ FST_CORE_BEGIN("conf") } FST_TEST_END() + FST_TEST_BEGIN(avformat_test_read_err) + { + char *path = "$$-non-exist-file.mp4"; + switch_status_t status; + switch_file_handle_t fh = { 0 }; + uint32_t flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO; + + status = switch_core_file_open(&fh, path, 1, 8000, flags, fst_pool); + fst_check(status == SWITCH_STATUS_GENERR); + } + FST_TEST_END() + + FST_TEST_BEGIN(avformat_test_read_ok) + { + char path[1024]; + switch_status_t status; + switch_file_handle_t fh = { 0 }; + uint8_t data[SAMPLES * 2] = { 0 }; + switch_frame_t frame = { 0 }; + switch_size_t len = SAMPLES; + uint32_t flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO; + + frame.data = data; + + sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, "../test_RGB.mp4"); + status = switch_core_file_open(&fh, path, 1, 8000, flags, fst_pool); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(switch_test_flag(&fh, SWITCH_FILE_OPEN)); + + while (1) { + status = switch_core_file_read(&fh, data, &len); + if (status != SWITCH_STATUS_SUCCESS) break; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d\n", len); + // fst_check(len == SAMPLES); + status = switch_core_file_read_video(&fh, &frame, SVR_FLUSH); + + if (status == SWITCH_STATUS_BREAK) { + switch_yield(20000); + continue; + } + + if (status != SWITCH_STATUS_SUCCESS) { + break; + } + + switch_img_free(&frame.img); + switch_yield(20000); + } + + switch_core_file_close(&fh); + } + FST_TEST_END() FST_TEARDOWN_BEGIN() {