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