From d1dc22e24fda6c626cfe70ef6a8658f6c503b3a5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 28 Jun 2017 12:16:46 -0500 Subject: [PATCH] FS-10433: [mod_av,mod_conference] Crash when video recording fails to setup properly #resolve --- src/mod/applications/mod_av/avformat.c | 21 +++++++++++++------ .../mod_conference/conference_video.c | 10 +++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 55ebed9746..1f2c273690 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -386,7 +386,7 @@ static switch_status_t add_stream(MediaStream *mst, AVFormatContext *fc, AVCodec } if (!(*codec)) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find encoder for '%s'\n", avcodec_get_name(codec_id)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find encoder\n"); return status; } @@ -916,8 +916,10 @@ static void close_stream(AVFormatContext *fc, MediaStream *mst) if (mst->sws_ctx) sws_freeContext(mst->sws_ctx); if (mst->frame) av_frame_free(&mst->frame); if (mst->tmp_frame) av_frame_free(&mst->tmp_frame); - - avcodec_close(mst->st->codec); + + if (mst->st && mst->st->codec) { + avcodec_close(mst->st->codec); + } } SWITCH_STANDARD_APP(record_av_function) @@ -1367,14 +1369,19 @@ SWITCH_STANDARD_API(av_format_api_function) static void mod_avformat_destroy_output_context(av_file_context_t *context) { - if (context->has_video) close_stream(context->fc, &context->video_st); - if (context->has_audio) close_stream(context->fc, &context->audio_st); + close_stream(context->fc, &context->video_st); + close_stream(context->fc, &context->audio_st); if (context->audio_st.resample_ctx) { avresample_free(&context->audio_st.resample_ctx); } avformat_close_input(&context->fc); + + context->fc = NULL; + context->audio_st.st = NULL; + context->video_st.st = NULL; + } static switch_status_t open_input_file(av_file_context_t *context, switch_file_handle_t *handle, const char *filename) @@ -2237,7 +2244,9 @@ static switch_status_t av_file_close(switch_file_handle_t *handle) } if (context->fc) { - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) av_write_trailer(context->fc); + if (context->has_video) { + av_write_trailer(context->fc); + } mod_avformat_destroy_output_context(context); } diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index f2f203980f..cc63d63d04 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -2274,7 +2274,10 @@ void conference_video_check_recording(conference_obj_t *conference, mcu_canvas_t if (switch_test_flag((&imember->rec->fh), SWITCH_FILE_OPEN) && !switch_test_flag((&imember->rec->fh), SWITCH_FILE_PAUSE) && switch_core_file_has_video(&imember->rec->fh, SWITCH_TRUE)) { - switch_core_file_write_video(&imember->rec->fh, frame); + if (switch_core_file_write_video(&imember->rec->fh, frame) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Write Failed\n"); + conference_utils_member_clear_flag_locked(imember, MFLAG_RUNNING); + } } } @@ -3679,7 +3682,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr write_frame.img = imember->canvas->img; if (imember->rec) { - switch_core_file_write_video(&imember->rec->fh, &write_frame); + if (switch_core_file_write_video(&imember->rec->fh, &write_frame) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Write Failed\n"); + conference_utils_member_clear_flag_locked(imember, MFLAG_RUNNING); + } } else { switch_set_flag(&write_frame, SFF_RAW_RTP); write_frame.packet = packet;