1 /***************************************************************************
2 \file ADM_vs.cpp
3 \author (C) 2015 by mean email : fixounet@free.fr
4 \brief VapourSynth demuxer
5
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "ADM_default.h"
18 #include "fourcc.h"
19 #include "ADM_vs.h"
20 #include "ADM_vsInternal.h"
21 static const VSAPI *vsapi = NULL;
22 #if 0
23 #define aprintf printf
24 #else
25 #define aprintf(...) {}
26 #endif
27 uint32_t ADM_UsecFromFps1000(uint32_t fps1000);
28 extern vsDynaLoader dynaLoader;
29 /**
30 \fn open
31 \brief open the flv file, gather infos and build index(es).
32 */
33
open(const char * name)34 uint8_t vsHeader::open(const char *name)
35 {
36 ADM_info("Opening %s as VapourSynth file\n",name);
37 inited+=!!dynaLoader.init();
38 if(!inited)
39 {
40 ADM_warning("Cannot initialize vsapi script_init. Check PYTHONPATH\n");
41 return false;
42 }
43 if(!vsapi)
44 {
45 vsapi = dynaLoader.getVSApi();
46 if(!vsapi)
47 {
48 ADM_warning("Cannot get vsAPI entry point\n");
49 close();
50 return 0;
51 }
52 }
53 ADM_info("VapourSynth init ok, opening file..\n");
54 if (dynaLoader.evaluateFile(&_script, name, 0))
55 {
56 ADM_warning("Evaluate script failed <%s>\n", dynaLoader.getError(_script));
57 close();
58 return 0;
59 }
60 _node = dynaLoader.getOutput(_script, 0);
61 if (!_node)
62 {
63 ADM_warning("vsscript_getOutputNode failed\n");
64 close();
65 return 0;
66 }
67
68 const VSVideoInfo *vi = vsapi->getVideoInfo(_node);
69 if(!vi)
70 {
71 ADM_warning("Cannot get information on node\n");
72 close();
73 return 0;
74 }
75 ADM_info("Format : %s\n",vi->format->name);
76 ADM_info("FrameRate : %d / %d\n",vi->fpsNum,vi->fpsDen);
77 ADM_info("Width : %d\n",vi->width);
78 ADM_info("Height : %d\n",vi->height);
79 ADM_info("Frames : %d\n",vi->numFrames);
80 ADM_info("Flags : 0x%x\n",vi->flags);
81
82 double fps1000;
83 if(vi->fpsDen)
84 {
85 fps1000=1000.*((double)vi->fpsNum /(double)vi-> fpsDen);
86 }else
87 {
88
89 fps1000=25000;
90 }
91 //--
92 _videostream.dwRate=vi->fpsNum;
93 _videostream.dwScale=vi-> fpsDen;
94
95 ADM_info("Fps1000=%d\n",(int)fps1000);
96
97 _mainaviheader.dwMicroSecPerFrame=ADM_UsecFromFps1000(fps1000);
98 _video_bih.biBitCount=24;
99 _videostream.dwInitialFrames= 0;
100 _videostream.dwStart= 0;
101 _video_bih.biHeight=_mainaviheader.dwHeight=vi->height ;
102 _video_bih.biWidth=_mainaviheader.dwWidth=vi->width;
103 _isvideopresent=true;
104 _isaudiopresent=false;
105 _nbFrames=vi->numFrames;
106 _videostream.dwLength=_mainaviheader.dwTotalFrames=_nbFrames;
107 _videostream.fccType=_videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t *)"YV12");
108 return true;
109 }
110 /**
111 \fn getVideoDuration
112 \brief Returns duration of video in us
113 */
getVideoDuration(void)114 uint64_t vsHeader::getVideoDuration(void)
115 {
116 uint64_t d=_mainaviheader.dwMicroSecPerFrame;
117 if(_nbFrames)
118 d+=getTimeForFrame(_nbFrames-1);
119 return d;
120 }
121 /**
122 *
123 * @param frame
124 * @param flags
125 * @return
126 */
setFlag(uint32_t frame,uint32_t flags)127 uint8_t vsHeader::setFlag(uint32_t frame,uint32_t flags)
128 {
129 return 0;
130 }
getFlags(uint32_t frame,uint32_t * flags)131 uint32_t vsHeader::getFlags(uint32_t frame,uint32_t *flags)
132 {
133 *flags=AVI_KEY_FRAME;
134 if(frame>=_mainaviheader.dwTotalFrames)
135 {
136 ADM_warning("Frame out of bounds: %u / %u\n",frame,_mainaviheader.dwTotalFrames);
137 return 0;
138 }
139 return 1;
140 }
141
142 /**
143 \fn getAudioInfo
144 \brief returns wav header for stream i (=0)
145 */
getAudioInfo(uint32_t i)146 WAVHeader *vsHeader::getAudioInfo(uint32_t i )
147 {
148 return NULL;
149 }
150 /**
151 *
152 * @param frame
153 * @return
154 */
getTime(uint32_t frame)155 uint64_t vsHeader::getTime(uint32_t frame)
156 {
157 return getTimeForFrame(frame);
158 }
159 /**
160 \fn getAudioStream
161 */
162
getAudioStream(uint32_t i,ADM_audioStream ** audio)163 uint8_t vsHeader::getAudioStream(uint32_t i,ADM_audioStream **audio)
164 {
165 *audio=NULL;
166 return 0;
167 }
168 /**
169 \fn getNbAudioStreams
170
171 */
getNbAudioStreams(void)172 uint8_t vsHeader::getNbAudioStreams(void)
173 {
174 return 0;
175 }
176 /**
177 \fn close
178 \brief cleanup
179 */
180
close(void)181 uint8_t vsHeader::close(void)
182 {
183 if(vsapi && _node)
184 {
185 vsapi->freeNode(_node);
186 _node=NULL;
187 }
188 if(_script)
189 {
190 dynaLoader.freeScript(_script);
191 _script=NULL;
192 }
193 while(inited)
194 {
195 inited--;
196 dynaLoader.finalize();
197 }
198 vsapi=NULL;
199 return 1;
200 }
201 /**
202 \fn vsHeader
203 \brief constructor
204 */
205
vsHeader(void)206 vsHeader::vsHeader( void ) : vidHeader()
207 {
208 inited=0;
209 _script=NULL;
210 _node = NULL;
211 }
212 /**
213 \fn vsHeader
214 \brief destructor
215 */
216
~vsHeader()217 vsHeader::~vsHeader( )
218 {
219 close();
220 }
221
222
223 /**
224 \fn getFrame
225 */
226
getFrame(uint32_t frame,ADMCompressedImage * img)227 uint8_t vsHeader::getFrame(uint32_t frame,ADMCompressedImage *img)
228 {
229 if(frame>=_nbFrames) return false;
230
231 char errMsg[1024];
232 const int mapp[3]={0,2,1};
233
234 const VSFrameRef *vsframe = vsapi->getFrame(frame, _node, errMsg, sizeof(errMsg));
235 if (!vsframe)
236 {
237 ADM_error("Error getting frame %d\n",frame);
238 return false;
239 }
240 img->flags=AVI_KEY_FRAME;
241 img->dataLength=(_mainaviheader.dwHeight*_mainaviheader.dwWidth*3)>>1;
242 img->demuxerPts=getTimeForFrame(frame);
243 img->demuxerDts=img->demuxerPts;
244 img->demuxerFrameNo=frame; // not sure
245 uint8_t *target=img->data;
246 #if 0
247 const VSVideoInfo *vi = vsapi->getVideoInfo(_node);
248 if(!vi)
249 {
250 ADM_error("Error getting getVideoInfo for frame %d\n",frame);
251 return false;
252 }
253 #endif
254 for (int plane = 0; plane < 3; plane++)
255 {
256 int p=mapp[plane];
257 int stride = vsapi->getStride(vsframe, p);
258 const uint8_t *readPtr = vsapi->getReadPtr(vsframe, p);
259
260 if(!readPtr)
261 {
262 ADM_error("Cannot get pointer for frame %p\n",p);
263 return false;
264 }
265
266 int rowSize = _mainaviheader.dwWidth;
267 int height = _mainaviheader.dwHeight;
268 if(p)
269 {
270 rowSize>>=1;height>>=1;
271 }
272 for (int y = 0; y < height; y++)
273 {
274
275 memcpy(target,readPtr,rowSize);
276 target += rowSize; // useless memcpy...
277 readPtr += stride;
278 }
279 }
280 vsapi->freeFrame(vsframe);
281 return true;
282 }
283 /**
284 \fn getExtraHeaderData
285 */
getExtraHeaderData(uint32_t * len,uint8_t ** data)286 uint8_t vsHeader::getExtraHeaderData(uint32_t *len, uint8_t **data)
287 {
288 *len=0;
289 *data=NULL;
290 return 1;
291 }
292 /**
293 *
294 */
Dump(void)295 void vsHeader::Dump(void)
296 {
297 return;
298 }
299 /**
300 \fn getFrameSize
301 \brief return the size of frame frame
302 */
getFrameSize(uint32_t frame,uint32_t * size)303 uint8_t vsHeader::getFrameSize (uint32_t frame, uint32_t * size)
304 {
305 *size = (_video_bih.biHeight*_video_bih.biWidth*3)>>1;
306 return 1;
307 }
308
309 /**
310 * \fn getTimeForFrame
311 * @param frame
312 * @return
313 */
getTimeForFrame(int frame)314 uint64_t vsHeader::getTimeForFrame(int frame)
315 {
316 double d=1000000.;
317 d*=(double)_videostream.dwScale;
318 d/=(double)_videostream.dwRate;
319 d*=frame;
320 return (uint64_t)d;
321 }
322 /**
323 \fn getPtsDts
324 */
getPtsDts(uint32_t frame,uint64_t * pts,uint64_t * dts)325 bool vsHeader::getPtsDts(uint32_t frame,uint64_t *pts,uint64_t *dts)
326 {
327 *dts=getTimeForFrame(frame);
328 *pts=*dts;
329 return true;
330 }
331 /**
332 \fn setPtsDts
333 */
setPtsDts(uint32_t frame,uint64_t pts,uint64_t dts)334 bool vsHeader::setPtsDts(uint32_t frame,uint64_t pts,uint64_t dts)
335 {
336 return false;
337 }
338
339 //EOF
340