1. making RenderData, xrect, yrect parameters in AviCodec calls
[blender.git] / source / blender / blenkernel / intern / writeavi.c
1 /**
2  * Functions for writing avi-format files.
3  * Added interface for generic movie support (ton)
4  *
5  * $Id$
6  *
7  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version. The Blender
13  * Foundation also sells licenses for use in proprietary software under
14  * the Blender License.  See http://www.blender.org/BL/ for information
15  * about this.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27  * All rights reserved.
28  *
29  * The Original Code is: all of this file.
30  *
31  * Contributor(s): Robert Wenzlaff
32  *
33  * ***** END GPL/BL DUAL LICENSE BLOCK *****
34  * 
35  */
36
37 #include <string.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_scene_types.h"
42
43 #include "BLI_blenlib.h"
44
45 #include "BKE_global.h"
46 #include "BKE_writeavi.h"
47 #include "AVI_avi.h"
48
49
50 /* ********************** general blender movie support ***************************** */
51
52 #ifdef WITH_QUICKTIME
53 #include "quicktime_export.h"
54 #endif
55
56 #if defined(_WIN32) && !defined(FREE_WINDOWS)
57 #include "BIF_writeavicodec.h"
58 #endif
59
60 bMovieHandle *BKE_get_movie_handle(int imtype)
61 {
62         static bMovieHandle mh;
63         
64         /* set the default handle, as builtin */
65         mh.start_movie= start_avi;
66         mh.append_movie= append_avi;
67         mh.end_movie= end_avi;
68         
69         /* do the platform specific handles */
70 #ifdef __sgi
71         if (imtype == R_MOVIE) {
72                 
73         }
74 #endif
75 #if defined(_WIN32) && !defined(FREE_WINDOWS)
76         if (imtype == R_AVICODEC) {             
77                 mh.start_movie= start_avi_codec;
78                 mh.append_movie= append_avi_codec;
79                 mh.end_movie= end_avi_codec;
80         }
81 #endif
82 #ifdef WITH_QUICKTIME
83         if (imtype == R_QUICKTIME) {
84                 mh.start_movie= start_qt;
85                 mh.append_movie= append_qt;
86                 mh.end_movie= end_qt;
87         }
88 #endif
89         
90         return &mh;
91 }
92
93 /* ****************************************************************** */
94
95
96 static AviMovie *avi=NULL;
97 static int sframe;
98
99 void makeavistring (RenderData *rd, char *string) 
100 {
101         char txt[64];
102
103         if (string==0) return;
104
105         strcpy(string, rd->pic);
106         BLI_convertstringcode(string, G.sce, rd->cfra);
107
108         BLI_make_existing_file(string);
109
110         if (BLI_strcasecmp(string + strlen(string) - 4, ".avi")) {
111                 sprintf(txt, "%04d_%04d.avi", (rd->sfra) , (rd->efra) );
112                 strcat(string, txt);
113         }
114 }
115
116 void start_avi(RenderData *rd, int rectx, int recty)
117 {
118         int x, y;
119         char name[256];
120         AviFormat format;
121         int quality, framerate;
122         
123         makeavistring(rd, name);
124
125         sframe = (rd->sfra);
126         x = rectx;
127         y = recty;
128
129         quality= rd->quality;
130         framerate= rd->frs_sec;
131         
132         avi = MEM_mallocN (sizeof(AviMovie), "avimovie");
133
134         /* RPW 11-21-2002 
135          if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB;
136         */
137         if (rd->imtype != R_AVIJPEG ) format = AVI_FORMAT_AVI_RGB;
138         else format = AVI_FORMAT_MJPEG;
139
140         if (AVI_open_compress (name, avi, 1, format) != AVI_ERROR_NONE) {
141                 printf("cannot open or start AVI movie file");
142                 MEM_freeN (avi);
143                 avi = NULL;
144                 return;
145         }
146                         
147         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x);
148         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &y);
149         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &quality);           
150         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &framerate);
151
152         avi->interlace= 0;
153         avi->odd_fields= 0;
154 /*      avi->interlace= rd->mode & R_FIELDS; */
155 /*      avi->odd_fields= (rd->mode & R_ODDFIELD)?1:0; */
156         
157         printf("Created avi: %s\n", name);
158 }
159
160 void append_avi(int frame, int *pixels, int rectx, int recty)
161 {
162         unsigned int *rt1, *rt2, *rectot;
163         int x, y;
164         char *cp, rt;
165         
166         if (avi == NULL) {
167                 G.afbreek = 1;
168                 return;
169         }
170
171         /* note that libavi free's the buffer... stupid interface - zr */
172         rectot= MEM_mallocN(rectx*recty*sizeof(int), "rectot");
173         rt1= rectot;
174         rt2= pixels + (recty-1)*rectx;
175         /* flip y and convert to abgr */
176         for (y=0; y < recty; y++, rt1+= rectx, rt2-= rectx) {
177                 memcpy (rt1, rt2, rectx*sizeof(int));
178                 
179                 cp= (char *)rt1;
180                 for(x= rectx; x>0; x--) {
181                         rt= cp[0];
182                         cp[0]= cp[3];
183                         cp[3]= rt;
184                         rt= cp[1];
185                         cp[1]= cp[2];
186                         cp[2]= rt;
187                         cp+= 4;
188                 }
189         }
190         
191         AVI_write_frame (avi, (frame-sframe), AVI_FORMAT_RGB32, rectot, rectx*recty*4);
192 //      printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe);
193 }
194
195 void end_avi(void)
196 {
197         if (avi == NULL) return;
198
199         AVI_close_compress (avi);
200         MEM_freeN (avi);
201         avi= NULL;
202 }