From e1f5433f1dd72913f45ab3cbd0e887d4a6354e8c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 22 Oct 2015 16:48:38 +1100 Subject: Fix T46565: Movie render crash w/o permissions Rendering to a path that didn't have write permissions would crash. Also fix error where `G.is_rendering` was left set when rendering failed. --- source/blender/avi/intern/avi.c | 5 +++ source/blender/blenkernel/intern/writeavi.c | 2 -- source/blender/render/intern/source/pipeline.c | 47 ++++++++++++++++---------- 3 files changed, 35 insertions(+), 19 deletions(-) (limited to 'source/blender') diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 6ea94d3b2f3..9601d6e5002 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -1063,6 +1063,11 @@ AviError AVI_close_compress(AviMovie *movie) { int temp, movi_size, i; + if (movie->fp == NULL) { + /* none of the allocations below were done if the file failed to open */ + return AVI_ERROR_FOUND; + } + fseek(movie->fp, 0L, SEEK_END); movi_size = (int)ftell(movie->fp); diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index cec455e01b9..cc39a1b6dd6 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -213,8 +213,6 @@ static int start_avi(void *context_v, Scene *UNUSED(scene), RenderData *rd, int if (AVI_open_compress(name, avi, 1, format) != AVI_ERROR_NONE) { BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file"); - MEM_freeN(avi); - avi = NULL; return 0; } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index cdbe8251a6a..150a04238eb 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -3486,6 +3486,18 @@ static void get_videos_dimensions(Render *re, RenderData *rd, size_t *r_width, s BKE_scene_multiview_videos_dimensions_get(rd, width, height, r_width, r_height); } +static void re_movie_free_all(Render *re, bMovieHandle *mh, size_t totvideos) +{ + size_t i; + + for (i = 0; i < totvideos; i++) { + mh->end_movie(re->movie_ctx_arr[i]); + mh->context_free(re->movie_ctx_arr[i]); + } + + MEM_SAFE_FREE(re->movie_ctx_arr); +} + /* saves images to disk */ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override, unsigned int lay_override, int sfra, int efra, int tfra) @@ -3510,15 +3522,10 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri BKE_report(re->reports, RPT_ERROR, "Frame Server only support stereo output for multiview rendering"); return; } - - /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ - /* is also set by caller renderwin.c */ - G.is_rendering = true; - - re->flag |= R_ANIMATION; if (is_movie) { size_t i, width, height; + bool is_error = false; get_videos_dimensions(re, &rd, &width, &height); @@ -3530,11 +3537,25 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri re->movie_ctx_arr[i] = mh->context_create(); - if (!mh->start_movie(re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix)) - G.is_break = true; + if (!mh->start_movie(re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix)) { + is_error = true; + break; + } + } + + if (is_error) { + /* report is handled above */ + re_movie_free_all(re, mh, i + 1); + return; } } + /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ + /* is also set by caller renderwin.c */ + G.is_rendering = true; + + re->flag |= R_ANIMATION; + if (mh && mh->get_next_frame) { /* MULTIVIEW_TODO: * in case a new video format is added that implements get_next_frame multiview has to be addressed @@ -3718,15 +3739,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri /* end movie */ if (is_movie) { - size_t i; - for (i = 0; i < totvideos; i++) { - mh->end_movie(re->movie_ctx_arr[i]); - mh->context_free(re->movie_ctx_arr[i]); - } - - if (re->movie_ctx_arr) { - MEM_freeN(re->movie_ctx_arr); - } + re_movie_free_all(re, mh, totvideos); } if (totskipped && totrendered == 0) -- cgit v1.2.3