├── .gitignore ├── .npmignore ├── discovery ├── ffmpeg.formats ├── full-frames-png │ ├── Makefile │ └── png2theora.c ├── full-frames │ ├── Makefile │ ├── framebyframe.c │ ├── terminals.tar.bz2 │ └── topng.js ├── html5 │ ├── full-frame-video.js │ ├── index-full-frames.html │ ├── theora-frames-full.html │ ├── theora-frames-full.js │ └── theora-frames-full │ │ ├── fragment-000.dat │ │ ├── fragment-001.dat │ │ ├── fragment-002.dat │ │ ├── fragment-003.dat │ │ ├── fragment-004.dat │ │ ├── fragment-005.dat │ │ ├── fragment-006.dat │ │ ├── fragment-007.dat │ │ ├── fragment-008.dat │ │ ├── fragment-009.dat │ │ ├── fragment-010.dat │ │ ├── fragment-011.dat │ │ ├── fragment-012.dat │ │ ├── fragment-013.dat │ │ ├── fragment-014.dat │ │ ├── fragment-015.dat │ │ ├── fragment-016.dat │ │ ├── fragment-017.dat │ │ ├── fragment-018.dat │ │ ├── fragment-019.dat │ │ ├── fragment-020.dat │ │ ├── fragment-021.dat │ │ ├── fragment-022.dat │ │ ├── fragment-023.dat │ │ ├── fragment-024.dat │ │ ├── fragment-025.dat │ │ ├── fragment-026.dat │ │ ├── fragment-027.dat │ │ ├── fragment-028.dat │ │ ├── fragment-029.dat │ │ ├── fragment-030.dat │ │ ├── fragment-031.dat │ │ ├── fragment-032.dat │ │ ├── fragment-033.dat │ │ ├── fragment-034.dat │ │ ├── fragment-035.dat │ │ ├── fragment-036.dat │ │ ├── fragment-037.dat │ │ ├── fragment-038.dat │ │ ├── fragment-039.dat │ │ ├── fragment-040.dat │ │ ├── fragment-041.dat │ │ ├── fragment-042.dat │ │ ├── fragment-043.dat │ │ ├── fragment-044.dat │ │ ├── fragment-045.dat │ │ ├── fragment-046.dat │ │ ├── fragment-047.dat │ │ ├── fragment-048.dat │ │ ├── fragment-049.dat │ │ ├── fragment-050.dat │ │ ├── fragment-051.dat │ │ ├── fragment-052.dat │ │ ├── fragment-053.dat │ │ ├── fragment-054.dat │ │ ├── fragment-055.dat │ │ ├── fragment-056.dat │ │ ├── fragment-057.dat │ │ ├── fragment-058.dat │ │ ├── fragment-059.dat │ │ ├── fragment-060.dat │ │ ├── fragment-061.dat │ │ ├── fragment-062.dat │ │ ├── fragment-063.dat │ │ ├── fragment-064.dat │ │ ├── fragment-065.dat │ │ ├── fragment-066.dat │ │ ├── fragment-067.dat │ │ ├── fragment-068.dat │ │ ├── fragment-069.dat │ │ ├── fragment-070.dat │ │ ├── fragment-071.dat │ │ ├── fragment-072.dat │ │ ├── fragment-073.dat │ │ ├── fragment-074.dat │ │ ├── fragment-075.dat │ │ ├── fragment-076.dat │ │ ├── fragment-077.dat │ │ ├── fragment-078.dat │ │ ├── fragment-079.dat │ │ ├── fragment-080.dat │ │ ├── fragment-081.dat │ │ ├── fragment-082.dat │ │ ├── fragment-083.dat │ │ ├── fragment-084.dat │ │ ├── fragment-085.dat │ │ ├── fragment-086.dat │ │ ├── fragment-087.dat │ │ ├── fragment-088.dat │ │ ├── fragment-089.dat │ │ ├── fragment-090.dat │ │ ├── fragment-091.dat │ │ ├── fragment-092.dat │ │ ├── fragment-093.dat │ │ ├── fragment-094.dat │ │ ├── fragment-095.dat │ │ ├── fragment-096.dat │ │ ├── fragment-097.dat │ │ ├── fragment-098.dat │ │ ├── fragment-099.dat │ │ ├── fragment-100.dat │ │ ├── fragment-101.dat │ │ ├── fragment-102.dat │ │ ├── fragment-103.dat │ │ ├── fragment-104.dat │ │ └── fragment-105.dat ├── rgba2yuv.c └── rgbatorgb.c ├── package.json ├── readme.md ├── src ├── async_stacked_video.cpp ├── async_stacked_video.h ├── common.cpp ├── common.h ├── fixed_video.cpp ├── fixed_video.h ├── loki │ ├── RefToValue.h │ └── ScopeGuard.h ├── module.cpp ├── stacked_video.cpp ├── stacked_video.h ├── utils.cpp ├── utils.h ├── video_encoder.cpp └── video_encoder.h ├── tests ├── full-frames │ ├── terminals.tar.bz2 │ └── tovideo.js └── stacked-frames │ ├── frames.tgz │ ├── tovideo-async.js │ └── tovideo.js └── wscript /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .lock-wscript 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | build 2 | discovery 3 | video.node 4 | terminal-* 5 | -------------------------------------------------------------------------------- /discovery/ffmpeg.formats: -------------------------------------------------------------------------------- 1 | File formats: 2 | E 3g2 3GP2 format 3 | E 3gp 3GP format 4 | D 4xm 4X Technologies format 5 | D IFF IFF format 6 | D MTV MTV format 7 | DE RoQ id RoQ format 8 | D aac ADTS AAC 9 | DE ac3 raw AC-3 10 | E adts ADTS AAC 11 | DE aiff Audio IFF 12 | DE alaw PCM A-law format 13 | DE amr 3GPP AMR file format 14 | D apc CRYO APC format 15 | D ape Monkey's Audio 16 | DE asf ASF format 17 | E asf_stream ASF format 18 | DE ass SSA/ASS format 19 | DE au SUN AU format 20 | DE avi AVI format 21 | E avm2 Flash 9 (AVM2) format 22 | D avs AVISynth 23 | D bethsoftvid Bethesda Softworks VID format 24 | D bfi Brute Force & Ignorance 25 | D c93 Interplay C93 26 | E crc CRC testing format 27 | DE daud D-Cinema audio format 28 | DE dirac raw Dirac 29 | DE dnxhd raw DNxHD (SMPTE VC-3) 30 | D dsicin Delphine Software International CIN format 31 | DE dts raw DTS 32 | DE dv DV video format 33 | E dvd MPEG-2 PS format (DVD VOB) 34 | D dxa DXA 35 | D ea Electronic Arts Multimedia Format 36 | D ea_cdata Electronic Arts cdata 37 | DE eac3 raw E-AC-3 38 | DE f32be PCM 32 bit floating-point big-endian format 39 | DE f32le PCM 32 bit floating-point little-endian format 40 | DE f64be PCM 64 bit floating-point big-endian format 41 | DE f64le PCM 64 bit floating-point little-endian format 42 | DE ffm FFM (FFserver live feed) format 43 | D film_cpk Sega FILM/CPK format 44 | DE flac raw FLAC 45 | D flic FLI/FLC/FLX animation format 46 | DE flv FLV format 47 | E framecrc framecrc testing format 48 | E gif GIF Animation 49 | D gsm GSM 50 | DE gxf GXF format 51 | DE h261 raw H.261 52 | DE h263 raw H.263 53 | DE h264 raw H.264 video format 54 | D idcin id CIN format 55 | DE image2 image2 sequence 56 | DE image2pipe piped image2 sequence 57 | D ingenient Ingenient MJPEG 58 | D ipmovie Interplay MVE format 59 | E ipod iPod H.264 MP4 format 60 | D lmlm4 lmlm4 raw format 61 | DE m4v raw MPEG-4 video format 62 | DE matroska Matroska file format 63 | DE mjpeg MJPEG video 64 | D mlp raw MLP 65 | D mm American Laser Games MM format 66 | DE mmf mmf format 67 | E mov MOV format 68 | D mov,mp4,m4a,3gp,3g2,mj2 QuickTime/MPEG-4/Motion JPEG 2000 format 69 | E mp2 MPEG audio layer 2 70 | DE mp3 MPEG audio layer 3 71 | E mp4 MP4 format 72 | D mpc Musepack 73 | D mpc8 Musepack SV8 74 | DE mpeg MPEG-1 System format 75 | E mpeg1video MPEG video 76 | E mpeg2video MPEG-2 video 77 | DE mpegts MPEG-2 transport stream format 78 | D mpegtsraw MPEG-2 raw transport stream format 79 | D mpegvideo MPEG video 80 | E mpjpeg Mime multipart JPEG format 81 | D msnwctcp MSN TCP Webcam stream 82 | DE mulaw PCM mu-law format 83 | D mvi Motion Pixels MVI format 84 | DE mxf Material eXchange Format 85 | D nsv NullSoft Video format 86 | E null null video format 87 | DE nut NUT format 88 | D nuv NuppelVideo format 89 | DE ogg Ogg 90 | D oma Sony OpenMG audio 91 | E psp PSP MP4 format 92 | D psxstr Sony Playstation STR format 93 | D pva TechnoTrend PVA file and stream format 94 | DE rawvideo raw video format 95 | E rcv VC-1 test bitstream 96 | D redir Redirector format 97 | D rl2 rl2 format 98 | DE rm RM format 99 | D rpl RPL/ARMovie format 100 | E rtp RTP output format 101 | D rtsp RTSP input format 102 | DE s16be PCM signed 16 bit big-endian format 103 | DE s16le PCM signed 16 bit little-endian format 104 | DE s24be PCM signed 24 bit big-endian format 105 | DE s24le PCM signed 24 bit little-endian format 106 | DE s32be PCM signed 32 bit big-endian format 107 | DE s32le PCM signed 32 bit little-endian format 108 | DE s8 PCM signed 8 bit format 109 | D sdp SDP 110 | D shn raw Shorten 111 | D siff Beam Software SIFF 112 | D smk Smacker video 113 | D sol Sierra SOL format 114 | E svcd MPEG-2 PS format (VOB) 115 | DE swf Flash format 116 | D thp THP 117 | D tiertexseq Tiertex Limited SEQ format 118 | D tta True Audio 119 | D txd txd format 120 | DE u16be PCM unsigned 16 bit big-endian format 121 | DE u16le PCM unsigned 16 bit little-endian format 122 | DE u24be PCM unsigned 24 bit big-endian format 123 | DE u24le PCM unsigned 24 bit little-endian format 124 | DE u32be PCM unsigned 32 bit big-endian format 125 | DE u32le PCM unsigned 32 bit little-endian format 126 | DE u8 PCM unsigned 8 bit format 127 | D vc1 raw VC-1 128 | D vc1test VC-1 test bitstream format 129 | E vcd MPEG-1 System format (VCD) 130 | D vfwcap VFW video capture 131 | D vmd Sierra VMD format 132 | E vob MPEG-2 PS format (VOB) 133 | DE voc Creative Voice file format 134 | DE wav WAV format 135 | D wc3movie Wing Commander III movie format 136 | D wsaud Westwood Studios audio format 137 | D wsvqa Westwood Studios VQA format 138 | D wv WavPack 139 | D xa Maxis XA File Format 140 | DE yuv4mpegpipe YUV4MPEG pipe format 141 | 142 | Codecs: 143 | D V 4xm 4X Movie 144 | D V D 8bps QuickTime 8BPS video 145 | D A 8svx_exp 8SVX exponential 146 | D A 8svx_fib 8SVX fibonacci 147 | D A aac Advanced Audio Coding 148 | D V D aasc Autodesk RLE 149 | DEA ac3 ATSC A/52A (AC-3) 150 | D A adpcm_4xm 4X Movie ADPCM 151 | DEA adpcm_adx SEGA CRI ADX 152 | D A adpcm_ct Creative Technology ADPCM 153 | D A adpcm_ea Electronic Arts ADPCM 154 | D A adpcm_ea_maxis_xa Electronic Arts Maxis CDROM XA ADPCM 155 | D A adpcm_ea_r1 Electronic Arts R1 ADPCM 156 | D A adpcm_ea_r2 Electronic Arts R2 ADPCM 157 | D A adpcm_ea_r3 Electronic Arts R3 ADPCM 158 | D A adpcm_ea_xas Electronic Arts XAS ADPCM 159 | D A adpcm_ima_amv IMA AMV ADPCM 160 | D A adpcm_ima_dk3 IMA Duck DK3 ADPCM 161 | D A adpcm_ima_dk4 IMA Duck DK4 ADPCM 162 | D A adpcm_ima_ea_eacs IMA Electronic Arts EACS ADPCM 163 | D A adpcm_ima_ea_sead IMA Electronic Arts SEAD ADPCM 164 | DEA adpcm_ima_qt IMA QuickTime ADPCM 165 | D A adpcm_ima_smjpeg IMA Loki SDL MJPEG ADPCM 166 | DEA adpcm_ima_wav IMA Wav ADPCM 167 | D A adpcm_ima_ws IMA Westwood ADPCM 168 | DEA adpcm_ms Microsoft ADPCM 169 | D A adpcm_sbpro_2 Sound Blaster Pro 2-bit ADPCM 170 | D A adpcm_sbpro_3 Sound Blaster Pro 2.6-bit ADPCM 171 | D A adpcm_sbpro_4 Sound Blaster Pro 4-bit ADPCM 172 | DEA adpcm_swf Shockwave Flash ADPCM 173 | D A adpcm_thp Nintendo Gamecube THP ADPCM 174 | D A adpcm_xa CDROM XA ADPCM 175 | DEA adpcm_yamaha Yamaha ADPCM 176 | DEA alac ALAC (Apple Lossless Audio Codec) 177 | D V amv AMV Video 178 | D A ape Monkey's Audio 179 | DEV D asv1 ASUS V1 180 | DEV D asv2 ASUS V2 181 | D A atrac3 Atrac 3 (Adaptive TRansform Acoustic Coding 3) 182 | D V D avs AVS (Audio Video Standard) video 183 | D V bethsoftvid Bethesda VID video 184 | D V bfi Brute Force & Ignorance 185 | DEV bmp BMP image 186 | D V D c93 Interplay C93 187 | D V D camstudio CamStudio 188 | D V D camtasia TechSmith Screen Capture Codec 189 | D V D cavs Chinese AVS video (AVS1-P2, JiZhun profile) 190 | D V D cinepak Cinepak 191 | D V D cljr Cirrus Logic AccuPak 192 | D A cook COOK 193 | D V D cyuv Creative YUV (CYUV) 194 | D A dca DCA (DTS Coherent Acoustics) 195 | DEV D dnxhd VC3/DNxHD 196 | D A dsicinaudio Delphine Software International CIN audio 197 | D V D dsicinvideo Delphine Software International CIN video 198 | DES dvbsub DVB subtitles 199 | DES dvdsub DVD subtitles 200 | DEV D dvvideo DV (Digital Video) 201 | D V dxa Feeble Files/ScummVM DXA 202 | D A eac3 ATSC A/52B (AC-3, E-AC-3) 203 | D V D eacmv Electronic Arts CMV Video 204 | D V D eatgq Electronic Arts TGQ Video 205 | D V eatgv Electronic Arts TGV Video 206 | D V D escape124 Escape 124 207 | DEV D ffv1 FFmpeg codec #1 208 | DEVSD ffvhuff Huffyuv FFmpeg variant 209 | DEA flac FLAC (Free Lossless Audio Codec) 210 | DEV D flashsv Flash Screen Video 211 | D V D flic Autodesk Animator Flic video 212 | DEVSD flv Flash Video 213 | D V D fraps Fraps 214 | DEA g726 G.726 ADPCM 215 | DEV gif GIF (Graphics Interchange Format) 216 | DEV D h261 H.261 217 | DEVSDT h263 H.263 218 | D VSD h263i H.263i 219 | EV h263p H.263+ / H.263 version 2 220 | D V D h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 221 | DEVSD huffyuv Huffyuv / HuffYUV 222 | D V D idcinvideo id Quake II CIN video 223 | D A imc IMC (Intel Music Coder) 224 | D V D indeo2 Intel Indeo 2 225 | D V indeo3 Intel Indeo 3 226 | D A interplay_dpcm Interplay DPCM 227 | D V D interplayvideo Interplay MVE Video 228 | DEV D jpegls JPEG-LS 229 | D V kmvc Karl Morton's video codec 230 | EV libdirac libdirac Dirac 2.2 231 | EA libfaac libfaac AAC (Advanced Audio Codec) 232 | D A libfaad libfaad AAC (Advanced Audio Codec) 233 | DEA libgsm libgsm GSM 234 | DEA libgsm_ms libgsm GSM Microsoft variant 235 | EA libmp3lame libmp3lame MP3 (MPEG audio layer 3) 236 | DEV libschroedinger libschroedinger Dirac 2.2 237 | D A libspeex libspeex 238 | EV libtheora libtheora Theora 239 | EA libvorbis libvorbis Vorbis 240 | EV libx264 libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 241 | EV libxvid libxvidcore MPEG-4 part 2 242 | EV ljpeg Lossless JPEG 243 | D V D loco LOCO 244 | D A mace3 MACE (Macintosh Audio Compression/Expansion) 3:1 245 | D A mace6 MACE (Macintosh Audio Compression/Expansion) 6:1 246 | D V D mdec Sony PlayStation MDEC (Motion DECoder) 247 | D V D mimic Mimic 248 | DEV D mjpeg MJPEG (Motion JPEG) 249 | D V D mjpegb Apple MJPEG-B 250 | D A mlp Meridian Lossless Packing 251 | D V D mmvideo American Laser Games MM Video 252 | D V D motionpixels Motion Pixels Video 253 | D A mp1 MP1 (MPEG audio layer 1) 254 | DEA mp2 MP2 (MPEG audio layer 2) 255 | D A mp3 MP3 (MPEG audio layer 3) 256 | D A mp3adu ADU (Application Data Unit) MP3 (MPEG audio layer 3) 257 | D A mp3on4 MP3onMP4 258 | D A mpc7 Musepack SV7 259 | D A mpc8 Musepack SV8 260 | DEVSDT mpeg1video MPEG-1 video 261 | DEVSDT mpeg2video MPEG-2 video 262 | DEVSDT mpeg4 MPEG-4 part 2 263 | D VSDT mpegvideo MPEG-1 video 264 | DEVSD msmpeg4 MPEG-4 part 2 Microsoft variant version 3 265 | DEVSD msmpeg4v1 MPEG-4 part 2 Microsoft variant version 1 266 | DEVSD msmpeg4v2 MPEG-4 part 2 Microsoft variant version 2 267 | D V D msrle Microsoft RLE 268 | D V D msvideo1 Microsoft Video 1 269 | D V D mszh LCL (LossLess Codec Library) MSZH 270 | DEA nellymoser Nellymoser Asao Codec 271 | D V D nuv NuppelVideo 272 | DEV pam PAM (Portable AnyMap) image 273 | DEV pbm PBM (Portable BitMap) image 274 | DEA pcm_alaw A-law PCM 275 | D A pcm_dvd signed 20|24-bit big-endian PCM 276 | DEA pcm_f32be 32-bit floating point big-endian PCM 277 | DEA pcm_f32le 32-bit floating point little-endian PCM 278 | DEA pcm_f64be 64-bit floating point big-endian PCM 279 | DEA pcm_f64le 64-bit floating point little-endian PCM 280 | DEA pcm_mulaw mu-law PCM 281 | DEA pcm_s16be signed 16-bit big-endian PCM 282 | DEA pcm_s16le signed 16-bit little-endian PCM 283 | D A pcm_s16le_planar 16-bit little-endian planar PCM 284 | DEA pcm_s24be signed 24-bit big-endian PCM 285 | DEA pcm_s24daud D-Cinema audio signed 24-bit PCM 286 | DEA pcm_s24le signed 24-bit little-endian PCM 287 | DEA pcm_s32be signed 32-bit big-endian PCM 288 | DEA pcm_s32le signed 32-bit little-endian PCM 289 | DEA pcm_s8 signed 8-bit PCM 290 | DEA pcm_u16be unsigned 16-bit big-endian PCM 291 | DEA pcm_u16le unsigned 16-bit little-endian PCM 292 | DEA pcm_u24be unsigned 24-bit big-endian PCM 293 | DEA pcm_u24le unsigned 24-bit little-endian PCM 294 | DEA pcm_u32be unsigned 32-bit big-endian PCM 295 | DEA pcm_u32le unsigned 32-bit little-endian PCM 296 | DEA pcm_u8 unsigned 8-bit PCM 297 | DEA pcm_zork Zork PCM 298 | D V pcx PC Paintbrush PCX image 299 | DEV pgm PGM (Portable GrayMap) image 300 | DEV pgmyuv PGMYUV (Portable GrayMap YUV) image 301 | DEV png PNG image 302 | DEV ppm PPM (Portable PixelMap) image 303 | D V ptx V.Flash PTX image 304 | D A qcelp QCELP / PureVoice 305 | D A qdm2 QDesign Music Codec 2 306 | D V D qdraw Apple QuickDraw 307 | D V D qpeg Q-team QPEG 308 | DEV D qtrle QuickTime Animation (RLE) video 309 | DEV rawvideo raw video 310 | D A real_144 RealAudio 1.0 (14.4K) 311 | D A real_288 RealAudio 2.0 (28.8K) 312 | D V D rl2 RL2 video 313 | DEA roq_dpcm id RoQ DPCM 314 | DEV D roqvideo id RoQ video 315 | D V D rpza QuickTime video (RPZA) 316 | DEV D rv10 RealVideo 1.0 317 | DEV D rv20 RealVideo 2.0 318 | D V D rv30 RealVideo 3.0 319 | D V D rv40 RealVideo 4.0 320 | DEV sgi SGI image 321 | D A shorten Shorten 322 | D A smackaud Smacker audio 323 | D V smackvid Smacker video 324 | D V D smc QuickTime Graphics (SMC) 325 | DEV snow Snow 326 | D A sol_dpcm Sol DPCM 327 | DEA sonic Sonic 328 | EA sonicls Sonic lossless 329 | D V D sp5x Sunplus JPEG (SP5X) 330 | D V sunrast Sun Rasterfile image 331 | DEV D svq1 Sorenson Vector Quantizer 1 332 | D VSD svq3 Sorenson Vector Quantizer 3 333 | DEV targa Truevision Targa image 334 | D V theora Theora 335 | D V D thp Nintendo Gamecube THP video 336 | D V D tiertexseqvideo Tiertex Limited SEQ video 337 | DEV tiff TIFF image 338 | D V D truemotion1 Duck TrueMotion 1.0 339 | D V D truemotion2 Duck TrueMotion 2.0 340 | D A truespeech DSP Group TrueSpeech 341 | D A tta True Audio 342 | D V txd Renderware TXD (TeXture Dictionary) image 343 | D V D ultimotion IBM UltiMotion 344 | D V vb Beam Software VB 345 | D V vc1 SMPTE VC-1 346 | D V D vcr1 ATI VCR1 347 | D A vmdaudio Sierra VMD audio 348 | D V D vmdvideo Sierra VMD video 349 | D V vmnc VMware Screen Codec / VMware Video 350 | DEA vorbis Vorbis 351 | D V vp3 On2 VP3 352 | D V D vp5 On2 VP5 353 | D V D vp6 On2 VP6 354 | D V D vp6a On2 VP6 (Flash version, with alpha channel) 355 | D V D vp6f On2 VP6 (Flash version) 356 | D V D vqavideo Westwood Studios VQA (Vector Quantized Animation) video 357 | D A wavpack WavPack 358 | DEA wmav1 Windows Media Audio 1 359 | DEA wmav2 Windows Media Audio 2 360 | DEVSD wmv1 Windows Media Video 7 361 | DEVSD wmv2 Windows Media Video 8 362 | D V wmv3 Windows Media Video 9 363 | D V D wnv1 Winnov WNV1 364 | D A ws_snd1 Westwood Audio (SND1) 365 | D A xan_dpcm Xan DPCM 366 | D V D xan_wc3 Wing Commander III / Xan 367 | D V D xl Miro VideoXL 368 | D S xsub XSUB 369 | DEV D zlib LCL (LossLess Codec Library) ZLIB 370 | DEV zmbv Zip Motion Blocks Video 371 | 372 | Bitstream filters: 373 | text2movsub remove_extra noise mov2textsub mp3decomp mp3comp mjpegadump imxdump h264_mp4toannexb dump_extra 374 | Supported file protocols: 375 | file: http: pipe: rtp: tcp: udp: 376 | Frame size, frame rate abbreviations: 377 | ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif 378 | 379 | Note, the names of encoders and decoders do not always match, so there are 380 | several cases where the above table shows encoder only or decoder only entries 381 | even though both encoding and decoding are supported. For example, the h263 382 | decoder corresponds to the h263 and h263p encoders, for file formats it is even 383 | worse. 384 | -------------------------------------------------------------------------------- /discovery/full-frames-png/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS+= 3 | LDFLAGS+=-lpng -logg -ltheoraenc -ltheoradec 4 | 5 | png2theora: png2theora.o 6 | $(CC) png2theora.o -o png2theora $(CFLAGS) $(LDFLAGS) 7 | 8 | -------------------------------------------------------------------------------- /discovery/full-frames-png/png2theora.c: -------------------------------------------------------------------------------- 1 | // This is a modified png2theora program that comes with libtheora. 2 | // It adds -Z flag that makes the program to output binary chunks 3 | // that make up the video (useful for testing streaming) rather than 4 | // the video itself. 5 | // The chunks get written to fragment-%03d.dat files. 6 | 7 | // Compile like this: 8 | // gcc png2theora.c -o png2theora -ltheoraenc -ltheoradec -lpng 9 | 10 | /******************************************************************** 11 | * * 12 | * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * 13 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 14 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 15 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 16 | * * 17 | * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009,2009 * 18 | * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * 19 | * * 20 | ******************************************************************** 21 | 22 | function: example encoder application; makes an Ogg Theora 23 | file from a sequence of png images 24 | last mod: $Id: png2theora.c 16503 2009-08-22 18:14:02Z giles $ 25 | based on code from Vegard Nossum 26 | 27 | ********************************************************************/ 28 | 29 | #define _FILE_OFFSET_BITS 64 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #ifdef HAVE_CONFIG_H 44 | # include 45 | #endif 46 | 47 | #include 48 | #include 49 | #include "theora/theoraenc.h" 50 | 51 | #define PROGRAM_NAME "png2theora" 52 | #define PROGRAM_VERSION "1.1-stackvm" 53 | 54 | static const char *option_output = NULL; 55 | static int video_fps_numerator = 0; 56 | static int video_fps_denominator = 0; 57 | static int video_aspect_numerator = 0; 58 | static int video_aspect_denominator = 0; 59 | static int video_rate = -1; 60 | static int video_quality = -1; 61 | ogg_uint32_t keyframe_frequency=0; 62 | int buf_delay=-1; 63 | int vp3_compatible=0; 64 | static int chroma_format = TH_PF_420; 65 | 66 | static FILE *twopass_file = NULL; 67 | static int twopass=0; 68 | static int passno; 69 | 70 | static FILE *ogg_fp = NULL; 71 | static ogg_stream_state ogg_os; 72 | static ogg_packet op; 73 | static ogg_page og; 74 | 75 | static th_enc_ctx *td; 76 | static th_info ti; 77 | 78 | static char *input_filter; 79 | 80 | static int write_fragments = 0; 81 | 82 | void write_stream_fragment(void *data, int len) { 83 | static int stream_fragment = 0; 84 | char filename[1024]; 85 | snprintf(filename, 1024, "fragment-%03d.dat", stream_fragment++); 86 | FILE *out = fopen(filename, "w+"); 87 | if (!out) { 88 | fprintf(stderr, "write_stream_fragment failed at %d\n", stream_fragment); 89 | exit(1); 90 | } 91 | fwrite(data, len, 1, out); 92 | fclose(out); 93 | } 94 | 95 | const char *optstring = "o:hv:\4:\2:V:s:S:f:F:ck:d:\1\2\3\4\5\6Z"; 96 | struct option options [] = { 97 | {"output",required_argument,NULL,'o'}, 98 | {"help",no_argument,NULL,'h'}, 99 | {"chroma-444",no_argument,NULL,'\5'}, 100 | {"chroma-422",no_argument,NULL,'\6'}, 101 | {"video-rate-target",required_argument,NULL,'V'}, 102 | {"video-quality",required_argument,NULL,'v'}, 103 | {"aspect-numerator",required_argument,NULL,'s'}, 104 | {"aspect-denominator",required_argument,NULL,'S'}, 105 | {"framerate-numerator",required_argument,NULL,'f'}, 106 | {"framerate-denominator",required_argument,NULL,'F'}, 107 | {"vp3-compatible",no_argument,NULL,'c'}, 108 | {"soft-target",no_argument,NULL,'\1'}, 109 | {"keyframe-freq",required_argument,NULL,'k'}, 110 | {"buf-delay",required_argument,NULL,'d'}, 111 | {"two-pass",no_argument,NULL,'\2'}, 112 | {"first-pass",required_argument,NULL,'\3'}, 113 | {"second-pass",required_argument,NULL,'\4'}, 114 | {"stream-fragments",no_argument,NULL,'Z'}, 115 | {NULL,0,NULL,0} 116 | }; 117 | 118 | static void usage(void){ 119 | fprintf(stderr, 120 | "%s %s\n" 121 | "Usage: %s [options] \n\n" 122 | "The input argument uses C printf format to represent a list of files,\n" 123 | " i.e. file-%%06d.png to look for files file000001.png to file9999999.png \n\n" 124 | "Options: \n\n" 125 | " -o --output file name for encoded output (required);\n" 126 | " -v --video-quality Theora quality selector fro 0 to 10\n" 127 | " (0 yields smallest files but lowest\n" 128 | " video quality. 10 yields highest\n" 129 | " fidelity but large files)\n\n" 130 | " -V --video-rate-target bitrate target for Theora video\n\n" 131 | " --soft-target Use a large reservoir and treat the rate\n" 132 | " as a soft target; rate control is less\n" 133 | " strict but resulting quality is usually\n" 134 | " higher/smoother overall. Soft target also\n" 135 | " allows an optional -v setting to specify\n" 136 | " a minimum allowed quality.\n\n" 137 | " --two-pass Compress input using two-pass rate control\n" 138 | " This option performs both passes automatically.\n\n" 139 | " --first-pass Perform first-pass of a two-pass rate\n" 140 | " controlled encoding, saving pass data to\n" 141 | " for a later second pass\n\n" 142 | " --second-pass Perform second-pass of a two-pass rate\n" 143 | " controlled encoding, reading first-pass\n" 144 | " data from . The first pass\n" 145 | " data must come from a first encoding pass\n" 146 | " using identical input video to work\n" 147 | " properly.\n\n" 148 | " -k --keyframe-freq Keyframe frequency\n" 149 | " -d --buf-delay Buffer delay (in frames). Longer delays\n" 150 | " allow smoother rate adaptation and provide\n" 151 | " better overall quality, but require more\n" 152 | " client side buffering and add latency. The\n" 153 | " default value is the keyframe interval for\n" 154 | " one-pass encoding (or somewhat larger if\n" 155 | " --soft-target is used) and infinite for\n" 156 | " two-pass encoding.\n" 157 | " --chroma-444 Use 4:4:4 chroma subsampling\n" 158 | " --chroma-422 Use 4:2:2 chroma subsampling\n" 159 | " (4:2:0 is default)\n\n" 160 | " -s --aspect-numerator Aspect ratio numerator, default is 0\n" 161 | " -S --aspect-denominator Aspect ratio denominator, default is 0\n" 162 | " -f --framerate-numerator Frame rate numerator\n" 163 | " -F --framerate-denominator Frame rate denominator\n" 164 | " The frame rate nominator divided by this\n" 165 | " determines the frame rate in units per tick\n" 166 | " -Z --stream-fragments Write out all the fragments the library\n" 167 | " generates for video\n" 168 | ,PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_NAME 169 | ); 170 | exit(0); 171 | } 172 | 173 | #ifdef WIN32 174 | int 175 | alphasort (const void *a, const void *b) 176 | { 177 | return strcoll ((*(const struct dirent **) a)->d_name, 178 | (*(const struct dirent **) b)->d_name); 179 | } 180 | 181 | int 182 | scandir (const char *dir, struct dirent ***namelist, 183 | int (*select)(const struct dirent *), int (*compar)(const void *, const void *)) 184 | { 185 | DIR *d; 186 | struct dirent *entry; 187 | register int i=0; 188 | size_t entrysize; 189 | 190 | if ((d=opendir(dir)) == NULL) 191 | return(-1); 192 | 193 | *namelist=NULL; 194 | while ((entry=readdir(d)) != NULL) 195 | { 196 | if (select == NULL || (select != NULL && (*select)(entry))) 197 | { 198 | *namelist=(struct dirent **)realloc((void *)(*namelist), 199 | (size_t)((i+1)*sizeof(struct dirent *))); 200 | if (*namelist == NULL) return(-1); 201 | entrysize=sizeof(struct dirent)-sizeof(entry->d_name)+strlen(entry->d_name)+1; 202 | (*namelist)[i]=(struct dirent *)malloc(entrysize); 203 | if ((*namelist)[i] == NULL) return(-1); 204 | memcpy((*namelist)[i], entry, entrysize); 205 | i++; 206 | } 207 | } 208 | if (closedir(d)) return(-1); 209 | if (i == 0) return(-1); 210 | if (compar != NULL) 211 | qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar); 212 | 213 | return(i); 214 | } 215 | #endif 216 | 217 | static int 218 | theora_write_frame(unsigned long w, unsigned long h, unsigned char *yuv, int last) 219 | { 220 | th_ycbcr_buffer ycbcr; 221 | ogg_packet op; 222 | ogg_page og; 223 | 224 | unsigned long yuv_w; 225 | unsigned long yuv_h; 226 | 227 | unsigned char *yuv_y; 228 | unsigned char *yuv_u; 229 | unsigned char *yuv_v; 230 | 231 | unsigned int x; 232 | unsigned int y; 233 | 234 | /* Must hold: yuv_w >= w */ 235 | yuv_w = (w + 15) & ~15; 236 | 237 | /* Must hold: yuv_h >= h */ 238 | yuv_h = (h + 15) & ~15; 239 | 240 | ycbcr[0].width = yuv_w; 241 | ycbcr[0].height = yuv_h; 242 | ycbcr[0].stride = yuv_w; 243 | ycbcr[1].width = (chroma_format == TH_PF_444) ? yuv_w : (yuv_w >> 1); 244 | ycbcr[1].stride = ycbcr[1].width; 245 | ycbcr[1].height = (chroma_format == TH_PF_420) ? (yuv_h >> 1) : yuv_h; 246 | ycbcr[2].width = ycbcr[1].width; 247 | ycbcr[2].stride = ycbcr[1].stride; 248 | ycbcr[2].height = ycbcr[1].height; 249 | 250 | ycbcr[0].data = yuv_y = malloc(ycbcr[0].stride * ycbcr[0].height); 251 | ycbcr[1].data = yuv_u = malloc(ycbcr[1].stride * ycbcr[1].height); 252 | ycbcr[2].data = yuv_v = malloc(ycbcr[2].stride * ycbcr[2].height); 253 | 254 | for(y = 0; y < h; y++) { 255 | for(x = 0; x < w; x++) { 256 | yuv_y[x + y * yuv_w] = yuv[3 * (x + y * w) + 0]; 257 | } 258 | } 259 | 260 | if (chroma_format == TH_PF_420) { 261 | for(y = 0; y < h; y += 2) { 262 | for(x = 0; x < w; x += 2) { 263 | yuv_u[(x >> 1) + (y >> 1) * (yuv_w >> 1)] = 264 | yuv[3 * (x + y * w) + 1]; 265 | yuv_v[(x >> 1) + (y >> 1) * (yuv_w >> 1)] = 266 | yuv[3 * (x + y * w) + 2]; 267 | } 268 | } 269 | } else if (chroma_format == TH_PF_444) { 270 | for(y = 0; y < h; y++) { 271 | for(x = 0; x < w; x++) { 272 | yuv_u[x + y * ycbcr[1].stride] = yuv[3 * (x + y * w) + 1]; 273 | yuv_v[x + y * ycbcr[2].stride] = yuv[3 * (x + y * w) + 2]; 274 | } 275 | } 276 | } else { /* TH_PF_422 */ 277 | for(y = 0; y < h; y += 1) { 278 | for(x = 0; x < w; x += 2) { 279 | yuv_u[(x >> 1) + y * ycbcr[1].stride] = 280 | yuv[3 * (x + y * w) + 1]; 281 | yuv_v[(x >> 1) + y * ycbcr[2].stride] = 282 | yuv[3 * (x + y * w) + 2]; 283 | } 284 | } 285 | } 286 | 287 | /* Theora is a one-frame-in,one-frame-out system; submit a frame 288 | for compression and pull out the packet */ 289 | /* in two-pass mode's second pass, we need to submit first-pass data */ 290 | if(passno==2){ 291 | int ret; 292 | for(;;){ 293 | static unsigned char buffer[80]; 294 | static int buf_pos; 295 | int bytes; 296 | /*Ask the encoder how many bytes it would like.*/ 297 | bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0); 298 | if(bytes<0){ 299 | fprintf(stderr,"Error submitting pass data in second pass.\n"); 300 | exit(1); 301 | } 302 | /*If it's got enough, stop.*/ 303 | if(bytes==0)break; 304 | /*Read in some more bytes, if necessary.*/ 305 | if(bytes>80-buf_pos)bytes=80-buf_pos; 306 | if(bytes>0&&fread(buffer+buf_pos,1,bytes,twopass_file)=bytes)buf_pos=0; 318 | /*Otherwise remember how much it used.*/ 319 | else buf_pos+=ret; 320 | } 321 | } 322 | 323 | if(th_encode_ycbcr_in(td, ycbcr)) { 324 | fprintf(stderr, "%s: error: could not encode frame\n", 325 | option_output); 326 | return 1; 327 | } 328 | 329 | /* in two-pass mode's first pass we need to extract and save the pass data */ 330 | if(passno==1){ 331 | unsigned char *buffer; 332 | int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer)); 333 | if(bytes<0){ 334 | fprintf(stderr,"Could not read two-pass data from encoder.\n"); 335 | exit(1); 336 | } 337 | if(fwrite(buffer,1,bytes,twopass_file) 255) 374 | return 255; 375 | 376 | return d; 377 | } 378 | 379 | static void 380 | rgb_to_yuv(png_bytep *png, 381 | unsigned char *yuv, 382 | unsigned int w, unsigned int h) 383 | { 384 | unsigned int x; 385 | unsigned int y; 386 | 387 | for(y = 0; y < h; y++) { 388 | for(x = 0; x < w; x++) { 389 | png_byte r; 390 | png_byte g; 391 | png_byte b; 392 | 393 | r = png[y][3 * x + 0]; 394 | g = png[y][3 * x + 1]; 395 | b = png[y][3 * x + 2]; 396 | 397 | /* XXX: Cringe. */ 398 | yuv[3 * (x + w * y) + 0] = clamp( 399 | 0.299 * r 400 | + 0.587 * g 401 | + 0.114 * b); 402 | yuv[3 * (x + w * y) + 1] = clamp((0.436 * 255 403 | - 0.14713 * r 404 | - 0.28886 * g 405 | + 0.436 * b) / 0.872); 406 | yuv[3 * (x + w * y) + 2] = clamp((0.615 * 255 407 | + 0.615 * r 408 | - 0.51499 * g 409 | - 0.10001 * b) / 1.230); 410 | } 411 | } 412 | } 413 | 414 | static int 415 | png_read(const char *pathname, unsigned int *w, unsigned int *h, unsigned char **yuv) 416 | { 417 | FILE *fp; 418 | unsigned char header[8]; 419 | png_structp png_ptr; 420 | png_infop info_ptr; 421 | png_infop end_ptr; 422 | png_bytep row_data; 423 | png_bytep *row_pointers; 424 | png_color_16p bkgd; 425 | png_uint_32 width; 426 | png_uint_32 height; 427 | int bit_depth; 428 | int color_type; 429 | int interlace_type; 430 | int compression_type; 431 | int filter_method; 432 | png_uint_32 y; 433 | 434 | fp = fopen(pathname, "rb"); 435 | if(!fp) { 436 | fprintf(stderr, "%s: error: %s\n", 437 | pathname, strerror(errno)); 438 | return 1; 439 | } 440 | 441 | fread(header, 1, 8, fp); 442 | if(png_sig_cmp(header, 0, 8)) { 443 | fprintf(stderr, "%s: error: %s\n", 444 | pathname, "not a PNG"); 445 | fclose(fp); 446 | return 1; 447 | } 448 | 449 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 450 | NULL, NULL, NULL); 451 | if(!png_ptr) { 452 | fprintf(stderr, "%s: error: %s\n", 453 | pathname, "couldn't create png read structure"); 454 | fclose(fp); 455 | return 1; 456 | } 457 | 458 | info_ptr = png_create_info_struct(png_ptr); 459 | if(!info_ptr) { 460 | fprintf(stderr, "%s: error: %s\n", 461 | pathname, "couldn't create png info structure"); 462 | png_destroy_read_struct(&png_ptr, NULL, NULL); 463 | fclose(fp); 464 | return 1; 465 | } 466 | 467 | end_ptr = png_create_info_struct(png_ptr); 468 | if(!end_ptr) { 469 | fprintf(stderr, "%s: error: %s\n", 470 | pathname, "couldn't create png info structure"); 471 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 472 | fclose(fp); 473 | return 1; 474 | } 475 | 476 | png_init_io(png_ptr, fp); 477 | png_set_sig_bytes(png_ptr, 8); 478 | png_read_info(png_ptr, info_ptr); 479 | png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 480 | &interlace_type, &compression_type, &filter_method); 481 | png_set_expand(png_ptr); 482 | if(bit_depth<8)png_set_packing(png_ptr); 483 | if(bit_depth==16)png_set_strip_16(png_ptr); 484 | if(!(color_type&PNG_COLOR_MASK_COLOR))png_set_gray_to_rgb(png_ptr); 485 | if(png_get_bKGD(png_ptr, info_ptr, &bkgd)){ 486 | png_set_background(png_ptr, bkgd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 487 | } 488 | /*Note that color_type 2 and 3 can also have alpha, despite not setting the 489 | PNG_COLOR_MASK_ALPHA bit. 490 | We always strip it to prevent libpng from overrunning our buffer.*/ 491 | png_set_strip_alpha(png_ptr); 492 | 493 | row_data = (png_bytep)png_malloc(png_ptr, 494 | 3*height*width*png_sizeof(*row_data)); 495 | row_pointers = (png_bytep *)png_malloc(png_ptr, 496 | height*png_sizeof(*row_pointers)); 497 | for(y = 0; y < height; y++) { 498 | row_pointers[y] = row_data + y*(3*width); 499 | } 500 | png_read_image(png_ptr, row_pointers); 501 | png_read_end(png_ptr, end_ptr); 502 | 503 | *w = width; 504 | *h = height; 505 | *yuv = malloc(*w * *h * 3); 506 | rgb_to_yuv(row_pointers, *yuv, *w, *h); 507 | 508 | png_free(png_ptr, row_pointers); 509 | png_free(png_ptr, row_data); 510 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr); 511 | 512 | fclose(fp); 513 | return 0; 514 | } 515 | 516 | static int include_files (const struct dirent *de) 517 | { 518 | char name[1024]; 519 | int number = -1; 520 | sscanf(de->d_name, input_filter, &number); 521 | sprintf(name, input_filter, number); 522 | return !strcmp(name, de->d_name); 523 | } 524 | 525 | static int ilog(unsigned _v){ 526 | int ret; 527 | for(ret=0;_v;ret++)_v>>=1; 528 | return ret; 529 | } 530 | 531 | int 532 | main(int argc, char *argv[]) 533 | { 534 | int c,long_option_index; 535 | int i, n; 536 | char *input_mask; 537 | char *input_directory; 538 | char *scratch; 539 | th_comment tc; 540 | struct dirent **png_files; 541 | int soft_target=0; 542 | int ret; 543 | 544 | while(1) { 545 | 546 | c=getopt_long(argc,argv,optstring,options,&long_option_index); 547 | if(c == EOF) 548 | break; 549 | 550 | switch(c) { 551 | case 'h': 552 | usage(); 553 | break; 554 | case 'o': 555 | option_output = optarg; 556 | break;; 557 | case 'v': 558 | video_quality=rint(atof(optarg)*6.3); 559 | if(video_quality<0 || video_quality>63){ 560 | fprintf(stderr,"Illegal video quality (choose 0 through 10)\n"); 561 | exit(1); 562 | } 563 | video_rate=0; 564 | break; 565 | case 'V': 566 | video_rate=rint(atof(optarg)*1000); 567 | if(video_rate<1){ 568 | fprintf(stderr,"Illegal video bitrate (choose > 0 please)\n"); 569 | exit(1); 570 | } 571 | video_quality=0; 572 | break; 573 | case '\1': 574 | soft_target=1; 575 | break; 576 | case 'c': 577 | vp3_compatible=1; 578 | break; 579 | case 'k': 580 | keyframe_frequency=rint(atof(optarg)); 581 | if(keyframe_frequency<1 || keyframe_frequency>2147483647){ 582 | fprintf(stderr,"Illegal keyframe frequency\n"); 583 | exit(1); 584 | } 585 | break; 586 | 587 | case 'd': 588 | buf_delay=atoi(optarg); 589 | if(buf_delay<=0){ 590 | fprintf(stderr,"Illegal buffer delay\n"); 591 | exit(1); 592 | } 593 | break; 594 | case 's': 595 | video_aspect_numerator=rint(atof(optarg)); 596 | break; 597 | case 'S': 598 | video_aspect_denominator=rint(atof(optarg)); 599 | break; 600 | case 'f': 601 | video_fps_numerator=rint(atof(optarg)); 602 | break; 603 | case 'F': 604 | video_fps_denominator=rint(atof(optarg)); 605 | break; 606 | case '\5': 607 | chroma_format=TH_PF_444; 608 | break; 609 | case '\6': 610 | chroma_format=TH_PF_422; 611 | break; 612 | case '\2': 613 | twopass=3; /* perform both passes */ 614 | twopass_file=tmpfile(); 615 | if(!twopass_file){ 616 | fprintf(stderr,"Unable to open temporary file for twopass data\n"); 617 | exit(1); 618 | } 619 | break; 620 | case '\3': 621 | twopass=1; /* perform first pass */ 622 | twopass_file=fopen(optarg,"wb"); 623 | if(!twopass_file){ 624 | fprintf(stderr,"Unable to open \'%s\' for twopass data\n",optarg); 625 | exit(1); 626 | } 627 | break; 628 | case '\4': 629 | twopass=2; /* perform second pass */ 630 | twopass_file=fopen(optarg,"rb"); 631 | if(!twopass_file){ 632 | fprintf(stderr,"Unable to open twopass data file \'%s\'",optarg); 633 | exit(1); 634 | } 635 | break; 636 | case 'Z': 637 | write_fragments=1; 638 | break; 639 | default: 640 | usage(); 641 | break; 642 | } 643 | } 644 | 645 | if(argc < 3) { 646 | usage(); 647 | } 648 | 649 | if(soft_target){ 650 | if(video_rate<=0){ 651 | fprintf(stderr,"Soft rate target (--soft-target) requested without a bitrate (-V).\n"); 652 | exit(1); 653 | } 654 | if(video_quality==-1) 655 | video_quality=0; 656 | }else{ 657 | if(video_rate>0) 658 | video_quality=0; 659 | if(video_quality==-1) 660 | video_quality=48; 661 | } 662 | 663 | if(keyframe_frequency<=0){ 664 | /*Use a default keyframe frequency of 64 for 1-pass (streaming) mode, and 665 | 256 for two-pass mode.*/ 666 | keyframe_frequency=twopass?256:64; 667 | } 668 | 669 | input_mask = argv[optind]; 670 | if (!input_mask) { 671 | fprintf(stderr, "no input files specified; run with -h for help.\n"); 672 | exit(1); 673 | } 674 | /* dirname and basename must operate on scratch strings */ 675 | scratch = strdup(input_mask); 676 | input_directory = strdup(dirname(scratch)); 677 | free(scratch); 678 | scratch = strdup(input_mask); 679 | input_filter = strdup(basename(scratch)); 680 | free(scratch); 681 | 682 | #ifdef DEBUG 683 | fprintf(stderr, "scanning %s with filter '%s'\n", 684 | input_directory, input_filter); 685 | #endif 686 | n = scandir (input_directory, &png_files, include_files, alphasort); 687 | 688 | if (!n) { 689 | fprintf(stderr, "no input files found; run with -h for help.\n"); 690 | exit(1); 691 | } 692 | 693 | ogg_fp = fopen(option_output, "wb"); 694 | if(!ogg_fp) { 695 | fprintf(stderr, "%s: error: %s\n", 696 | option_output, "couldn't open output file"); 697 | return 1; 698 | } 699 | 700 | srand(time(NULL)); 701 | if(ogg_stream_init(&ogg_os, rand())) { 702 | fprintf(stderr, "%s: error: %s\n", 703 | option_output, "couldn't create ogg stream state"); 704 | return 1; 705 | } 706 | 707 | for(passno=(twopass==3?1:twopass);passno<=(twopass==3?2:twopass);passno++){ 708 | unsigned int w; 709 | unsigned int h; 710 | unsigned char *yuv; 711 | char input_png[1024]; 712 | int last = 0; 713 | 714 | snprintf(input_png, 1023,"%s/%s", input_directory, png_files[0]->d_name); 715 | if(png_read(input_png, &w, &h, &yuv)) { 716 | fprintf(stderr, "could not read %s\n", input_png); 717 | exit(1); 718 | } 719 | 720 | if (passno!=2) fprintf(stderr,"%d frames, %dx%d\n",n,w,h); 721 | 722 | /* setup complete. Raw processing loop */ 723 | switch(passno){ 724 | case 0: case 2: 725 | fprintf(stderr,"\rCompressing.... \n"); 726 | break; 727 | case 1: 728 | fprintf(stderr,"\rScanning first pass.... \n"); 729 | break; 730 | } 731 | 732 | fprintf(stderr, "%s\n", input_png); 733 | 734 | th_info_init(&ti); 735 | ti.frame_width = ((w + 15) >>4)<<4; 736 | ti.frame_height = ((h + 15)>>4)<<4; 737 | ti.pic_width = w; 738 | ti.pic_height = h; 739 | ti.pic_x = 0; 740 | ti.pic_y = 0; 741 | ti.fps_numerator = video_fps_numerator; 742 | ti.fps_denominator = video_fps_denominator; 743 | ti.aspect_numerator = video_aspect_numerator; 744 | ti.aspect_denominator = video_aspect_denominator; 745 | ti.colorspace = TH_CS_UNSPECIFIED; 746 | ti.pixel_fmt = chroma_format; 747 | ti.target_bitrate = video_rate; 748 | ti.quality = video_quality; 749 | ti.keyframe_granule_shift=ilog(keyframe_frequency-1); 750 | 751 | td=th_encode_alloc(&ti); 752 | th_info_clear(&ti); 753 | /* setting just the granule shift only allows power-of-two keyframe 754 | spacing. Set the actual requested spacing. */ 755 | ret=th_encode_ctl(td,TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, 756 | &keyframe_frequency,sizeof(keyframe_frequency-1)); 757 | if(ret<0){ 758 | fprintf(stderr,"Could not set keyframe interval to %d.\n",(int)keyframe_frequency); 759 | } 760 | if(vp3_compatible){ 761 | ret=th_encode_ctl(td,TH_ENCCTL_SET_VP3_COMPATIBLE,&vp3_compatible, 762 | sizeof(vp3_compatible)); 763 | if(ret<0||!vp3_compatible){ 764 | fprintf(stderr,"Could not enable strict VP3 compatibility.\n"); 765 | if(ret>=0){ 766 | fprintf(stderr,"Ensure your source format is supported by VP3.\n"); 767 | fprintf(stderr, 768 | "(4:2:0 pixel format, width and height multiples of 16).\n"); 769 | } 770 | } 771 | } 772 | if(soft_target){ 773 | /* reverse the rate control flags to favor a 'long time' strategy */ 774 | int arg = TH_RATECTL_CAP_UNDERFLOW; 775 | ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_FLAGS,&arg,sizeof(arg)); 776 | if(ret<0) 777 | fprintf(stderr,"Could not set encoder flags for --soft-target\n"); 778 | /* Default buffer control is overridden on two-pass */ 779 | if(!twopass&&buf_delay<0){ 780 | if((keyframe_frequency*7>>1) > 5*video_fps_numerator/video_fps_denominator) 781 | arg=keyframe_frequency*7>>1; 782 | else 783 | arg=5*video_fps_numerator/video_fps_denominator; 784 | ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,&arg,sizeof(arg)); 785 | if(ret<0) 786 | fprintf(stderr,"Could not set rate control buffer for --soft-target\n"); 787 | } 788 | } 789 | /* set up two-pass if needed */ 790 | if(passno==1){ 791 | unsigned char *buffer; 792 | int bytes; 793 | bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_OUT,&buffer,sizeof(buffer)); 794 | if(bytes<0){ 795 | fprintf(stderr,"Could not set up the first pass of two-pass mode.\n"); 796 | fprintf(stderr,"Did you remember to specify an estimated bitrate?\n"); 797 | exit(1); 798 | } 799 | /*Perform a seek test to ensure we can overwrite this placeholder data at 800 | the end; this is better than letting the user sit through a whole 801 | encode only to find out their pass 1 file is useless at the end.*/ 802 | if(fseek(twopass_file,0,SEEK_SET)<0){ 803 | fprintf(stderr,"Unable to seek in two-pass data file.\n"); 804 | exit(1); 805 | } 806 | if(fwrite(buffer,1,bytes,twopass_file)=0){ 833 | ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER, 834 | &buf_delay,sizeof(buf_delay)); 835 | if(ret<0){ 836 | fprintf(stderr,"Warning: could not set desired buffer delay.\n"); 837 | } 838 | } 839 | /* write the bitstream header packets with proper page interleave */ 840 | th_comment_init(&tc); 841 | /* first packet will get its own page automatically */ 842 | if(th_encode_flushheader(td,&tc,&op)<=0){ 843 | fprintf(stderr,"Internal Theora library error.\n"); 844 | exit(1); 845 | } 846 | th_comment_clear(&tc); 847 | if(passno!=1){ 848 | ogg_stream_packetin(&ogg_os,&op); 849 | if(ogg_stream_pageout(&ogg_os,&og)!=1){ 850 | fprintf(stderr,"Internal Ogg library error.\n"); 851 | exit(1); 852 | } 853 | fwrite(og.header,1,og.header_len,ogg_fp); 854 | if (write_fragments) write_stream_fragment(og.header, og.header_len); 855 | fwrite(og.body,1,og.body_len,ogg_fp); 856 | if (write_fragments) write_stream_fragment(og.body, og.body_len); 857 | } 858 | /* create the remaining theora headers */ 859 | for(;;){ 860 | ret=th_encode_flushheader(td,&tc,&op); 861 | if(ret<0){ 862 | fprintf(stderr,"Internal Theora library error.\n"); 863 | exit(1); 864 | } 865 | else if(!ret)break; 866 | if(passno!=1)ogg_stream_packetin(&ogg_os,&op); 867 | } 868 | /* Flush the rest of our headers. This ensures 869 | the actual data in each stream will start 870 | on a new page, as per spec. */ 871 | if(passno!=1){ 872 | for(;;){ 873 | int result = ogg_stream_flush(&ogg_os,&og); 874 | if(result<0){ 875 | /* can't get here */ 876 | fprintf(stderr,"Internal Ogg library error.\n"); 877 | exit(1); 878 | } 879 | if(result==0)break; 880 | fwrite(og.header,1,og.header_len,ogg_fp); 881 | if (write_fragments) write_stream_fragment(og.header, og.header_len); 882 | fwrite(og.body,1,og.body_len,ogg_fp); 883 | if (write_fragments) write_stream_fragment(og.body, og.body_len); 884 | } 885 | } 886 | 887 | i=0; last=0; 888 | do { 889 | if(i >= n-1) last = 1; 890 | if(theora_write_frame(w, h, yuv, last)) { 891 | fprintf(stderr,"Encoding error.\n"); 892 | exit(1); 893 | } 894 | free(yuv); 895 | i++; 896 | if (!last) { 897 | snprintf(input_png, 1023,"%s/%s", input_directory, png_files[i]->d_name); 898 | if(png_read(input_png, &w, &h, &yuv)) { 899 | fprintf(stderr, "could not read %s\n", input_png); 900 | exit(1); 901 | } 902 | fprintf(stderr, "%s\n", input_png); 903 | } 904 | } while (!last); 905 | 906 | if(passno==1){ 907 | /* need to read the final (summary) packet */ 908 | unsigned char *buffer; 909 | int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer)); 910 | if(bytes<0){ 911 | fprintf(stderr,"Could not read two-pass summary data from encoder.\n"); 912 | exit(1); 913 | } 914 | if(fseek(twopass_file,0,SEEK_SET)<0){ 915 | fprintf(stderr,"Unable to seek in two-pass data file.\n"); 916 | exit(1); 917 | } 918 | if(fwrite(buffer,1,bytes,twopass_file) 2 | #include 3 | #include 4 | #include 5 | 6 | static int chroma_format = TH_PF_420; 7 | 8 | static inline unsigned char 9 | clamp(double d) 10 | { 11 | if(d < 0) return 0; 12 | if(d > 255) return 255; 13 | return d; 14 | } 15 | 16 | static void 17 | rgba_to_yuv(unsigned char *rgba, unsigned char *yuv, unsigned int w, unsigned int h) 18 | { 19 | unsigned int rgba_size = w*h*4; 20 | unsigned char r, g, b; 21 | size_t i, j; 22 | 23 | for (i=0,j=0; i= w 84 | yuv_w = (w + 15) & ~15; 85 | 86 | // Must hold: yuv_h >= h 87 | yuv_h = (h + 15) & ~15; 88 | 89 | ycbcr[0].width = yuv_w; 90 | ycbcr[0].height = yuv_h; 91 | ycbcr[0].stride = yuv_w; 92 | ycbcr[1].width = (chroma_format == TH_PF_444) ? yuv_w : (yuv_w >> 1); 93 | ycbcr[1].stride = ycbcr[1].width; 94 | ycbcr[1].height = (chroma_format == TH_PF_420) ? (yuv_h >> 1) : yuv_h; 95 | ycbcr[2].width = ycbcr[1].width; 96 | ycbcr[2].stride = ycbcr[1].stride; 97 | ycbcr[2].height = ycbcr[1].height; 98 | 99 | ycbcr[0].data = yuv_y = malloc(ycbcr[0].stride * ycbcr[0].height); 100 | ycbcr[1].data = yuv_u = malloc(ycbcr[1].stride * ycbcr[1].height); 101 | ycbcr[2].data = yuv_v = malloc(ycbcr[2].stride * ycbcr[2].height); 102 | 103 | for(y = 0; y < h; y++) { 104 | for(x = 0; x < w; x++) { 105 | yuv_y[x + y * yuv_w] = yuv[3 * (x + y * w) + 0]; 106 | } 107 | } 108 | 109 | if (chroma_format == TH_PF_420) { 110 | for(y = 0; y < h; y += 2) { 111 | for(x = 0; x < w; x += 2) { 112 | yuv_u[(x >> 1) + (y >> 1) * (yuv_w >> 1)] = 113 | yuv[3 * (x + y * w) + 1]; 114 | yuv_v[(x >> 1) + (y >> 1) * (yuv_w >> 1)] = 115 | yuv[3 * (x + y * w) + 2]; 116 | } 117 | } 118 | } else if (chroma_format == TH_PF_444) { 119 | for(y = 0; y < h; y++) { 120 | for(x = 0; x < w; x++) { 121 | yuv_u[x + y * ycbcr[1].stride] = yuv[3 * (x + y * w) + 1]; 122 | yuv_v[x + y * ycbcr[2].stride] = yuv[3 * (x + y * w) + 2]; 123 | } 124 | } 125 | } else { // TH_PF_422 126 | for(y = 0; y < h; y += 1) { 127 | for(x = 0; x < w; x += 2) { 128 | yuv_u[(x >> 1) + y * ycbcr[1].stride] = 129 | yuv[3 * (x + y * w) + 1]; 130 | yuv_v[(x >> 1) + y * ycbcr[2].stride] = 131 | yuv[3 * (x + y * w) + 2]; 132 | } 133 | } 134 | } 135 | 136 | if(th_encode_ycbcr_in(td, ycbcr)) { 137 | fprintf(stderr, "error: could not encode frame\n"); 138 | return 1; 139 | } 140 | 141 | if(!th_encode_packetout(td, last, &op)) { 142 | fprintf(stderr, "error: could not read packets\n"); 143 | return 1; 144 | } 145 | 146 | ogg_stream_packetin(ogg_os, &op); 147 | while(ogg_stream_pageout(ogg_os, &og)) { 148 | fwrite(og.header, og.header_len, 1, ogg_fp); 149 | fwrite(og.body, og.body_len, 1, ogg_fp); 150 | } 151 | 152 | free(yuv_y); 153 | free(yuv_u); 154 | free(yuv_v); 155 | 156 | free(yuv); 157 | free(rgba); 158 | fclose(terminal); 159 | 160 | return 0; 161 | } 162 | 163 | int main() { 164 | th_info ti; 165 | th_enc_ctx *td; 166 | th_comment tc; 167 | ogg_packet op; 168 | ogg_page og; 169 | ogg_stream_state ogg_os; 170 | 171 | th_info_init(&ti); 172 | ti.frame_width = ((720 + 15) >> 4) << 4; // ??? 173 | ti.frame_height = ((400 + 15) >> 4) << 4; // ??? 174 | ti.pic_width = 720; 175 | ti.pic_height = 400; 176 | ti.pic_x = 0; 177 | ti.pic_y = 0; 178 | 179 | ti.fps_numerator = 0; 180 | ti.fps_denominator = 0; 181 | ti.aspect_numerator = 0; 182 | ti.aspect_denominator = 0; 183 | ti.colorspace = TH_CS_UNSPECIFIED; 184 | ti.pixel_fmt = TH_PF_420; 185 | ti.target_bitrate = 0; 186 | ti.quality = 10; // quality from 0-63 187 | ti.keyframe_granule_shift=6; // ??? 188 | 189 | td = th_encode_alloc(&ti); 190 | th_info_clear(&ti); 191 | 192 | srand((getpid()<<16) ^ (getpid()<<8) ^ time(NULL)); 193 | 194 | FILE *ogg_fp=fopen("video.ogv", "w+"); 195 | if (!ogg_fp) { 196 | printf("failed opening video.ogv\n"); 197 | exit(1); 198 | } 199 | if (ogg_stream_init(&ogg_os, rand())) { 200 | printf("could not create ogg stream state\n"); 201 | exit(1); 202 | } 203 | 204 | th_comment_init(&tc); 205 | if (th_encode_flushheader(td, &tc, &op) <= 0) { 206 | printf("could not th_encode_flushheader\n"); 207 | exit(1); 208 | } 209 | th_comment_clear(&tc); 210 | 211 | ogg_stream_packetin(&ogg_os, &op); 212 | if (ogg_stream_pageout(&ogg_os, &og)!=1) { 213 | printf("could not ogg_stream_pageout\n"); 214 | exit(1); 215 | } 216 | fwrite(og.header,1,og.header_len,ogg_fp); 217 | fwrite(og.body,1,og.body_len,ogg_fp); 218 | 219 | for (;;) { 220 | int ret = th_encode_flushheader(td, &tc, &op); 221 | if (ret<0) { 222 | printf("could not th_encode_flushheader 2\n"); 223 | exit(1); 224 | } 225 | else if (ret == 0) break; 226 | ogg_stream_packetin(&ogg_os, &op); 227 | } 228 | 229 | for (;;) { 230 | int ret = ogg_stream_flush(&ogg_os, &og); 231 | if (ret < 0) { 232 | printf("could not ogg_stream_flush\n"); 233 | exit(1); 234 | } 235 | else if (ret == 0) break; 236 | fwrite(og.header, 1, og.header_len, ogg_fp); 237 | fwrite(og.body, 1, og.body_len, ogg_fp); 238 | } 239 | 240 | int i; 241 | for (i=0; i<=23; i++) { // 23 terminal rgba buffers 242 | printf("doing frame %02d\n", i); 243 | theora_write_frame(i, ogg_fp, &ogg_os, td, i==23); 244 | } 245 | 246 | fclose(ogg_fp); 247 | ogg_stream_clear(&ogg_os); 248 | 249 | return 0; 250 | } 251 | 252 | -------------------------------------------------------------------------------- /discovery/full-frames/terminals.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/full-frames/terminals.tar.bz2 -------------------------------------------------------------------------------- /discovery/full-frames/topng.js: -------------------------------------------------------------------------------- 1 | var Png = require('png').Png; 2 | var Buffer = require('buffer').Buffer; 3 | var fs = require('fs'); 4 | 5 | var fileRx = new RegExp(/^terminal-(\d+).rgba/); 6 | 7 | var files = fs.readdirSync('.').sort().filter( 8 | function (f) { return fileRx.test(f) } 9 | ); 10 | 11 | function baseName(fileName) { 12 | return fileName.slice(0, fileName.indexOf('.')); 13 | } 14 | 15 | var buf = new Buffer(1152000); 16 | files.forEach(function (file) { 17 | var terminal = fs.readFileSync(file, 'binary'); 18 | buf.write(terminal, 'binary'); 19 | var png = new Png(buf, 720, 400); 20 | fs.writeFileSync(baseName(file) + '.png', png.encode(), 'binary'); 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /discovery/html5/full-frame-video.js: -------------------------------------------------------------------------------- 1 | //var Video = require('video'); 2 | var http = require('http'); 3 | var fs = require('fs'); 4 | var sys = require('sys'); 5 | var Buffer = require('buffer').Buffer; 6 | 7 | var frameFiles = fs.readdirSync('./frames-full').sort(); 8 | 9 | var currFrame = 0; 10 | function nextFrame () { 11 | if (currFrame >= frameFiles.length) 12 | currFrame = 0; 13 | return frameFiles[currFrame++]; 14 | } 15 | 16 | //var video = new Video(720, 400); 17 | // video.setEncoding('video/mp4'); 18 | 19 | function getRange (rangeString) { 20 | if (rangeString) { 21 | var m = r.match(/bytes=(\d+)-(\d+)?/); 22 | if (m) return { lo: m[1], hi: m[2] }; 23 | } 24 | } 25 | 26 | http.createServer(function (req, res) { 27 | sys.log(req.url); 28 | if (req.url == '/') { 29 | res.writeHead(200, { 30 | 'Content-Type': 'text/html', 31 | }); 32 | res.write(fs.readFileSync('./index-full-frames.html')); 33 | res.end(); 34 | } 35 | else if (req.url == '/video.ogv') { 36 | sys.log(req.headers.range); 37 | res.writeHead(200, { 38 | 'Content-Type': 'video/ogg' 39 | }); 40 | var contents = fs.readFileSync('./video2.ogv', 'binary'); 41 | res.write(contents, 'binary'); 42 | res.end(); 43 | } 44 | else if (req.url == '/video.mp4') { 45 | var range = getRange(req.headers.range); 46 | 47 | if (range) { 48 | if (range.hi) { 49 | var len = range.hi-range.lo+1; 50 | var fd = fs.openSync('./video.mp4', 'r'); 51 | 52 | var contents = fs.readFileSync('./video.mp4', 'binary'); 53 | 54 | /* 55 | res.writeHead(206, { 56 | 'Content-Type': 'video/mp4', // video.getEncoding(); 57 | 'Content-Length': len, 58 | 'Content-Range': 'bytes ' + range.lo + '-' + range.hi + '/18317', 59 | 'Accept-Ranges': 'bytes' 60 | }); 61 | */ 62 | res.writeHead(206, { 63 | 'Content-Type': 'video/mp4', // video.getEncoding(); 64 | 'Content-Length': len, 65 | 'Content-Range': 'bytes ' + range.lo + '-' + range.hi + '/18317', 66 | 'Accept-Ranges': 'bytes' 67 | }); 68 | 69 | var slice = contents.slice(range.lo, parseInt(range.hi)+1); 70 | res.write(slice, 'binary'); 71 | } 72 | else { 73 | var contents = fs.readFileSync('./video.mp4', 'binary'); 74 | res.writeHead(206, { 75 | 'Content-Type': 'video/mp4', // video.getEncoding(); 76 | 'Content-Length': contents.length-range.lo, 77 | 'Accept-Ranges': 'bytes' 78 | }); 79 | res.write(contents.slice(range.lo), 'binary'); 80 | } 81 | } 82 | else { 83 | var vid = fs.readFileSync('./video.mp4', 'binary'); 84 | res.writeHead(200, { 85 | 'Content-Type': 'video/mp4', // video.getEncoding(); 86 | }); 87 | res.write(vid, 'binary'); 88 | } 89 | 90 | //for (var i=0; i<60; i++) { 91 | // res.write(video.newFrame(nextFrame()), 'binary'); 92 | // setTimeout(function(){},1000); 93 | //} 94 | 95 | res.end(); 96 | } 97 | }).listen(9000); 98 | 99 | -------------------------------------------------------------------------------- /discovery/html5/index-full-frames.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Index-full-frames test 5 | 6 | 7 | 14 |

theora video:

15 |
16 | 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Index-full-frames test 5 | 6 | 7 | 14 |

theora video:

15 |
16 | 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full.js: -------------------------------------------------------------------------------- 1 | //var Video = require('video'); 2 | var http = require('http'); 3 | var fs = require('fs'); 4 | var sys = require('sys'); 5 | var Buffer = require('buffer').Buffer; 6 | 7 | var frameFiles = fs.readdirSync('./theora-frames-full').sort(); 8 | 9 | var currFrame = 0; 10 | function nextFrame () { 11 | if (currFrame >= frameFiles.length) 12 | currFrame = 0; 13 | return frameFiles[currFrame++]; 14 | } 15 | 16 | //var video = new Video(720, 400); 17 | // video.setEncoding('video/ogg'); 18 | 19 | function getRange (rangeString) { 20 | if (rangeString) { 21 | var m = r.match(/bytes=(\d+)-(\d+)?/); 22 | if (m) return { lo: m[1], hi: m[2] }; 23 | } 24 | } 25 | 26 | http.createServer(function (req, res) { 27 | sys.log(req.url); 28 | if (req.url == '/') { 29 | res.writeHead(200, { 30 | 'Content-Type': 'text/html', 31 | }); 32 | res.write(fs.readFileSync('./theora-frames-full.html')); 33 | res.end(); 34 | } 35 | else if (req.url == '/video.ogv') { 36 | res.writeHead(200, { 37 | 'Content-Type': 'video/ogg' 38 | }); 39 | 40 | for (var i = 0; i < frameFiles.length; i++) { 41 | (function (j) { 42 | setTimeout(function () { 43 | var file = frameFiles[j]; 44 | var fileContents = fs.readFileSync('./theora-frames-full/' + file, 'binary'); 45 | res.write(fileContents, 'binary'); 46 | sys.log(file); 47 | }, 100*j); 48 | if (j == frameFiles.length-1) { 49 | setTimeout(function () { 50 | res.end(); 51 | }, 100*(j+1)); 52 | } 53 | })(i); 54 | } 55 | } 56 | }).listen(8000); 57 | 58 | -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-000.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-000.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-001.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-001.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-002.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-002.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-003.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-003.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-004.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-004.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-005.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-005.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-006.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-006.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-007.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-007.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-008.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-008.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-009.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-009.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-010.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-010.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-011.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-011.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-012.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-012.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-013.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-013.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-014.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-014.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-015.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-015.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-016.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-016.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-017.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-017.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-018.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-018.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-019.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-019.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-020.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-020.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-021.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-021.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-022.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-022.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-023.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-023.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-024.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-024.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-025.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-025.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-026.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-026.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-027.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-027.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-028.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-028.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-029.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-029.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-030.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-030.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-031.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-031.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-032.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-032.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-033.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-033.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-034.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-034.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-035.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-035.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-036.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-036.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-037.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-037.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-038.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-038.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-039.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-039.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-040.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-040.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-041.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-041.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-042.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-042.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-043.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-043.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-044.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-044.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-045.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-045.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-046.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-046.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-047.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-047.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-048.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-048.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-049.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-049.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-050.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-050.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-051.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-051.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-052.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-052.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-053.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-053.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-054.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-054.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-055.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-055.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-056.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-056.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-057.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-057.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-058.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-058.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-059.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-059.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-060.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-060.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-061.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-061.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-062.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-062.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-063.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-063.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-064.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-064.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-065.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-065.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-066.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-066.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-067.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-067.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-068.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-068.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-069.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-069.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-070.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-070.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-071.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-071.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-072.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-072.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-073.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-073.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-074.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-074.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-075.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-075.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-076.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-076.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-077.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-077.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-078.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-078.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-079.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-079.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-080.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-080.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-081.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-081.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-082.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-082.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-083.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-083.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-084.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-084.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-085.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-085.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-086.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-086.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-087.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-087.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-088.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-088.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-089.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-089.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-090.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-090.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-091.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-091.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-092.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-092.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-093.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-093.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-094.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-094.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-095.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-095.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-096.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-096.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-097.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-097.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-098.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-098.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-099.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-099.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-100.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-100.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-101.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-101.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-102.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-102.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-103.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-103.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-104.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-104.dat -------------------------------------------------------------------------------- /discovery/html5/theora-frames-full/fragment-105.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkrumins/node-video/64d077f4bf13928289c11713394364a57404b1a9/discovery/html5/theora-frames-full/fragment-105.dat -------------------------------------------------------------------------------- /discovery/rgba2yuv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* 7 | found the algo how to convert rgb to yuv 420 here: 8 | 9 | http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.directx.video/2007-09/msg00087.html 10 | */ 11 | 12 | #define rgbtoy(b, g, r, y) \ 13 | y=(unsigned char)(((int)(30*r) + (int)(59*g) + (int)(11*b))/100) 14 | 15 | #define rgbtoyuv(b, g, r, y, u, v) \ 16 | rgbtoy(b, g, r, y); \ 17 | u=(unsigned char)(((int)(-17*r) - (int)(33*g) + (int)(50*b)+12800)/100); \ 18 | v=(unsigned char)(((int)(50*r) - (int)(42*g) - (int)(8*b)+12800)/100) 19 | 20 | static void 21 | rgba_to_yuv420 ( 22 | const unsigned char * rgba, 23 | unsigned char * yuv, 24 | int srcFrameWidth, 25 | int srcFrameHeight 26 | ) { 27 | unsigned int planeSize; 28 | unsigned int halfWidth; 29 | 30 | unsigned char * yplane; 31 | unsigned char * uplane; 32 | unsigned char * vplane; 33 | const unsigned char * rgbaIndex; 34 | 35 | int x, y; 36 | unsigned char * yline; 37 | unsigned char * uline; 38 | unsigned char * vline; 39 | 40 | planeSize = srcFrameWidth * srcFrameHeight; 41 | halfWidth = srcFrameWidth >> 1; 42 | 43 | yplane = yuv; 44 | uplane = yuv + planeSize; 45 | vplane = yuv + planeSize + (planeSize >> 2); 46 | rgbaIndex = rgba; 47 | 48 | for (y = 0; y < srcFrameHeight; y++) { 49 | yline = yplane + (y * srcFrameWidth); 50 | uline = uplane + ((y >> 1) * halfWidth); 51 | vline = vplane + ((y >> 1) * halfWidth); 52 | 53 | for (x = 0; x < (int) srcFrameWidth; x+=2) 54 | { 55 | rgbtoyuv(rgbaIndex[0], rgbaIndex[1], rgbaIndex[2], *yline, *uline, *vline); 56 | rgbaIndex += 4; 57 | yline++; 58 | rgbtoyuv(rgbaIndex[0], rgbaIndex[1], rgbaIndex[2], *yline, *uline, *vline); 59 | rgbaIndex += 4; 60 | yline++; 61 | uline++; 62 | vline++; 63 | } 64 | } 65 | } 66 | 67 | static unsigned char * 68 | rgba_to_yuv(unsigned char *rgba, int rgba_size) 69 | { 70 | int yuv_size = rgba_size/4*3; 71 | unsigned char *yuv = (unsigned char *)malloc(sizeof(unsigned char)*yuv_size); 72 | if (!yuv) return NULL; 73 | int i, j; 74 | unsigned char r, g, b; 75 | unsigned int y, u, v; 76 | for (i=0,j=0;i> 16) & 0xFF; 82 | u = ((-11055*r - 21712*g + 32768*b + 8388608) >> 16) & 0xFF; 83 | v = ((32768*r - 27439*g - 5328*b + 8388608) >> 16) & 0xFF; 84 | 85 | yuv[j] = y; 86 | yuv[j+1] = u; 87 | yuv[j+2] = v; 88 | } 89 | return yuv; 90 | } 91 | 92 | int main(int argc, char **argv) { 93 | if (argc < 5) { 94 | printf("Usage: rgba2yuv \n"); 95 | exit(1); 96 | } 97 | char *inputf = argv[1]; 98 | char *outputf = argv[2]; 99 | int width = atoi(argv[3]); 100 | int height = atoi(argv[4]); 101 | 102 | FILE *input = fopen(inputf, "r"); 103 | if (!input) { 104 | printf("Could not open %s input file\n", inputf); 105 | exit(1); 106 | } 107 | FILE *output = fopen(outputf, "w+"); 108 | if (!output) { 109 | printf("Could not open %s output file\n", outputf); 110 | exit(1); 111 | } 112 | 113 | size_t rgba_size = width*height*4; 114 | size_t yuv_size = width*height*3/2; 115 | 116 | unsigned char *rgba_buf = malloc(sizeof(unsigned char)*rgba_size); 117 | if (!rgba_buf) { 118 | printf("Could not malloc mem for rgba_buf\n"); 119 | exit(1); 120 | } 121 | 122 | unsigned char *yuv_buf = malloc(sizeof(unsigned char)*yuv_size); 123 | if (!yuv_buf) { 124 | printf("Could not malloc yuv_buf\n"); 125 | exit(1); 126 | } 127 | 128 | size_t n = fread(rgba_buf, sizeof(unsigned char), rgba_size, input); 129 | if (n != rgba_size) { 130 | printf("Didn't read %d bytes (width*height*4)\n", rgba_size); 131 | exit(1); 132 | } 133 | 134 | rgba_to_yuv420(rgba_buf, yuv_buf, width, height); 135 | 136 | if (fwrite(yuv_buf, sizeof(unsigned char), yuv_size, output) != yuv_size) { 137 | printf("Failed writing file output file %s, %s\n", outputf, 138 | strerror(errno)); 139 | exit(1); 140 | } 141 | 142 | fclose(input); 143 | fclose(output); 144 | 145 | return 0; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /discovery/rgbatorgb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | rgba_to_rgb(unsigned char *rgba, unsigned char *rgb, int width, int height) 8 | { 9 | int i, j; 10 | for (i=0,j=0;i \n"); 20 | exit(1); 21 | } 22 | char *inputf = argv[1]; 23 | char *outputf = argv[2]; 24 | int width = atoi(argv[3]); 25 | int height = atoi(argv[4]); 26 | 27 | FILE *input = fopen(inputf, "r"); 28 | if (!input) { 29 | printf("Could not open %s input file\n", inputf); 30 | exit(1); 31 | } 32 | FILE *output = fopen(outputf, "w+"); 33 | if (!output) { 34 | printf("Could not open %s output file\n", outputf); 35 | exit(1); 36 | } 37 | 38 | size_t rgba_size = width*height*4; 39 | size_t rgb_size = width*height*3; 40 | 41 | unsigned char *rgba_buf = malloc(sizeof(unsigned char)*rgba_size); 42 | if (!rgba_buf) { 43 | printf("Could not malloc mem for rgba_buf\n"); 44 | exit(1); 45 | } 46 | 47 | unsigned char *rgb_buf = malloc(sizeof(unsigned char)*rgb_size); 48 | if (!rgb_buf) { 49 | printf("Could not malloc rgb_buf\n"); 50 | exit(1); 51 | } 52 | 53 | size_t n = fread(rgba_buf, sizeof(unsigned char), rgba_size, input); 54 | if (n != rgba_size) { 55 | printf("Didn't read %d bytes (width*height*4), read %d\n", rgba_size, n); 56 | exit(1); 57 | } 58 | 59 | rgba_to_rgb(rgba_buf, rgb_buf, width, height); 60 | 61 | if (fwrite(rgb_buf, sizeof(unsigned char), rgb_size, output) != rgb_size) { 62 | printf("Failed writing file output file %s, %s\n", outputf, 63 | strerror(errno)); 64 | exit(1); 65 | } 66 | 67 | free(rgba_buf); 68 | free(rgb_buf); 69 | fclose(input); 70 | fclose(output); 71 | 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "video", 3 | "version": "2.0.0", 4 | "main": "build/Release/video.node", 5 | "description": "A C++ module for node.js that creates Theora/Ogg videos from RGB frames.", 6 | "keywords": [ 7 | "video", 8 | "videos", 9 | "theora", 10 | "rgb" 11 | ], 12 | "author": { 13 | "name": "Peteris Krumins", 14 | "email": "peteris.krumins@gmail.com", 15 | "web": "http://www.catonmat.net", 16 | "twitter": "pkrumins" 17 | }, 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "http://github.com/pkrumins/node-video.git" 22 | }, 23 | "directories": { 24 | "tests": "tests" 25 | }, 26 | "engines": { 27 | "node": ">=0.1.93" 28 | }, 29 | "scripts": { 30 | "install": "node-waf configure build" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | This is a node.js module, writen in C++, that produces Theora/Ogg videos from 3 | the given RGB buffers. 4 | 5 | It was written by Peteris Krumins (peter@catonmat.net). 6 | His blog is at http://www.catonmat.net -- good coders code, great reuse. 7 | 8 | ------------------------------------------------------------------------------ 9 | 10 | This module exports several objects that you can work with: 11 | 12 | * FixedVideo - to create videos from fixed size frames 13 | * StackedVideo - to create videos from fragmented frames (stack them together) 14 | * AsyncStackedVideo - same as StackedVideo but asynchronous 15 | 16 | // these are not there yet, still hacking them in right now. 17 | // * StreamingVideo - to create streamable videos (works with HTML5