Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_07_rc1 / src / modules / mod_ppm / trgt_mpg.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file trgt_mpg.cpp
3 **      \brief bsd_mpeg1 Target Module
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 **
21 ** === N O T E S ===========================================================
22 **
23 ** ========================================================================= */
24
25 /* === H E A D E R S ======================================================= */
26
27 #define SYNFIG_TARGET
28
29 #ifdef USING_PCH
30 #       include "pch.h"
31 #else
32 #ifdef HAVE_CONFIG_H
33 #       include <config.h>
34 #endif
35
36 #include <ETL/stringf>
37 #include "trgt_mpg.h"
38 #include <stdio.h>
39 #include <iostream>
40 #include <algorithm>
41 #include <functional>
42 #endif
43
44 /* === M A C R O S ========================================================= */
45
46 using namespace synfig;
47 using namespace std;
48 using namespace etl;
49
50 /* === G L O B A L S ======================================================= */
51
52 const char bsd_mpeg1::Name[]="mpeg1";
53 const char bsd_mpeg1::Ext[]="mpg";
54
55 #define tmp_dir         string("/tmp/")
56
57 /* === M E T H O D S ======================================================= */
58
59 Target *
60 bsd_mpeg1::New(const char *filename)
61 {
62         return new bsd_mpeg1(filename);
63 }
64
65 bsd_mpeg1::bsd_mpeg1(const char *Filename)
66 {
67         filename=Filename;
68         passthru=ppm::New((tmp_dir+"temp.ppm").c_str());
69         paramfile=NULL;
70
71 }
72
73 bsd_mpeg1::~bsd_mpeg1()
74 {
75         if(paramfile)
76                 fclose(paramfile);
77         delete passthru;
78         cerr<<"Encoding "<<filename<<"with \"mpeg_encode\" utility..."<<endl;
79         if(system("mpeg_encode -float-dct -realquiet /tmp/temp.param")!=0)
80         {
81                 cerr<<"Failed to encode "<<filename<<"with \"mpeg_encode\" utility"<<endl;
82                 cerr<<"Are you sure it is installed?"<<endl;
83         }
84 }
85
86 bool
87 bsd_mpeg1::set_rend_desc(RendDesc *given_desc)
88 {
89         if(paramfile)
90                 fclose(paramfile);
91
92
93         paramfile=fopen((tmp_dir+"temp.param").c_str(),"wt");
94         int bitrate=150; // kbytes per second
95         int buffer_drift=50; // bitrate drift (in kbytes per second)
96
97         bitrate*=8*1024;
98         buffer_drift*=8*1024;
99
100         fprintf(paramfile,
101                 "PATTERN                IBBPBBPBBPBBPBBP\n"
102                 "OUTPUT         %s\n"
103                 "BASE_FILE_FORMAT       PPM\n"
104                 "INPUT_CONVERT  *\n"
105                 "GOP_SIZE       16\n"
106                 "SLICES_PER_FRAME       1\n"
107                 "INPUT_DIR      \n"
108                 "PIXEL          HALF\n"
109                 "RANGE          10\n"
110                 "PSEARCH_ALG    LOGARITHMIC\n"
111                 "BSEARCH_ALG    CROSS2\n"
112 //              "IQSCALE                8\n"
113 //              "PQSCALE                10\n"
114 //              "BQSCALE                25\n"
115                 "IQSCALE                3\n"
116                 "PQSCALE                5\n"
117                 "BQSCALE                10\n"
118                 "REFERENCE_FRAME        ORIGINAL\n"
119                 "BIT_RATE  %d\n"
120 //              "BIT_RATE  1000000\n"
121 //              "BUFFER_SIZE 327680\n"
122                 "BUFFER_SIZE %d\n"
123                 ,filename.c_str(),bitrate,buffer_drift);
124          float fps=given_desc->get_frame_rate();
125
126         // Valid framerates:
127         // 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60
128
129         if(fps <24.0)
130         {
131                 fprintf(paramfile,"FRAME_RATE 23.976\n");
132                 given_desc->set_frame_rate(23.976);
133         }
134         if(fps>=24.0 && fps <25.0)
135         {
136                 fprintf(paramfile,"FRAME_RATE 24\n");
137                 given_desc->set_frame_rate(24);
138         }
139         if(fps>=25.0 && fps <29.97)
140         {
141                 fprintf(paramfile,"FRAME_RATE 25\n");
142                 given_desc->set_frame_rate(25);
143         }
144         if(fps>=29.97 && fps <30.0)
145         {
146                 fprintf(paramfile,"FRAME_RATE 29.97\n");
147                 given_desc->set_frame_rate(29.97);
148         }
149         if(fps>=29.97 && fps <30.0)
150         {
151                 fprintf(paramfile,"FRAME_RATE 29.97\n");
152                 given_desc->set_frame_rate(29.97);
153         }
154         if(fps>=30.0 && fps <50.0)
155         {
156                 fprintf(paramfile,"FRAME_RATE 30\n");
157                 given_desc->set_frame_rate(30.0);
158         }
159         if(fps>=50.0 && fps <59.94)
160         {
161                 fprintf(paramfile,"FRAME_RATE 50\n");
162                 given_desc->set_frame_rate(50);
163         }
164         if(fps>=59.94)
165         {
166                 fprintf(paramfile,"FRAME_RATE 59.94\n");
167                 given_desc->set_frame_rate(59.94);
168         }
169
170         // Make sure that the width and height
171         // are multiples of 8
172         given_desc->set_w((given_desc->get_w()+4)/8*8);
173         given_desc->set_h((given_desc->get_h()+4)/8*8);
174
175         if(!passthru->set_rend_desc(given_desc))
176                 return false;
177
178         desc=*given_desc;
179
180         fprintf(paramfile,
181                 "INPUT\n"
182                 "tmp/temp*.ppm  [%04d-%04d]\n"
183                 "END_INPUT\n",desc.get_frame_start(),desc.get_frame_end()-1);
184
185         fclose(paramfile);
186         paramfile=NULL;
187
188         return true;
189 }
190
191 void
192 bsd_mpeg1::end_frame()
193 {
194         passthru->end_frame();
195 }
196
197 bool
198 bsd_mpeg1::start_frame(synfig::ProgressCallback *callback)
199 {
200         return passthru->start_frame(callback);
201 }
202
203 unsigned char *
204 bsd_mpeg1::start_scanline(int scanline)
205 {
206         return passthru->start_scanline(scanline);
207 }
208
209 bool
210 bsd_mpeg1::end_scanline(void)
211 {
212         return passthru->end_scanline();
213 }