Reports: writing movies now uses the reports mechanism to throw errors.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 22 Dec 2009 12:01:32 +0000 (12:01 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 22 Dec 2009 12:01:32 +0000 (12:01 +0000)
Also fixes bug #19463: screencast to xvid ffmpeg crash.

15 files changed:
source/blender/blenkernel/BKE_writeavi.h
source/blender/blenkernel/BKE_writeffmpeg.h
source/blender/blenkernel/BKE_writeframeserver.h
source/blender/blenkernel/intern/writeavi.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenkernel/intern/writeframeserver.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/screen/screendump.c
source/blender/quicktime/apple/qtkit_export.m
source/blender/quicktime/apple/quicktime_export.c
source/blender/quicktime/quicktime_export.h
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/intern/wm_event_system.c
source/creator/creator.c

index 4ef63b0..a8d38dd 100644 (file)
@@ -37,17 +37,19 @@ extern "C" {
 /* generic blender movie support, could move to own module */
 
 struct RenderData;     
+struct ReportList;
 struct Scene;
-void start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
+
+int start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
 void end_avi(void);
-void append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
+int append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
 void makeavistring (struct RenderData *rd, char *string);
 
 typedef struct bMovieHandle {
-       void (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
-       void (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
+       int (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
+       int (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
        void (*end_movie)(void);
-       int (*get_next_frame)(struct RenderData *rd); /* optional */
+       int (*get_next_frame)(struct RenderData *rd, struct ReportList *reports); /* optional */
 } bMovieHandle;
 
 bMovieHandle *BKE_get_movie_handle(int imtype);
index 07e0e01..6ec8320 100644 (file)
@@ -57,11 +57,12 @@ extern "C" {
 
 struct IDProperty;
 struct RenderData;     
+struct ReportList;
 struct Scene;
 
-extern void start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
+extern int start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
 extern void end_ffmpeg(void);
-extern void append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
+extern int append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
 
 extern void ffmpeg_set_preset(struct RenderData *rd, int preset);
 extern void ffmpeg_verify_image_type(struct RenderData *rd);
index 6a38abe..50b905c 100644 (file)
@@ -33,12 +33,13 @@ extern "C" {
 #endif
 
 struct RenderData;     
+struct ReportList;
 struct Scene;
 
-extern void start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
+extern int start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
 extern void end_frameserver(void);
-extern void append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
-extern int frameserver_loop(struct RenderData *rd);
+extern int append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
+extern int frameserver_loop(struct RenderData *rd, struct ReportList *reports);
 
 #ifdef __cplusplus
 }
index 7c58a4f..ec3d118 100644 (file)
@@ -40,6 +40,7 @@
 #include "BLI_blenlib.h"
 
 #include "BKE_global.h"
+#include "BKE_report.h"
 #include "BKE_utildefines.h"
 #include "BKE_writeavi.h"
 #include "AVI_avi.h"
@@ -127,7 +128,7 @@ void makeavistring (RenderData *rd, char *string)
        }
 }
 
-void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty)
+int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports)
 {
        int x, y;
        char name[256];
@@ -153,10 +154,10 @@ void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty)
        else format = AVI_FORMAT_MJPEG;
 
        if (AVI_open_compress (name, avi, 1, format) != AVI_ERROR_NONE) {
-               printf("cannot open or start AVI movie file");
+               BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file.");
                MEM_freeN (avi);
                avi = NULL;
-               return;
+               return 0;
        }
                        
        AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x);
@@ -170,18 +171,17 @@ void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty)
 /*     avi->odd_fields= (rd->mode & R_ODDFIELD)?1:0; */
        
        printf("Created avi: %s\n", name);
+       return 1;
 }
 
-void append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty)
+int append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports)
 {
        unsigned int *rt1, *rt2, *rectot;
        int x, y;
        char *cp, rt;
        
-       if (avi == NULL) {
-               G.afbreek = 1;
-               return;
-       }
+       if (avi == NULL)
+               return 0;
 
        /* note that libavi free's the buffer... stupid interface - zr */
        rectot= MEM_mallocN(rectx*recty*sizeof(int), "rectot");
@@ -205,6 +205,8 @@ void append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty)
        
        AVI_write_frame (avi, (frame-sframe), AVI_FORMAT_RGB32, rectot, rectx*recty*4);
 //     printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe);
+
+       return 1;
 }
 
 void end_avi(void)
@@ -215,3 +217,4 @@ void end_avi(void)
        MEM_freeN (avi);
        avi= NULL;
 }
+
index 1953058..4176794 100644 (file)
 #define snprintf _snprintf
 #endif
 
-#include "BKE_writeffmpeg.h"
-
 #include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+
 #include "BLI_blenlib.h"
 
+#include "AUD_C-API.h" /* must be before BKE_sound.h for define */
+
 #include "BKE_global.h"
 #include "BKE_idprop.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_sound.h"
+#include "BKE_writeffmpeg.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
-#include "DNA_scene_types.h"
-
-#include "AUD_C-API.h"
-#include "BKE_sound.h"
-#include "BKE_main.h"
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -239,10 +240,10 @@ static const char** get_file_extensions(int format)
 }
 
 /* Write a frame to the output file */
-static void write_video_frame(RenderData *rd, AVFrame* frame) 
+static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports)
 {
        int outsize = 0;
-       int ret;
+       int ret, success= 1;
        AVCodecContext* c = get_codec_from_stream(video_stream);
 #ifdef FFMPEG_CODEC_TIME_BASE
        frame->pts = rd->cfra - rd->sfra;
@@ -276,14 +277,17 @@ static void write_video_frame(RenderData *rd, AVFrame* frame)
                packet.size = outsize;
                ret = av_interleaved_write_frame(outfile, &packet);
        } else ret = 0;
+
        if (ret != 0) {
-               G.afbreek = 1;
-               //XXX error("Error writing frame");
+               success= 0;
+               BKE_report(reports, RPT_ERROR, "Error writing frame.");
        }
+
+       return success;
 }
 
 /* read and encode a frame of audio from the buffer */
-static AVFrame* generate_video_frame(uint8_t* pixels) 
+static AVFrame* generate_video_frame(uint8_t* pixels, ReportList *reports
 {
        uint8_t* rendered_frame;
 
@@ -295,8 +299,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
        if (c->pix_fmt != PIX_FMT_BGR32) {
                rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height);
                if (!rgb_frame) {
-                       G.afbreek=1;
-                       //XXX error("Couldn't allocate temporary frame");
+                       BKE_report(reports, RPT_ERROR, "Couldn't allocate temporary frame.");
                        return NULL;
                }
        } else {
@@ -613,7 +616,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
 }
 /* essential functions -- start, append, end */
 
-static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
+static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, ReportList *reports)
 {
        /* Handle to the output file */
        AVFormatContext* of;
@@ -648,22 +651,19 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
        
        exts = get_file_extensions(ffmpeg_type);
        if (!exts) {
-               G.afbreek = 1; /* Abort render */
-               //XXX error("No valid formats found");
-               return;
+               BKE_report(reports, RPT_ERROR, "No valid formats found.");
+               return 0;
        }
        fmt = guess_format(NULL, exts[0], NULL);
        if (!fmt) {
-               G.afbreek = 1; /* Abort render */
-               //XXX error("No valid formats found");
-               return;
+               BKE_report(reports, RPT_ERROR, "No valid formats found.");
+               return 0;
        }
 
        of = av_alloc_format_context();
        if (!of) {
-               G.afbreek = 1;
-               //XXX error("Error opening output file");
-               return;
+               BKE_report(reports, RPT_ERROR, "Error opening output file");
+               return 0;
        }
        
        of->oformat = fmt;
@@ -711,22 +711,16 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
        }
        if (fmt->video_codec == CODEC_ID_DVVIDEO) {
                if (rectx != 720) {
-                       G.afbreek = 1;
-                       //XXX error("Render width has to be 720 pixels for DV!");
-                       return;
+                       BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!");
+                       return 0;
                }
                if (rd->frs_sec != 25 && recty != 480) {
-                       G.afbreek = 1;
-                       //XXX error("Render height has to be 480 pixels "
-                       //      "for DV-NTSC!");
-                       return;
-                       
+                       BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!");
+                       return 0;
                }
                if (rd->frs_sec == 25 && recty != 576) {
-                       G.afbreek = 1;
-                       //XXX error("Render height has to be 576 pixels "
-                       //      "for DV-PAL!");
-                       return;
+                       BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!");
+                       return 0;
                }
        }
        
@@ -735,46 +729,42 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
        if (ffmpeg_type == FFMPEG_DV) {
                fmt->audio_codec = CODEC_ID_PCM_S16LE;
                if (ffmpeg_multiplex_audio && rd->ffcodecdata.audio_mixrate != 48000) {
-                       G.afbreek = 1;
-                       //XXX error("FFMPEG only supports 48khz / stereo "
-                       //      "audio for DV!");
-                       return;
+                       BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
+                       return 0;
                }
        }
        
        video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty);
+       printf("alloc video stream %p\n", video_stream);
        if (!video_stream) {
-               G.afbreek = 1;
-               //XXX error("Error initializing video stream");
-               return;
+               BKE_report(reports, RPT_ERROR, "Error initializing video stream.");
+               return 0;
        }
        
        if (ffmpeg_multiplex_audio) {
                audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of);
                if (!audio_stream) {
-                       G.afbreek = 1;
-                       //XXX error("Error initializing audio stream");
-                       return;
+                       BKE_report(reports, RPT_ERROR, "Error initializing audio stream.");
+                       return 0;
                }
                //XXX audiostream_play(SFRA, 0, 1);
        }
        if (av_set_parameters(of, NULL) < 0) {
-               G.afbreek = 1;
-               //XXX error("Error setting output parameters");
-               return;
+               BKE_report(reports, RPT_ERROR, "Error setting output parameters.");
+               return 0;
        }
        if (!(fmt->flags & AVFMT_NOFILE)) {
                if (url_fopen(&of->pb, name, URL_WRONLY) < 0) {
-                       G.afbreek = 1;
-                       //
-                       //XXX error("Could not open file for writing");
-                       return;
+                       BKE_report(reports, RPT_ERROR, "Could not open file for writing.");
+                       return 0;
                }
        }
 
        av_write_header(of);
        outfile = of;
        dump_format(of, 0, name, 1);
+
+       return 1;
 }
 
 /* **********************************************************************
@@ -831,11 +821,13 @@ static void makeffmpegstring(RenderData* rd, char* string) {
        }
 }
 
-void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty)
+int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports)
 {
+       int success;
+
        ffmpeg_autosplit_count = 0;
 
-       start_ffmpeg_impl(rd, rectx, recty);
+       success = start_ffmpeg_impl(rd, rectx, recty, reports);
 
        if(ffmpeg_multiplex_audio && audio_stream)
        {
@@ -846,6 +838,8 @@ void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty)
                specs.rate = rd->ffcodecdata.audio_mixrate;
                audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra, rd->ffcodecdata.audio_volume);
        }
+
+       return success;
 }
 
 void end_ffmpeg(void);
@@ -870,22 +864,29 @@ static void write_audio_frames()
        }
 }
 
-void append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty
+int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports
 {
+       AVFrame* avframe;
+       int success;
+
        fprintf(stderr, "Writing frame %i, "
                "render width=%d, render height=%d\n", frame,
                rectx, recty);
 
        write_audio_frames();
-       write_video_frame(rd, generate_video_frame((unsigned char*) pixels));
+
+       avframe= generate_video_frame((unsigned char*) pixels, reports);
+       success= (avframe && write_video_frame(rd, avframe, reports));
 
        if (ffmpeg_autosplit) {
                if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) {
                        end_ffmpeg();
                        ffmpeg_autosplit_count++;
-                       start_ffmpeg_impl(rd, rectx, recty);
+                       success &= start_ffmpeg_impl(rd, rectx, recty, reports);
                }
        }
+
+       return success;
 }
 
 
@@ -914,6 +915,7 @@ void end_ffmpeg(void)
        if (video_stream && get_codec_from_stream(video_stream)) {
                avcodec_close(get_codec_from_stream(video_stream));
                video_stream = 0;
+               printf("zero video stream %p\n", video_stream);
        }
 
        
index 0780cd0..20d858f 100644 (file)
@@ -48,6 +48,7 @@
 #include "DNA_userdef_types.h"
 
 #include "BKE_global.h"
+#include "BKE_report.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -101,48 +102,45 @@ static int closesocket(int fd)
 }
 #endif
 
-void start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty)
+int start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports)
 {
-        struct sockaddr_in      addr;
+       struct sockaddr_in addr;
        int arg = 1;
 
        if (!startup_socket_system()) {
-               G.afbreek = 1;
-               //XXX error("Can't startup socket system");
-               return;
+               BKE_report(reports, RPT_ERROR, "Can't startup socket system");
+               return 0;
        }
 
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                shutdown_socket_system();
-               G.afbreek = 1; /* Abort render */
-               //XXX error("Can't open socket");
-               return;
-        }
+               BKE_report(reports, RPT_ERROR, "Can't open socket");
+               return 0;
+       }
 
-       setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-                   (char*) &arg, sizeof(arg));
+       setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &arg, sizeof(arg));
 
        addr.sin_family = AF_INET;
-        addr.sin_port = htons(U.frameserverport);
-        addr.sin_addr.s_addr = INADDR_ANY;
+       addr.sin_port = htons(U.frameserverport);
+       addr.sin_addr.s_addr = INADDR_ANY;
 
        if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                shutdown_socket_system();
-               G.afbreek = 1; /* Abort render */
-               //XXX error("Can't bind to socket");
-               return;
-        }
+               BKE_report(reports, RPT_ERROR, "Can't bind to socket");
+               return 0;
+       }
 
-        if (listen(sock, SOMAXCONN) < 0) {
+       if (listen(sock, SOMAXCONN) < 0) {
                shutdown_socket_system();
-               G.afbreek = 1; /* Abort render */
-               //XXX error("Can't establish listen backlog");
-               return;
-        }
+               BKE_report(reports, RPT_ERROR, "Can't establish listen backlog");
+               return 0;
+       }
        connsock = -1;
 
        render_width = rectx;
        render_height = recty;
+
+       return 1;
 }
 
 static char index_page[] 
@@ -249,7 +247,7 @@ static int handle_request(RenderData *rd, char * req)
        return -1;
 }
 
-int frameserver_loop(RenderData *rd)
+int frameserver_loop(RenderData *rd, ReportList *reports)
 {
        fd_set readfds;
        struct timeval tv;
@@ -355,7 +353,7 @@ static void serve_ppm(int *pixels, int rectx, int recty)
        connsock = -1;
 }
 
-void append_frameserver(RenderData *rd, int frame, int *pixels, int rectx, int recty)
+int append_frameserver(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports)
 {
        fprintf(stderr, "Serving frame: %d\n", frame);
        if (write_ppm) {
@@ -365,6 +363,8 @@ void append_frameserver(RenderData *rd, int frame, int *pixels, int rectx, int r
                closesocket(connsock);
                connsock = -1;
        }
+
+       return 0;
 }
 
 void end_frameserver()
index fe1587a..f0cf338 100644 (file)
@@ -2810,7 +2810,7 @@ static int screen_render_exec(bContext *C, wmOperator *op)
        RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break);
        
        if(RNA_boolean_get(op->ptr, "animation"))
-               RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step);
+               RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports);
        else
                RE_BlenderFrame(re, scene, scene->r.cfra);
        
@@ -2831,6 +2831,7 @@ typedef struct RenderJob {
        ImageUser iuser;
        short *stop;
        short *do_update;
+       ReportList *reports;
 } RenderJob;
 
 static void render_freejob(void *rjv)
@@ -3035,7 +3036,7 @@ static void render_startjob(void *rjv, short *stop, short *do_update)
 #endif
        
        if(rj->anim)
-               RE_BlenderAnim(rj->re, rj->scene, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step);
+               RE_BlenderAnim(rj->re, rj->scene, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step, rj->reports);
        else
                RE_BlenderFrame(rj->re, rj->scene, rj->scene->r.cfra);
 }
@@ -3108,6 +3109,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
        rj->anim= RNA_boolean_get(op->ptr, "animation");
        rj->iuser.scene= scene;
        rj->iuser.ok= 1;
+       rj->reports= op->reports;
        
        /* setup job */
        steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
@@ -3139,8 +3141,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
        
        WM_jobs_start(CTX_wm_manager(C), steve);
        
-       G.afbreek= 0;
-       
        WM_cursor_wait(0);
        WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
        
@@ -3185,6 +3185,7 @@ typedef struct OGLRender {
        GPUOffScreen *ofs;
        int sizex, sizey;
        
+       ReportList *reports;
        bMovieHandle *mh;
        int cfrao, nfra;
        
@@ -3383,9 +3384,9 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *even
        
        if(ibuf) {
                if(BKE_imtype_is_movie(scene->r.imtype)) {
-                       oglrender->mh->append_movie(&scene->r, CFRA, (int*)ibuf->rect, oglrender->sizex, oglrender->sizey);
-                       printf("Append frame %d", scene->r.cfra);
-                       ok= 1;
+                       ok= oglrender->mh->append_movie(&scene->r, CFRA, (int*)ibuf->rect, oglrender->sizex, oglrender->sizey, oglrender->reports);
+                       if(ok)
+                               printf("Append frame %d", scene->r.cfra);
                }
                else {
                        BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
@@ -3439,9 +3440,14 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, wmEvent *eve
                oglrender= op->customdata;
                scene= oglrender->scene;
                
+               oglrender->reports= op->reports;
                oglrender->mh= BKE_get_movie_handle(scene->r.imtype);
-               if(BKE_imtype_is_movie(scene->r.imtype))
-                       oglrender->mh->start_movie(scene, &scene->r, oglrender->sizex, oglrender->sizey);
+               if(BKE_imtype_is_movie(scene->r.imtype)) {
+                       if(!oglrender->mh->start_movie(scene, &scene->r, oglrender->sizex, oglrender->sizey, oglrender->reports)) {
+                               screen_opengl_render_end(C, oglrender);
+                               return OPERATOR_CANCELLED;
+                       }
+               }
                
                oglrender->cfrao= scene->r.cfra;
                oglrender->nfra= SFRA;
index 81c3f4d..088be19 100644 (file)
@@ -42,6 +42,7 @@
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
+#include "BKE_report.h"
 #include "BKE_utildefines.h"
 #include "BKE_writeavi.h"
 
@@ -185,6 +186,7 @@ typedef struct ScreenshotJob {
        int x, y, dumpsx, dumpsy;
        short *stop;
        short *do_update;
+       ReportList reports;
 } ScreenshotJob;
 
 
@@ -227,8 +229,12 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update)
        rd.frs_sec= 10;
        rd.frs_sec_base= 1.0f;
        
-       if(BKE_imtype_is_movie(rd.imtype))
-               mh->start_movie(sj->scene, &rd, sj->dumpsx, sj->dumpsy);
+       if(BKE_imtype_is_movie(rd.imtype)) {
+               if(!mh->start_movie(sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports)) {
+                       printf("screencast job stopped\n");
+                       return;
+               }
+       }
        else
                mh= NULL;
        
@@ -242,8 +248,10 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update)
                if(sj->dumprect) {
                        
                        if(mh) {
-                               mh->append_movie(&rd, cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy);
-                               printf("Append frame %d\n", cfra);
+                               if(mh->append_movie(&rd, cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports))
+                                       printf("Append frame %d\n", cfra);
+                               else
+                                       break;
                        }
                        else {
                                ImBuf *ibuf= IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.planes, 0, 0);
@@ -286,7 +294,7 @@ static int screencast_exec(bContext *C, wmOperator *op)
        bScreen *screen= CTX_wm_screen(C);
        wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), screen, 0);
        ScreenshotJob *sj= MEM_callocN(sizeof(ScreenshotJob), "screenshot job");
-       
+
        /* setup sj */
        if(RNA_boolean_get(op->ptr, "full")) {
                wmWindow *win= CTX_wm_window(C);
@@ -304,6 +312,8 @@ static int screencast_exec(bContext *C, wmOperator *op)
        }
        sj->scene= CTX_data_scene(C);
 
+       BKE_reports_init(&sj->reports, RPT_PRINT);
+
        /* setup job */
        WM_jobs_customdata(steve, sj, screenshot_freejob);
        WM_jobs_timer(steve, 0.1, 0, NC_SCREEN|ND_SCREENCAST);
index c775905..38baacf 100644 (file)
@@ -154,68 +154,68 @@ void makeqtstring (RenderData *rd, char *string) {
 
 #pragma mark export functions
 
-void start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty)
+int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports)
 {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSError *error;
        char name[2048];
+       int success= 1;
 
+       if(qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
        
-       if (G.afbreek != 1) {
-               
-               if(qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
-               
-               [QTMovie enterQTKitOnThread];           
-               
-               /* Check first if the QuickTime 7.2.1 initToWritableFile: method is available */
-               if ([[[[QTMovie alloc] init] autorelease] respondsToSelector:@selector(initToWritableFile:error:)] != YES) {
-                       G.afbreek = 1;
-                       fprintf(stderr, "\nUnable to create quicktime movie, need Quicktime rev 7.2.1 or later");
-               }
-               else {
-                       makeqtstring(rd, name);
-                       qtexport->filename = [NSString stringWithCString:name
-                                                                         encoding:[NSString defaultCStringEncoding]];
-                       qtexport->movie = [[QTMovie alloc] initToWritableFile:qtexport->filename error:&error];
-                               
-                       if(qtexport->movie == nil) {
-                               G.afbreek = 1;
-                               NSLog(@"Unable to create quicktime movie : %@",[error localizedDescription]);
-                               [QTMovie exitQTKitOnThread];
-                       } else {
-                               [qtexport->movie retain];
-                               [qtexport->filename retain];
-                               [qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
-                               [qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute];
-                               
-                               qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000);
-                               
-                               /* specifying the codec attributes : try to retrieve them from render data first*/
-                               if (rd->qtcodecsettings.codecType) {
-                                       qtexport->frameAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
-                                                                                                stringWithCodecType(rd->qtcodecsettings.codecType),
-                                                                                                QTAddImageCodecType,
-                                                                                                [NSNumber numberWithLong:((rd->qtcodecsettings.codecSpatialQuality)*codecLosslessQuality)/100],
-                                                                                                QTAddImageCodecQuality,
-                                                                                                nil];
-                               }
-                               else {
-                                       qtexport->frameAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"jpeg",
-                                                                                                QTAddImageCodecType,
-                                                                                                [NSNumber numberWithLong:codecHighQuality],
-                                                                                                QTAddImageCodecQuality,
-                                                                                                nil];
-                               }
-                               [qtexport->frameAttributes retain];
+       [QTMovie enterQTKitOnThread];           
+       
+       /* Check first if the QuickTime 7.2.1 initToWritableFile: method is available */
+       if ([[[[QTMovie alloc] init] autorelease] respondsToSelector:@selector(initToWritableFile:error:)] != YES) {
+               BKE_report(reports, RPT_EROR, "\nUnable to create quicktime movie, need Quicktime rev 7.2.1 or later");
+               success= 0;
+       }
+       else {
+               makeqtstring(rd, name);
+               qtexport->filename = [NSString stringWithCString:name
+                                                                 encoding:[NSString defaultCStringEncoding]];
+               qtexport->movie = [[QTMovie alloc] initToWritableFile:qtexport->filename error:&error];
+                       
+               if(qtexport->movie == nil) {
+                       BKE_report(reports, RPT_ERROR, "Unable to create quicktime movie.");
+                       success= 0;
+                       NSLog(@"Unable to create quicktime movie : %@",[error localizedDescription]);
+                       [QTMovie exitQTKitOnThread];
+               } else {
+                       [qtexport->movie retain];
+                       [qtexport->filename retain];
+                       [qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
+                       [qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute];
+                       
+                       qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000);
+                       
+                       /* specifying the codec attributes : try to retrieve them from render data first*/
+                       if (rd->qtcodecsettings.codecType) {
+                               qtexport->frameAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
+                                                                                        stringWithCodecType(rd->qtcodecsettings.codecType),
+                                                                                        QTAddImageCodecType,
+                                                                                        [NSNumber numberWithLong:((rd->qtcodecsettings.codecSpatialQuality)*codecLosslessQuality)/100],
+                                                                                        QTAddImageCodecQuality,
+                                                                                        nil];
                        }
+                       else {
+                               qtexport->frameAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"jpeg",
+                                                                                        QTAddImageCodecType,
+                                                                                        [NSNumber numberWithLong:codecHighQuality],
+                                                                                        QTAddImageCodecQuality,
+                                                                                        nil];
+                       }
+                       [qtexport->frameAttributes retain];
                }
        }
        
        [pool drain];
+
+       return success;
 }
 
 
-void append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty)
+int append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports)
 {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSBitmapImageRep *blBitmapFormatImage;
@@ -235,7 +235,7 @@ void append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int rec
                                                                                                                                bitsPerPixel:32];
        if (!blBitmapFormatImage) {
                [pool drain];
-               return;
+               return 0;
        }
        
        from_Ptr = (unsigned char*)pixels;
@@ -257,6 +257,8 @@ void append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int rec
        [blBitmapFormatImage release];
        [frameImage release];
        [pool drain];   
+
+       return 1;
 }
 
 
index 68fd60d..a5737e9 100644 (file)
@@ -503,7 +503,7 @@ void makeqtstring (RenderData *rd, char *string) {
 }
 
 
-void start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty) {
+int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports) {
        OSErr err = noErr;
 
        char name[2048];
@@ -515,6 +515,7 @@ void start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty)
 #else
        char    *qtname;
 #endif
+       int success= 1;
 
        if(qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
 
@@ -534,57 +535,57 @@ void start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty)
                check_renderbutton_framerate(rd);
        }
        
-       if (G.afbreek != 1) {
-               sframe = (rd->sfra);
+       sframe = (rd->sfra);
 
-               makeqtstring(rd, name);
+       makeqtstring(rd, name);
 
 #ifdef __APPLE__
-               EnterMoviesOnThread(0);
-               sprintf(theFullPath, "%s", name);
-
-               /* hack: create an empty file to make FSPathMakeRef() happy */
-               myFile = open(theFullPath, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRUSR|S_IWUSR);
-               if (myFile < 0) {
-                       printf("error while creating file!\n");
-                       /* do something? */
-               }
-               close(myFile);
-               err = FSPathMakeRef((const UInt8 *)theFullPath, &myRef, 0);
-               CheckError(err, "FsPathMakeRef error");
-               err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL);
-               CheckError(err, "FsGetCatalogInfoRef error");
+       EnterMoviesOnThread(0);
+       sprintf(theFullPath, "%s", name);
+
+       /* hack: create an empty file to make FSPathMakeRef() happy */
+       myFile = open(theFullPath, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRUSR|S_IWUSR);
+       if (myFile < 0) {
+               printf("error while creating file!\n");
+               /* do something? */
+       }
+       close(myFile);
+       err = FSPathMakeRef((const UInt8 *)theFullPath, &myRef, 0);
+       CheckError(err, "FsPathMakeRef error");
+       err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL);
+       CheckError(err, "FsGetCatalogInfoRef error");
 #endif
 #ifdef _WIN32
-               qtname = get_valid_qtname(name);
-               sprintf(theFullPath, "%s", qtname);
-               strcpy(name, qtname);
-               MEM_freeN(qtname);
-               
-               CopyCStringToPascal(theFullPath, qtexport->qtfilename);
-               err = FSMakeFSSpec(0, 0L, qtexport->qtfilename, &qtexport->theSpec);
+       qtname = get_valid_qtname(name);
+       sprintf(theFullPath, "%s", qtname);
+       strcpy(name, qtname);
+       MEM_freeN(qtname);
+       
+       CopyCStringToPascal(theFullPath, qtexport->qtfilename);
+       err = FSMakeFSSpec(0, 0L, qtexport->qtfilename, &qtexport->theSpec);
 #endif
 
-               err = CreateMovieFile (&qtexport->theSpec, 
-                                                       kMyCreatorType,
-                                                       smCurrentScript, 
-                                                       createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
-                                                       &qtexport->resRefNum, 
-                                                       &qtexport->theMovie );
-               CheckError(err, "CreateMovieFile error");
-
-               if(err != noErr) {
-                       G.afbreek = 1;
-// XXX                 error("Unable to create Quicktime movie: %s", name);
+       err = CreateMovieFile (&qtexport->theSpec, 
+                                               kMyCreatorType,
+                                               smCurrentScript, 
+                                               createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
+                                               &qtexport->resRefNum, 
+                                               &qtexport->theMovie );
+       CheckError(err, "CreateMovieFile error");
+
+       if(err != noErr) {
+               BKE_reportf(reports, RPT_ERROR, "Unable to create Quicktime movie: %s", name);
+               success= 0;
 #ifdef __APPLE__
-                       ExitMoviesOnThread();
+               ExitMoviesOnThread();
 #endif
-               } else {
-                       printf("Created QuickTime movie: %s\n", name);
+       } else {
+               printf("Created QuickTime movie: %s\n", name);
 
-                       QT_CreateMyVideoTrack(rectx, recty);
-               }
+               QT_CreateMyVideoTrack(rectx, recty);
        }
+
+       return success;
 }
 
 
index 69f6796..5433719 100644 (file)
@@ -46,8 +46,8 @@ struct RenderData;
 struct Scene;
 struct wmOperatorType;
 
-void start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty);       //for movie handle (BKE writeavi.c now)
-void append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
+int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports);   //for movie handle (BKE writeavi.c now)
+int append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports);
 void end_qt(void);
 
 /*RNA helper functions */
index 477a4ba..76e3e00 100644 (file)
@@ -44,6 +44,7 @@ struct RenderData;
 struct RenderEngine;
 struct RenderEngineType;
 struct RenderResult;
+struct ReportList;
 struct Scene;
 
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -200,7 +201,7 @@ void RE_TileProcessor(struct Render *re, int firsttile, int threaded);
 
 /* only RE_NewRender() needed, main Blender render calls */
 void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame);
-void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra, int tfra);
+void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra, int tfra, struct ReportList *reports);
 
 void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
 void RE_WriteRenderResult(RenderResult *rr, char *filename, int compress);
index f7d3d6f..e2b290f 100644 (file)
@@ -2752,10 +2752,11 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
        re->result_ok= 1;
 }
 
-static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
+static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports)
 {
        char name[FILE_MAX];
        RenderResult rres;
+       int ok= 1;
        
        RE_AcquireResultImage(re, &rres);
 
@@ -2768,7 +2769,7 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                        dofree = 1;
                }
                RE_ResultGet32(re, (unsigned int *)rres.rect32);
-               mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
+               ok= mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty, reports);
                if(dofree) {
                        MEM_freeN(rres.rect32);
                }
@@ -2785,7 +2786,6 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                }
                else {
                        ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
-                       int ok;
                        
                        /* if not exists, BKE_write_ibuf makes one */
                        ibuf->rect= (unsigned int *)rres.rect32;    
@@ -2802,7 +2802,6 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                        
                        if(ok==0) {
                                printf("Render error: cannot save %s\n", name);
-                               G.afbreek=1;
                        }
                        else printf("Saved: %s", name);
                        
@@ -2826,10 +2825,12 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
        BLI_timestr(re->i.lastframetime, name);
        printf(" Time: %s\n", name);
        fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
+
+       return ok;
 }
 
 /* saves images to disk */
-void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
+void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, ReportList *reports)
 {
        bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
        unsigned int lay;
@@ -2846,18 +2847,20 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
        re->result_ok= 0;
        
        if(BKE_imtype_is_movie(scene->r.imtype))
-               mh->start_movie(scene, &re->r, re->rectx, re->recty);
-       
+               if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports))
+                       G.afbreek= 1;
+
        if (mh->get_next_frame) {
                while (!(G.afbreek == 1)) {
-                       int nf = mh->get_next_frame(&re->r);
+                       int nf = mh->get_next_frame(&re->r, reports);
                        if (nf >= 0 && nf >= scene->r.sfra && nf <= scene->r.efra) {
                                scene->r.cfra = re->r.cfra = nf;
                                
                                do_render_all_options(re);
 
                                if(re->test_break(re->tbh) == 0) {
-                                       do_write_image_or_movie(re, scene, mh);
+                                       if(!do_write_image_or_movie(re, scene, mh, reports))
+                                               G.afbreek= 1;
                                }
                        } else {
                                if(re->test_break(re->tbh))
@@ -2907,8 +2910,11 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
                        
                        do_render_all_options(re);
                        
-                       if(re->test_break(re->tbh) == 0)
-                               do_write_image_or_movie(re, scene, mh);
+                       if(re->test_break(re->tbh) == 0) {
+                               if(!G.afbreek)
+                                       if(!do_write_image_or_movie(re, scene, mh, reports))
+                                               G.afbreek= 1;
+                       }
                        else
                                G.afbreek= 1;
                
index 435f382..6b0368f 100644 (file)
@@ -305,7 +305,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
        if(op->type->exec)
                retval= op->type->exec(C, op);
        
-       if(!(retval & OPERATOR_RUNNING_MODAL))
+       if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED))
                if(op->reports->list.first)
                        uiPupMenuReports(C, op->reports);
        
@@ -435,11 +435,11 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
 
                /* Note, if the report is given as an argument then assume the caller will deal with displaying them
                 * currently python only uses this */
-               if(!(retval & OPERATOR_RUNNING_MODAL) && reports==NULL) {
+               if((retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED)) && reports==NULL)
                        if(op->reports->list.first) /* only show the report if the report list was not given in the function */
                                uiPupMenuReports(C, op->reports);
                
-               if (retval & OPERATOR_FINISHED) /* todo - this may conflict with the other wm_operator_print, if theres ever 2 prints for 1 action will may need to add modal check here */
+               if (retval & OPERATOR_FINISHED) /* todo - this may conflict with the other wm_operator_print, if theres ever 2 prints for 1 action will may need to add modal check here */
                        if(G.f & G_DEBUG)
                                wm_operator_print(op);
                }
@@ -884,7 +884,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                                CTX_wm_region_set(C, NULL);
                        }
 
-                       if(!(retval & OPERATOR_RUNNING_MODAL))
+                       if(retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED))
                                if(op->reports->list.first)
                                        uiPupMenuReports(C, op->reports);
 
index c080062..cad7939 100644 (file)
@@ -651,10 +651,13 @@ int main(int argc, char **argv)
                                        if (a < argc) {
                                                int frame = atoi(argv[a]);
                                                Render *re = RE_NewRender(scene->id.name);
+                                               ReportList reports;
+
+                                               BKE_reports_init(&reports, RPT_PRINT);
 
                                                frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
                                                
-                                               RE_BlenderAnim(re, scene, frame, frame, scene->r.frame_step);
+                                               RE_BlenderAnim(re, scene, frame, frame, scene->r.frame_step, &reports);
                                        }
                                } else {
                                        printf("\nError: no blend loaded. cannot use '-f'.\n");
@@ -664,7 +667,9 @@ int main(int argc, char **argv)
                                if (CTX_data_scene(C)) {
                                        Scene *scene= CTX_data_scene(C);
                                        Render *re= RE_NewRender(scene->id.name);
-                                       RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step);
+                                       ReportList reports;
+                                       BKE_reports_init(&reports, RPT_PRINT);
+                                       RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
                                } else {
                                        printf("\nError: no blend loaded. cannot use '-a'.\n");
                                }