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