Blender  V2.93
writeavi.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  * Functions for writing avi-format files.
19  * Added interface for generic movie support (ton)
20  */
21 
26 #include <string.h>
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "DNA_scene_types.h"
31 
32 #include "BLI_utildefines.h"
33 
34 #include "BKE_report.h"
35 #ifdef WITH_AVI
36 # include "BLI_blenlib.h"
37 
38 # include "BKE_main.h"
39 #endif
40 
41 #include "BKE_writeavi.h"
42 
43 /* ********************** general blender movie support ***************************** */
44 
45 static int start_stub(void *UNUSED(context_v),
46  const Scene *UNUSED(scene),
47  RenderData *UNUSED(rd),
48  int UNUSED(rectx),
49  int UNUSED(recty),
50  ReportList *UNUSED(reports),
51  bool UNUSED(preview),
52  const char *UNUSED(suffix))
53 {
54  return 0;
55 }
56 
57 static void end_stub(void *UNUSED(context_v))
58 {
59 }
60 
61 static int append_stub(void *UNUSED(context_v),
62  RenderData *UNUSED(rd),
63  int UNUSED(start_frame),
64  int UNUSED(frame),
65  int *UNUSED(pixels),
66  int UNUSED(rectx),
67  int UNUSED(recty),
68  const char *UNUSED(suffix),
69  ReportList *UNUSED(reports))
70 {
71  return 0;
72 }
73 
74 static void *context_create_stub(void)
75 {
76  return NULL;
77 }
78 
79 static void context_free_stub(void *UNUSED(context_v))
80 {
81 }
82 
83 #ifdef WITH_AVI
84 # include "AVI_avi.h"
85 
86 /* callbacks */
87 static int start_avi(void *context_v,
88  const Scene *scene,
89  RenderData *rd,
90  int rectx,
91  int recty,
92  ReportList *reports,
93  bool preview,
94  const char *suffix);
95 static void end_avi(void *context_v);
96 static int append_avi(void *context_v,
97  RenderData *rd,
98  int start_frame,
99  int frame,
100  int *pixels,
101  int rectx,
102  int recty,
103  const char *suffix,
104  ReportList *reports);
105 static void filepath_avi(char *string, const RenderData *rd, bool preview, const char *suffix);
106 static void *context_create_avi(void);
107 static void context_free_avi(void *context_v);
108 #endif /* WITH_AVI */
109 
110 #ifdef WITH_FFMPEG
111 # include "BKE_writeffmpeg.h"
112 #endif
113 
115 {
116  static bMovieHandle mh = {NULL};
117  /* stub callbacks in case none of the movie formats is supported */
118  mh.start_movie = start_stub;
120  mh.end_movie = end_stub;
121  mh.get_movie_path = NULL;
124 
125  /* set the default handle, as builtin */
126 #ifdef WITH_AVI
127  mh.start_movie = start_avi;
128  mh.append_movie = append_avi;
129  mh.end_movie = end_avi;
130  mh.get_movie_path = filepath_avi;
131  mh.context_create = context_create_avi;
132  mh.context_free = context_free_avi;
133 #endif
134 
135  /* do the platform specific handles */
136 #ifdef WITH_FFMPEG
137  if (ELEM(imtype,
142  mh.start_movie = BKE_ffmpeg_start;
143  mh.append_movie = BKE_ffmpeg_append;
144  mh.end_movie = BKE_ffmpeg_end;
145  mh.get_movie_path = BKE_ffmpeg_filepath_get;
146  mh.context_create = BKE_ffmpeg_context_create;
147  mh.context_free = BKE_ffmpeg_context_free;
148  }
149 #endif
150 
151  /* in case all above are disabled */
152  (void)imtype;
153 
154  return (mh.append_movie != append_stub) ? &mh : NULL;
155 }
156 
157 /* ****************************************************************** */
158 
159 #ifdef WITH_AVI
160 
161 static void filepath_avi(char *string, const RenderData *rd, bool preview, const char *suffix)
162 {
163  int sfra, efra;
164 
165  if (string == NULL) {
166  return;
167  }
168 
169  if (preview) {
170  sfra = rd->psfra;
171  efra = rd->pefra;
172  }
173  else {
174  sfra = rd->sfra;
175  efra = rd->efra;
176  }
177 
178  strcpy(string, rd->pic);
180 
181  BLI_make_existing_file(string);
182 
183  if (rd->scemode & R_EXTENSION) {
184  if (!BLI_path_extension_check(string, ".avi")) {
185  BLI_path_frame_range(string, sfra, efra, 4);
186  strcat(string, ".avi");
187  }
188  }
189  else {
190  if (BLI_path_frame_check_chars(string)) {
191  BLI_path_frame_range(string, sfra, efra, 4);
192  }
193  }
194 
195  BLI_path_suffix(string, FILE_MAX, suffix, "");
196 }
197 
198 static int start_avi(void *context_v,
199  const Scene *UNUSED(scene),
200  RenderData *rd,
201  int rectx,
202  int recty,
203  ReportList *reports,
204  bool preview,
205  const char *suffix)
206 {
207  int x, y;
208  char name[256];
210  int quality;
211  double framerate;
212  AviMovie *avi = context_v;
213 
214  filepath_avi(name, rd, preview, suffix);
215 
216  x = rectx;
217  y = recty;
218 
219  quality = rd->im_format.quality;
220  framerate = (double)rd->frs_sec / (double)rd->frs_sec_base;
221 
224  }
225  else {
227  }
228 
229  if (AVI_open_compress(name, avi, 1, format) != AVI_ERROR_NONE) {
230  BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file");
231  return 0;
232  }
233 
238 
239  avi->interlace = 0;
240  avi->odd_fields = 0;
241 
242  printf("Created avi: %s\n", name);
243  return 1;
244 }
245 
246 static int append_avi(void *context_v,
247  RenderData *UNUSED(rd),
248  int start_frame,
249  int frame,
250  int *pixels,
251  int rectx,
252  int recty,
253  const char *UNUSED(suffix),
254  ReportList *UNUSED(reports))
255 {
256  unsigned int *rt1, *rt2, *rectot;
257  int x, y;
258  char *cp, rt;
259  AviMovie *avi = context_v;
260 
261  if (avi == NULL) {
262  return 0;
263  }
264 
265  /* note that libavi free's the buffer... stupid interface - zr */
266  rectot = MEM_mallocN(rectx * recty * sizeof(int), "rectot");
267  rt1 = rectot;
268  rt2 = (unsigned int *)pixels + (recty - 1) * rectx;
269  /* flip y and convert to abgr */
270  for (y = 0; y < recty; y++, rt1 += rectx, rt2 -= rectx) {
271  memcpy(rt1, rt2, rectx * sizeof(int));
272 
273  cp = (char *)rt1;
274  for (x = rectx; x > 0; x--) {
275  rt = cp[0];
276  cp[0] = cp[3];
277  cp[3] = rt;
278  rt = cp[1];
279  cp[1] = cp[2];
280  cp[2] = rt;
281  cp += 4;
282  }
283  }
284 
285  AVI_write_frame(avi, (frame - start_frame), AVI_FORMAT_RGB32, rectot, rectx * recty * 4);
286  // printf("added frame %3d (frame %3d in avi): ", frame, frame-start_frame);
287 
288  return 1;
289 }
290 
291 static void end_avi(void *context_v)
292 {
293  AviMovie *avi = context_v;
294 
295  if (avi == NULL) {
296  return;
297  }
298 
299  AVI_close_compress(avi);
300 }
301 
302 static void *context_create_avi(void)
303 {
304  AviMovie *avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
305  return avi;
306 }
307 
308 static void context_free_avi(void *context_v)
309 {
310  AviMovie *avi = context_v;
311  if (avi) {
312  MEM_freeN(avi);
313  }
314 }
315 
316 #endif /* WITH_AVI */
317 
318 /* similar to BKE_image_path_from_imformat() */
319 void BKE_movie_filepath_get(char *string, const RenderData *rd, bool preview, const char *suffix)
320 {
322  if (mh && mh->get_movie_path) {
323  mh->get_movie_path(string, rd, preview, suffix);
324  }
325  else {
326  string[0] = '\0';
327  }
328 }
@ AVI_ERROR_NONE
Definition: AVI_avi.h:202
AviError AVI_open_compress(char *name, AviMovie *movie, int streams,...)
Definition: avi.c:711
@ AVI_OPTION_HEIGHT
Definition: AVI_avi.h:216
@ AVI_OPTION_FRAMERATE
Definition: AVI_avi.h:218
@ AVI_OPTION_WIDTH
Definition: AVI_avi.h:215
@ AVI_OPTION_QUALITY
Definition: AVI_avi.h:217
AviError AVI_close_compress(AviMovie *movie)
Definition: avi.c:1005
#define AVI_OPTION_TYPE_MAIN
Definition: AVI_avi.h:258
AviFormat
Definition: AVI_avi.h:160
@ AVI_FORMAT_RGB32
Definition: AVI_avi.h:164
@ AVI_FORMAT_AVI_RGB
Definition: AVI_avi.h:166
@ AVI_FORMAT_MJPEG
Definition: AVI_avi.h:168
AviError AVI_write_frame(AviMovie *movie, int frame_num,...)
Definition: avi.c:897
AviError AVI_set_compress_option(AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data)
Definition: avi_options.c:38
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:439
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
bool BLI_make_existing_file(const char *name)
Definition: path_util.c:1347
#define FILE_MAX
bool BLI_path_extension_check(const char *str, const char *ext) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1459
bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL()
Definition: path_util.c:958
bool BLI_path_frame_range(char *path, int sta, int end, int digits) ATTR_NONNULL()
Definition: path_util.c:825
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep) ATTR_NONNULL()
Definition: path_util.c:669
#define UNUSED(x)
#define ELEM(...)
typedef double(DMatrix)[4][4]
#define R_IMF_IMTYPE_FFMPEG
#define R_IMF_IMTYPE_H264
#define R_EXTENSION
#define R_IMF_IMTYPE_THEORA
#define R_IMF_IMTYPE_AVIJPEG
#define R_IMF_IMTYPE_XVID
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
Scene scene
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
float frs_sec_base
struct ImageFormatData im_format
char pic[1024]
int odd_fields
Definition: AVI_avi.h:198
int interlace
Definition: AVI_avi.h:197
void(* get_movie_path)(char *string, const struct RenderData *rd, bool preview, const char *suffix)
Definition: BKE_writeavi.h:57
void(* end_movie)(void *context_v)
Definition: BKE_writeavi.h:54
int(* start_movie)(void *context_v, const struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports, bool preview, const char *suffix)
Definition: BKE_writeavi.h:37
void(* context_free)(void *context_v)
Definition: BKE_writeavi.h:63
void *(* context_create)(void)
Definition: BKE_writeavi.h:62
int(* append_movie)(void *context_v, struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, const char *suffix, struct ReportList *reports)
Definition: BKE_writeavi.h:45
bMovieHandle * BKE_movie_handle_get(const char imtype)
Definition: writeavi.c:114
static void context_free_stub(void *UNUSED(context_v))
Definition: writeavi.c:79
static int start_stub(void *UNUSED(context_v), const Scene *UNUSED(scene), RenderData *UNUSED(rd), int UNUSED(rectx), int UNUSED(recty), ReportList *UNUSED(reports), bool UNUSED(preview), const char *UNUSED(suffix))
Definition: writeavi.c:45
static void end_stub(void *UNUSED(context_v))
Definition: writeavi.c:57
static void * context_create_stub(void)
Definition: writeavi.c:74
void BKE_movie_filepath_get(char *string, const RenderData *rd, bool preview, const char *suffix)
Definition: writeavi.c:319
static int append_stub(void *UNUSED(context_v), RenderData *UNUSED(rd), int UNUSED(start_frame), int UNUSED(frame), int *UNUSED(pixels), int UNUSED(rectx), int UNUSED(recty), const char *UNUSED(suffix), ReportList *UNUSED(reports))
Definition: writeavi.c:61