Initial Stable Commit
[synfig.git] / synfig-core / trunk / src / modules / mod_ffmpeg / trgt_ffmpeg.cpp
1 /*! ========================================================================
2 ** Sinfg
3 ** ppm Target Module
4 ** $Id: trgt_ffmpeg.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
8 ** This software and associated documentation
9 ** are CONFIDENTIAL and PROPRIETARY property of
10 ** the above-mentioned copyright holder.
11 **
12 ** You may not copy, print, publish, or in any
13 ** other way distribute this software without
14 ** a prior written agreement with
15 ** the copyright holder.
16 **
17 ** === N O T E S ===========================================================
18 **
19 ** ========================================================================= */
20
21 /* === H E A D E R S ======================================================= */
22
23 #define SINFG_TARGET
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include <ETL/stringf>
33 #include "trgt_ffmpeg.h"
34 #include <stdio.h>
35 #include <algorithm>
36 #include <functional>
37 #include <ETL/clock>
38
39 #endif
40
41 /* === M A C R O S ========================================================= */
42
43 using namespace sinfg;
44 using namespace std;
45 using namespace etl;
46
47 /* === G L O B A L S ======================================================= */
48
49 SINFG_TARGET_INIT(ffmpeg_trgt);
50 SINFG_TARGET_SET_NAME(ffmpeg_trgt,"ffmpeg");
51 SINFG_TARGET_SET_EXT(ffmpeg_trgt,"mpg");
52 SINFG_TARGET_SET_VERSION(ffmpeg_trgt,"0.1");
53 SINFG_TARGET_SET_CVS_ID(ffmpeg_trgt,"$Id: trgt_ffmpeg.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $");
54
55 /* === M E T H O D S ======================================================= */
56
57 ffmpeg_trgt::ffmpeg_trgt(const char *Filename)
58 {
59         file=NULL;
60         filename=Filename;
61         multi_image=false;
62         buffer=NULL;
63         color_buffer=0;
64         set_remove_alpha();
65 }
66
67 ffmpeg_trgt::~ffmpeg_trgt()
68 {
69         if(file)
70         {
71                 etl::yield();
72                 sleep(1);
73                 pclose(file);
74         }
75         file=NULL;
76         delete [] buffer;
77         delete [] color_buffer;
78 }
79
80 bool
81 ffmpeg_trgt::set_rend_desc(RendDesc *given_desc)
82 {
83         //given_desc->set_pixel_format(PF_RGB);
84         
85         // Make sure that the width and height
86         // are multiples of 8
87         given_desc->set_w((given_desc->get_w()+4)/8*8);
88         given_desc->set_h((given_desc->get_h()+4)/8*8);
89
90         /*
91         // Valid framerates:
92         // 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60
93         float fps=given_desc->get_frame_rate();
94         if(fps <24.0)
95                 given_desc->set_frame_rate(23.976);
96         if(fps>=24.0 && fps <25.0)
97                 given_desc->set_frame_rate(24);
98         if(fps>=25.0 && fps <29.97)
99                 given_desc->set_frame_rate(25);
100         if(fps>=29.97 && fps <30.0)
101                 given_desc->set_frame_rate(29.97);
102         if(fps>=29.97 && fps <30.0)
103                 given_desc->set_frame_rate(29.97);
104         if(fps>=30.0 && fps <50.0)
105                 given_desc->set_frame_rate(30.0);
106         if(fps>=50.0 && fps <59.94)
107                 given_desc->set_frame_rate(50);
108         if(fps>=59.94)
109                 given_desc->set_frame_rate(59.94);
110     */
111         
112         desc=*given_desc;
113
114         return true;
115 }
116
117 bool
118 ffmpeg_trgt::init()
119 {
120         imagecount=desc.get_frame_start();
121         if(desc.get_frame_end()-desc.get_frame_start()>0)
122                 multi_image=true;
123         string command;
124         
125         command=strprintf("ffmpeg -f imagepipe -an -r %f -i pipe: -loop -hq -title \"%s\" -y \"%s\"\n",desc.get_frame_rate(),get_canvas()->get_name().c_str(),filename.c_str());
126         
127         file=popen(command.c_str(),"w");
128         
129         // etl::yield();
130         
131         if(!file)
132         {
133                 sinfg::error(_("Unable to open pipe to ffmpeg"));
134                 return false;
135         }
136                         
137         return true;
138 }
139
140 void
141 ffmpeg_trgt::end_frame()
142 {
143         //fprintf(file, " ");
144         fflush(file);
145         imagecount++;
146 }
147
148 bool
149 ffmpeg_trgt::start_frame(sinfg::ProgressCallback *callback)
150 {
151         int w=desc.get_w(),h=desc.get_h();
152                 
153         if(!file)
154                 return false;
155         
156         fprintf(file, "P6\n");
157         fprintf(file, "%d %d\n", w, h);
158         fprintf(file, "%d\n", 255);     
159         
160         delete [] buffer;
161         buffer=new unsigned char[3*w];
162         delete [] color_buffer;
163         color_buffer=new Color[w];
164         
165         return true;
166 }
167
168 Color *
169 ffmpeg_trgt::start_scanline(int scanline)
170 {
171         return color_buffer;
172 }
173
174 bool
175 ffmpeg_trgt::end_scanline()
176 {
177         if(!file)
178                 return false;
179                         
180         convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB, gamma());
181
182         if(!fwrite(buffer,1,desc.get_w()*3,file))
183                 return false;
184         
185         return true;
186 }