Blender  V3.3
writeavi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "DNA_scene_types.h"
15 
16 #include "BLI_utildefines.h"
17 
18 #include "BKE_report.h"
19 #ifdef WITH_AVI
20 # include "BLI_blenlib.h"
21 
22 # include "BKE_main.h"
23 #endif
24 
25 #include "BKE_writeavi.h"
26 
27 /* ********************** general blender movie support ***************************** */
28 
29 static int start_stub(void *UNUSED(context_v),
30  const Scene *UNUSED(scene),
31  RenderData *UNUSED(rd),
32  int UNUSED(rectx),
33  int UNUSED(recty),
34  ReportList *UNUSED(reports),
35  bool UNUSED(preview),
36  const char *UNUSED(suffix))
37 {
38  return 0;
39 }
40 
41 static void end_stub(void *UNUSED(context_v))
42 {
43 }
44 
45 static int append_stub(void *UNUSED(context_v),
46  RenderData *UNUSED(rd),
47  int UNUSED(start_frame),
48  int UNUSED(frame),
49  int *UNUSED(pixels),
50  int UNUSED(rectx),
51  int UNUSED(recty),
52  const char *UNUSED(suffix),
53  ReportList *UNUSED(reports))
54 {
55  return 0;
56 }
57 
58 static void *context_create_stub(void)
59 {
60  return NULL;
61 }
62 
63 static void context_free_stub(void *UNUSED(context_v))
64 {
65 }
66 
67 #ifdef WITH_AVI
68 # include "AVI_avi.h"
69 
70 /* callbacks */
71 static int start_avi(void *context_v,
72  const Scene *scene,
73  RenderData *rd,
74  int rectx,
75  int recty,
76  ReportList *reports,
77  bool preview,
78  const char *suffix);
79 static void end_avi(void *context_v);
80 static int append_avi(void *context_v,
81  RenderData *rd,
82  int start_frame,
83  int frame,
84  int *pixels,
85  int rectx,
86  int recty,
87  const char *suffix,
88  ReportList *reports);
89 static void filepath_avi(char *string, const RenderData *rd, bool preview, const char *suffix);
90 static void *context_create_avi(void);
91 static void context_free_avi(void *context_v);
92 #endif /* WITH_AVI */
93 
94 #ifdef WITH_FFMPEG
95 # include "BKE_writeffmpeg.h"
96 #endif
97 
99 {
100  static bMovieHandle mh = {NULL};
101  /* stub callbacks in case none of the movie formats is supported */
102  mh.start_movie = start_stub;
104  mh.end_movie = end_stub;
105  mh.get_movie_path = NULL;
108 
109  /* set the default handle, as builtin */
110 #ifdef WITH_AVI
111  mh.start_movie = start_avi;
112  mh.append_movie = append_avi;
113  mh.end_movie = end_avi;
114  mh.get_movie_path = filepath_avi;
115  mh.context_create = context_create_avi;
116  mh.context_free = context_free_avi;
117 #endif
118 
119  /* do the platform specific handles */
120 #ifdef WITH_FFMPEG
121  if (ELEM(imtype,
126  mh.start_movie = BKE_ffmpeg_start;
127  mh.append_movie = BKE_ffmpeg_append;
128  mh.end_movie = BKE_ffmpeg_end;
129  mh.get_movie_path = BKE_ffmpeg_filepath_get;
130  mh.context_create = BKE_ffmpeg_context_create;
131  mh.context_free = BKE_ffmpeg_context_free;
132  }
133 #endif
134 
135  /* in case all above are disabled */
136  (void)imtype;
137 
138  return (mh.append_movie != append_stub) ? &mh : NULL;
139 }
140 
141 /* ****************************************************************** */
142 
143 #ifdef WITH_AVI
144 
145 static void filepath_avi(char *string, const RenderData *rd, bool preview, const char *suffix)
146 {
147  int sfra, efra;
148 
149  if (string == NULL) {
150  return;
151  }
152 
153  if (preview) {
154  sfra = rd->psfra;
155  efra = rd->pefra;
156  }
157  else {
158  sfra = rd->sfra;
159  efra = rd->efra;
160  }
161 
162  strcpy(string, rd->pic);
164 
165  BLI_make_existing_file(string);
166 
167  if (rd->scemode & R_EXTENSION) {
168  if (!BLI_path_extension_check(string, ".avi")) {
169  BLI_path_frame_range(string, sfra, efra, 4);
170  strcat(string, ".avi");
171  }
172  }
173  else {
174  if (BLI_path_frame_check_chars(string)) {
175  BLI_path_frame_range(string, sfra, efra, 4);
176  }
177  }
178 
179  BLI_path_suffix(string, FILE_MAX, suffix, "");
180 }
181 
182 static int start_avi(void *context_v,
183  const Scene *UNUSED(scene),
184  RenderData *rd,
185  int rectx,
186  int recty,
187  ReportList *reports,
188  bool preview,
189  const char *suffix)
190 {
191  int x, y;
192  char name[256];
194  int quality;
195  double framerate;
196  AviMovie *avi = context_v;
197 
198  filepath_avi(name, rd, preview, suffix);
199 
200  x = rectx;
201  y = recty;
202 
203  quality = rd->im_format.quality;
204  framerate = (double)rd->frs_sec / (double)rd->frs_sec_base;
205 
208  }
209  else {
211  }
212 
213  if (AVI_open_compress(name, avi, 1, format) != AVI_ERROR_NONE) {
214  BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file");
215  return 0;
216  }
217 
222 
223  avi->interlace = 0;
224  avi->odd_fields = 0;
225 
226  printf("Created avi: %s\n", name);
227  return 1;
228 }
229 
230 static int append_avi(void *context_v,
231  RenderData *UNUSED(rd),
232  int start_frame,
233  int frame,
234  int *pixels,
235  int rectx,
236  int recty,
237  const char *UNUSED(suffix),
238  ReportList *UNUSED(reports))
239 {
240  unsigned int *rt1, *rt2, *rectot;
241  int x, y;
242  char *cp, rt;
243  AviMovie *avi = context_v;
244 
245  if (avi == NULL) {
246  return 0;
247  }
248 
249  /* note that libavi free's the buffer... stupid interface - zr */
250  rectot = MEM_mallocN(rectx * recty * sizeof(int), "rectot");
251  rt1 = rectot;
252  rt2 = (unsigned int *)pixels + (recty - 1) * rectx;
253  /* flip y and convert to abgr */
254  for (y = 0; y < recty; y++, rt1 += rectx, rt2 -= rectx) {
255  memcpy(rt1, rt2, rectx * sizeof(int));
256 
257  cp = (char *)rt1;
258  for (x = rectx; x > 0; x--) {
259  rt = cp[0];
260  cp[0] = cp[3];
261  cp[3] = rt;
262  rt = cp[1];
263  cp[1] = cp[2];
264  cp[2] = rt;
265  cp += 4;
266  }
267  }
268 
269  AVI_write_frame(avi, (frame - start_frame), AVI_FORMAT_RGB32, rectot, rectx * recty * 4);
270  // printf("added frame %3d (frame %3d in avi): ", frame, frame-start_frame);
271 
272  return 1;
273 }
274 
275 static void end_avi(void *context_v)
276 {
277  AviMovie *avi = context_v;
278 
279  if (avi == NULL) {
280  return;
281  }
282 
283  AVI_close_compress(avi);
284 }
285 
286 static void *context_create_avi(void)
287 {
288  AviMovie *avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
289  return avi;
290 }
291 
292 static void context_free_avi(void *context_v)
293 {
294  AviMovie *avi = context_v;
295  if (avi) {
296  MEM_freeN(avi);
297  }
298 }
299 
300 #endif /* WITH_AVI */
301 
302 void BKE_movie_filepath_get(char *string, const RenderData *rd, bool preview, const char *suffix)
303 {
305  if (mh && mh->get_movie_path) {
306  mh->get_movie_path(string, rd, preview, suffix);
307  }
308  else {
309  string[0] = '\0';
310  }
311 }
@ AVI_ERROR_NONE
Definition: AVI_avi.h:186
AviError AVI_open_compress(char *name, AviMovie *movie, int streams,...)
Definition: avi.c:695
@ AVI_OPTION_HEIGHT
Definition: AVI_avi.h:200
@ AVI_OPTION_FRAMERATE
Definition: AVI_avi.h:202
@ AVI_OPTION_WIDTH
Definition: AVI_avi.h:199
@ AVI_OPTION_QUALITY
Definition: AVI_avi.h:201
AviError AVI_close_compress(AviMovie *movie)
Definition: avi.c:989
#define AVI_OPTION_TYPE_MAIN
Definition: AVI_avi.h:243
AviFormat
Definition: AVI_avi.h:144
@ AVI_FORMAT_RGB32
Definition: AVI_avi.h:148
@ AVI_FORMAT_AVI_RGB
Definition: AVI_avi.h:150
@ AVI_FORMAT_MJPEG
Definition: AVI_avi.h:152
AviError AVI_write_frame(AviMovie *movie, int frame_num,...)
Definition: avi.c:881
AviError AVI_set_compress_option(AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data)
Definition: avi_options.c:22
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:562
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
bool BLI_make_existing_file(const char *name)
Definition: path_util.c:1197
bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:853
#define FILE_MAX
bool BLI_path_extension_check(const char *str, const char *ext) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1299
bool BLI_path_frame_range(char *path, int sta, int end, int digits) ATTR_NONNULL()
Definition: path_util.c:727
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:897
bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep) ATTR_NONNULL()
Definition: path_util.c:588
#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
SyclQueue void void size_t num_bytes void
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
float frs_sec_base
struct ImageFormatData im_format
char pic[1024]
int odd_fields
Definition: AVI_avi.h:182
int interlace
Definition: AVI_avi.h:181
void(* get_movie_path)(char *string, const struct RenderData *rd, bool preview, const char *suffix)
Definition: BKE_writeavi.h:41
void(* end_movie)(void *context_v)
Definition: BKE_writeavi.h:38
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:21
void(* context_free)(void *context_v)
Definition: BKE_writeavi.h:47
void *(* context_create)(void)
Definition: BKE_writeavi.h:46
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:29
bMovieHandle * BKE_movie_handle_get(const char imtype)
Definition: writeavi.c:98
static void context_free_stub(void *UNUSED(context_v))
Definition: writeavi.c:63
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:29
static void end_stub(void *UNUSED(context_v))
Definition: writeavi.c:41
static void * context_create_stub(void)
Definition: writeavi.c:58
void BKE_movie_filepath_get(char *string, const RenderData *rd, bool preview, const char *suffix)
Definition: writeavi.c:302
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:45