Initial Stable Commit
[synfig.git] / synfig-core / trunk / src / modules / mod_ppm / trgt_mpg.cpp
1 /*! ========================================================================
2 ** Sinfg
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 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_mpg.h"
34 #include <stdio.h>
35 #include <iostream>
36 #include <algorithm>
37 #include <functional>
38 #endif
39
40 /* === M A C R O S ========================================================= */
41
42 using namespace sinfg;
43 using namespace std;
44 using namespace etl;
45
46 /* === G L O B A L S ======================================================= */
47
48 const char bsd_mpeg1::Name[]="mpeg1";
49 const char bsd_mpeg1::Ext[]="mpg";
50
51 #define tmp_dir         string("/tmp/")
52
53 /* === M E T H O D S ======================================================= */
54
55 Target *
56 bsd_mpeg1::New(const char *filename)
57 {
58         return new bsd_mpeg1(filename);
59 }
60
61 bsd_mpeg1::bsd_mpeg1(const char *Filename)
62 {
63         filename=Filename;
64         passthru=ppm::New((tmp_dir+"temp.ppm").c_str());
65         paramfile=NULL;
66         
67 }
68
69 bsd_mpeg1::~bsd_mpeg1()
70 {
71         if(paramfile)
72                 fclose(paramfile);
73         delete passthru;
74         cerr<<"Encoding "<<filename<<"with \"mpeg_encode\" utility..."<<endl;
75         if(system("mpeg_encode -float-dct -realquiet /tmp/temp.param")!=0)
76         {
77                 cerr<<"Failed to encode "<<filename<<"with \"mpeg_encode\" utility"<<endl;
78                 cerr<<"Are you sure it is installed?"<<endl;
79         }
80 }
81
82 bool
83 bsd_mpeg1::set_rend_desc(RendDesc *given_desc)
84 {
85         if(paramfile)
86                 fclose(paramfile);              
87         
88         
89         paramfile=fopen((tmp_dir+"temp.param").c_str(),"wt");
90         int bitrate=150; // kbytes per second
91         int buffer_drift=50; // bitrate drift (in kbytes per second)
92         
93         bitrate*=8*1024;
94         buffer_drift*=8*1024;
95         
96         fprintf(paramfile,
97                 "PATTERN                IBBPBBPBBPBBPBBP\n"
98                 "OUTPUT         %s\n"
99                 "BASE_FILE_FORMAT       PPM\n"
100                 "INPUT_CONVERT  *\n"
101                 "GOP_SIZE       16\n"
102                 "SLICES_PER_FRAME       1\n"
103                 "INPUT_DIR      \n"
104                 "PIXEL          HALF\n"
105                 "RANGE          10\n"
106                 "PSEARCH_ALG    LOGARITHMIC\n"
107                 "BSEARCH_ALG    CROSS2\n"
108 //              "IQSCALE                8\n"
109 //              "PQSCALE                10\n"
110 //              "BQSCALE                25\n"
111                 "IQSCALE                3\n"
112                 "PQSCALE                5\n"
113                 "BQSCALE                10\n"
114                 "REFERENCE_FRAME        ORIGINAL\n"
115                 "BIT_RATE  %d\n"
116 //              "BIT_RATE  1000000\n"
117 //              "BUFFER_SIZE 327680\n"
118                 "BUFFER_SIZE %d\n"
119                 ,filename.c_str(),bitrate,buffer_drift);
120          float fps=given_desc->get_frame_rate();
121         
122         // Valid framerates:
123         // 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60
124                 
125         if(fps <24.0)
126         {
127                 fprintf(paramfile,"FRAME_RATE 23.976\n");
128                 given_desc->set_frame_rate(23.976);
129         }
130         if(fps>=24.0 && fps <25.0)
131         {
132                 fprintf(paramfile,"FRAME_RATE 24\n");
133                 given_desc->set_frame_rate(24);
134         }
135         if(fps>=25.0 && fps <29.97)
136         {
137                 fprintf(paramfile,"FRAME_RATE 25\n");
138                 given_desc->set_frame_rate(25);
139         }
140         if(fps>=29.97 && fps <30.0)
141         {
142                 fprintf(paramfile,"FRAME_RATE 29.97\n");
143                 given_desc->set_frame_rate(29.97);
144         }
145         if(fps>=29.97 && fps <30.0)
146         {
147                 fprintf(paramfile,"FRAME_RATE 29.97\n");
148                 given_desc->set_frame_rate(29.97);
149         }
150         if(fps>=30.0 && fps <50.0)
151         {
152                 fprintf(paramfile,"FRAME_RATE 30\n");
153                 given_desc->set_frame_rate(30.0);
154         }
155         if(fps>=50.0 && fps <59.94)
156         {
157                 fprintf(paramfile,"FRAME_RATE 50\n");
158                 given_desc->set_frame_rate(50);
159         }
160         if(fps>=59.94)
161         {
162                 fprintf(paramfile,"FRAME_RATE 59.94\n");
163                 given_desc->set_frame_rate(59.94);
164         }
165         
166         // Make sure that the width and height
167         // are multiples of 8
168         given_desc->set_w((given_desc->get_w()+4)/8*8);
169         given_desc->set_h((given_desc->get_h()+4)/8*8);
170         
171         if(!passthru->set_rend_desc(given_desc))
172                 return false;
173                 
174         desc=*given_desc;
175
176         fprintf(paramfile,
177                 "INPUT\n"
178                 "tmp/temp*.ppm  [%04d-%04d]\n"
179                 "END_INPUT\n",desc.get_frame_start(),desc.get_frame_end()-1);
180
181         fclose(paramfile);
182         paramfile=NULL;
183         
184         return true;
185 }
186
187 void
188 bsd_mpeg1::end_frame()
189 {
190         passthru->end_frame();
191 }
192
193 bool
194 bsd_mpeg1::start_frame(sinfg::ProgressCallback *callback)
195 {
196         return passthru->start_frame(callback);
197 }
198
199 unsigned char *
200 bsd_mpeg1::start_scanline(int scanline)
201 {
202         return passthru->start_scanline(scanline);
203 }
204
205 bool
206 bsd_mpeg1::end_scanline(void)
207 {
208         return passthru->end_scanline();
209 }