moreupdates
[synfig.git] / synfig-core / trunk / src / modules / mod_ffmpeg / mptr_ffmpeg.cpp
1 /*! ========================================================================
2 ** Synfig
3 ** ppm Target Module
4 ** $Id: mptr_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 #ifdef USING_PCH
24 #       include "pch.h"
25 #else
26 #ifdef HAVE_CONFIG_H
27 #       include <config.h>
28 #endif
29
30 #include <ETL/stringf>
31 #include "mptr_ffmpeg.h"
32 #include <stdio.h>
33 #include <iostream>
34 #include <algorithm>
35 #include <functional>
36 #include <ETL/stringf>
37 #endif
38
39 /* === M A C R O S ========================================================= */
40
41 using namespace synfig;
42 using namespace std;
43 using namespace etl;
44
45 /* === G L O B A L S ======================================================= */
46
47 SYNFIG_IMPORTER_INIT(ffmpeg_mptr);
48 SYNFIG_IMPORTER_SET_NAME(ffmpeg_mptr,"ffmpeg");
49 SYNFIG_IMPORTER_SET_EXT(ffmpeg_mptr,"avi");
50 SYNFIG_IMPORTER_SET_VERSION(ffmpeg_mptr,"0.1");
51 SYNFIG_IMPORTER_SET_CVS_ID(ffmpeg_mptr,"$Id: mptr_ffmpeg.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $");
52
53 /* === M E T H O D S ======================================================= */
54
55 bool
56 ffmpeg_mptr::seek_to(int frame)
57 {
58         if(frame<cur_frame || !file)
59         {
60                 if(file)
61                 {
62                         pclose(file);   
63                 }
64
65                 string command;
66         
67                 command=strprintf("ffmpeg -i \"%s\" -an -f ppmpipe -\n",filename.c_str());
68         
69                 file=popen(command.c_str(),"r");
70         
71                 if(!file)
72                 {
73                         cerr<<"Unable to open pipe to ffmpeg"<<endl;
74                         return false;
75                 }
76                 cur_frame=-1;
77         }
78         
79         while(cur_frame<frame-1)
80         {
81                 cerr<<"Seeking to..."<<frame<<'('<<cur_frame<<')'<<endl;
82                 if(!grab_frame())
83                         return false;
84         }
85         return true;
86 }
87
88 bool
89 ffmpeg_mptr::grab_frame(void)
90 {
91         if(!file)
92         {
93                 cerr<<"unable to open "<<filename<<endl;
94                 return false;
95         }
96         int w,h;
97         float divisor;
98         char cookie[2];
99         cookie[0]=fgetc(file);
100         cookie[1]=fgetc(file);
101         
102         if(cookie[0]!='P' || cookie[1]!='6')
103         {
104                 cerr<<"stream not in PPM format \""<<cookie[0]<<cookie[1]<<'"'<<endl;
105                 return false;
106         }
107         
108         fgetc(file);
109         fscanf(file,"%d %d\n",&w,&h);
110         fscanf(file,"%f",&divisor);
111         fgetc(file);
112                         
113         if(feof(file))
114                 return false;
115         
116         int x;
117         int y;
118         frame.set_wh(w,h);
119         for(y=0;y<frame.get_h();y++)
120                 for(x=0;x<frame.get_w();x++)
121                 {
122                         if(feof(file))
123                                 return false;
124 /*
125                         frame[y][x]=Color(
126                                 (float)(unsigned char)fgetc(file)/divisor,
127                                 (float)(unsigned char)fgetc(file)/divisor,
128                                 (float)(unsigned char)fgetc(file)/divisor,
129                                 1.0
130 */
131                         float r=gamma().r_U8_to_F32((unsigned char)fgetc(file));
132                         float g=gamma().g_U8_to_F32((unsigned char)fgetc(file));
133                         float b=gamma().b_U8_to_F32((unsigned char)fgetc(file));
134                         frame[y][x]=Color(
135                                 r,
136                                 g,
137                                 b,
138                                 1.0
139                         );
140                 }
141         cur_frame++;            
142         return true;
143 }
144
145 ffmpeg_mptr::ffmpeg_mptr(const char *f)
146 {
147 #ifdef HAVE_TERMIOS_H
148         tcgetattr (0, &oldtty);
149 #endif
150         filename=f;
151         file=NULL;
152         fps=23.98;
153         cur_frame=-1;
154 }
155
156 ffmpeg_mptr::~ffmpeg_mptr()
157 {
158         if(file)
159                 pclose(file);   
160 #ifdef HAVE_TERMIOS_H
161         tcsetattr(0,TCSANOW,&oldtty);
162 #endif
163 }
164
165 bool
166 ffmpeg_mptr::get_frame(synfig::Surface &surface,Time time, synfig::ProgressCallback *)
167 {
168         int i=(int)(time*fps);
169         if(i!=cur_frame)
170         {
171                 if(!seek_to(i))
172                         return false;
173                 if(!grab_frame());
174                         return false;
175         }
176         
177         surface=frame;
178         return false;
179 }