Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): Robert Wenzlaff 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * 00027 * Functions for writing avi-format files. 00028 * Added interface for generic movie support (ton) 00029 */ 00030 00036 #include <string.h> 00037 00038 #include "MEM_guardedalloc.h" 00039 00040 #include "DNA_scene_types.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_utildefines.h" 00044 00045 #include "BKE_global.h" 00046 #include "BKE_main.h" 00047 #include "BKE_report.h" 00048 00049 #include "BKE_writeavi.h" 00050 #include "AVI_avi.h" 00051 00052 /* callbacks */ 00053 static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports); 00054 static void end_avi(void); 00055 static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels, 00056 int rectx, int recty, ReportList *reports); 00057 static void filepath_avi(char *string, RenderData *rd); 00058 00059 /* ********************** general blender movie support ***************************** */ 00060 00061 #ifdef WITH_QUICKTIME 00062 #include "quicktime_export.h" 00063 #endif 00064 00065 #ifdef WITH_FFMPEG 00066 #include "BKE_writeffmpeg.h" 00067 #endif 00068 00069 #include "BKE_writeframeserver.h" 00070 00071 bMovieHandle *BKE_get_movie_handle(const char imtype) 00072 { 00073 static bMovieHandle mh; 00074 00075 /* set the default handle, as builtin */ 00076 mh.start_movie= start_avi; 00077 mh.append_movie= append_avi; 00078 mh.end_movie= end_avi; 00079 mh.get_next_frame = NULL; 00080 mh.get_movie_path = filepath_avi; 00081 00082 /* do the platform specific handles */ 00083 #if defined(_WIN32) && !defined(FREE_WINDOWS) 00084 if (imtype == R_IMF_IMTYPE_AVICODEC) { 00085 //XXX mh.start_movie= start_avi_codec; 00086 //XXX mh.append_movie= append_avi_codec; 00087 //XXX mh.end_movie= end_avi_codec; 00088 } 00089 #endif 00090 #ifdef WITH_QUICKTIME 00091 if (imtype == R_IMF_IMTYPE_QUICKTIME) { 00092 mh.start_movie= start_qt; 00093 mh.append_movie= append_qt; 00094 mh.end_movie= end_qt; 00095 mh.get_movie_path = filepath_qt; 00096 } 00097 #endif 00098 #ifdef WITH_FFMPEG 00099 if (ELEM4(imtype, R_IMF_IMTYPE_FFMPEG, R_IMF_IMTYPE_H264, R_IMF_IMTYPE_XVID, R_IMF_IMTYPE_THEORA)) { 00100 mh.start_movie = start_ffmpeg; 00101 mh.append_movie = append_ffmpeg; 00102 mh.end_movie = end_ffmpeg; 00103 mh.get_movie_path = filepath_ffmpeg; 00104 } 00105 #endif 00106 #ifdef WITH_FRAMESERVER 00107 if (imtype == R_IMF_IMTYPE_FRAMESERVER) { 00108 mh.start_movie = start_frameserver; 00109 mh.append_movie = append_frameserver; 00110 mh.end_movie = end_frameserver; 00111 mh.get_next_frame = frameserver_loop; 00112 } 00113 #endif 00114 00115 /* incase all above are disabled */ 00116 (void)imtype; 00117 00118 return &mh; 00119 } 00120 00121 /* ****************************************************************** */ 00122 00123 00124 static AviMovie *avi=NULL; 00125 00126 static void filepath_avi (char *string, RenderData *rd) 00127 { 00128 if (string==NULL) return; 00129 00130 strcpy(string, rd->pic); 00131 BLI_path_abs(string, G.main->name); 00132 00133 BLI_make_existing_file(string); 00134 00135 if (!BLI_testextensie(string, ".avi")) { 00136 BLI_path_frame_range(string, rd->sfra, rd->efra, 4); 00137 strcat(string, ".avi"); 00138 } 00139 } 00140 00141 static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports) 00142 { 00143 int x, y; 00144 char name[256]; 00145 AviFormat format; 00146 int quality; 00147 double framerate; 00148 00149 (void)scene; /* unused */ 00150 00151 filepath_avi(name, rd); 00152 00153 x = rectx; 00154 y = recty; 00155 00156 quality= rd->im_format.quality; 00157 framerate= (double) rd->frs_sec / (double) rd->frs_sec_base; 00158 00159 avi = MEM_mallocN (sizeof(AviMovie), "avimovie"); 00160 00161 if (rd->im_format.imtype != R_IMF_IMTYPE_AVIJPEG ) format = AVI_FORMAT_AVI_RGB; 00162 else format = AVI_FORMAT_MJPEG; 00163 00164 if (AVI_open_compress (name, avi, 1, format) != AVI_ERROR_NONE) { 00165 BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file."); 00166 MEM_freeN (avi); 00167 avi = NULL; 00168 return 0; 00169 } 00170 00171 AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x); 00172 AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &y); 00173 AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &quality); 00174 AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &framerate); 00175 00176 avi->interlace= 0; 00177 avi->odd_fields= 0; 00178 /* avi->interlace= rd->mode & R_FIELDS; */ 00179 /* avi->odd_fields= (rd->mode & R_ODDFIELD)?1:0; */ 00180 00181 printf("Created avi: %s\n", name); 00182 return 1; 00183 } 00184 00185 static int append_avi(RenderData *UNUSED(rd), int start_frame, int frame, int *pixels, 00186 int rectx, int recty, ReportList *UNUSED(reports)) 00187 { 00188 unsigned int *rt1, *rt2, *rectot; 00189 int x, y; 00190 char *cp, rt; 00191 00192 if (avi == NULL) 00193 return 0; 00194 00195 /* note that libavi free's the buffer... stupid interface - zr */ 00196 rectot= MEM_mallocN(rectx*recty*sizeof(int), "rectot"); 00197 rt1= rectot; 00198 rt2= (unsigned int*)pixels + (recty-1)*rectx; 00199 /* flip y and convert to abgr */ 00200 for (y=0; y < recty; y++, rt1+= rectx, rt2-= rectx) { 00201 memcpy (rt1, rt2, rectx*sizeof(int)); 00202 00203 cp= (char *)rt1; 00204 for(x= rectx; x>0; x--) { 00205 rt= cp[0]; 00206 cp[0]= cp[3]; 00207 cp[3]= rt; 00208 rt= cp[1]; 00209 cp[1]= cp[2]; 00210 cp[2]= rt; 00211 cp+= 4; 00212 } 00213 } 00214 00215 AVI_write_frame (avi, (frame-start_frame), AVI_FORMAT_RGB32, rectot, rectx*recty*4); 00216 // printf ("added frame %3d (frame %3d in avi): ", frame, frame-start_frame); 00217 00218 return 1; 00219 } 00220 00221 static void end_avi(void) 00222 { 00223 if (avi == NULL) return; 00224 00225 AVI_close_compress (avi); 00226 MEM_freeN (avi); 00227 avi= NULL; 00228 } 00229 00230 /* similar to BKE_makepicstring() */ 00231 void BKE_makeanimstring(char *string, RenderData *rd) 00232 { 00233 bMovieHandle *mh= BKE_get_movie_handle(rd->im_format.imtype); 00234 if(mh->get_movie_path) 00235 mh->get_movie_path(string, rd); 00236 else 00237 string[0]= '\0'; 00238 }