Reports: writing movies now uses the reports mechanism to throw errors.

Also fixes bug #19463: screencast to xvid ffmpeg crash.
This commit is contained in:
Brecht Van Lommel 2009-12-22 12:01:32 +00:00
parent 0606dbe291
commit d653192751
15 changed files with 266 additions and 226 deletions

View 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);

View 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);

View 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
}

View 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;
}

View File

@ -52,22 +52,23 @@
#define snprintf _snprintf
#endif
#include "BKE_writeffmpeg.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BKE_global.h"
#include "BKE_idprop.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 "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"
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -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);
}

View 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()

View 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;

View 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);

View 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;
}

View 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);
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");
/* 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");
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);
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;
}

View 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 */

View 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);

View 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;

View 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);

View 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");
}