10 #define FLAG_FRAMERATE 4
11 #define FLAG_FULLRANGE 8
13 #define FLAG_ITU709 16
14 #define FLAG_SMPTE240M 32
15 #define FLAG_CS_MASK 48
18 //Heh, this happens to be exact hardware capacity of 1.44MB 90mm floppy. :-)
19 unsigned char yuv_buffer
[1474560];
22 uint32_t ymatrix
[0x80000];
23 uint32_t cbmatrix
[0x80000];
24 uint32_t crmatrix
[0x80000];
27 #define TOYUV(src, idx) do {\
28 uint32_t c = (static_cast<uint32_t>(src[(idx) + 0]) << 24) |\
29 (static_cast<uint32_t>(src[(idx) + 1]) << 16) |\
30 (static_cast<uint32_t>(src[(idx) + 2]) << 8) |\
31 static_cast<uint32_t>(src[(idx) + 3]);\
32 Y += ymatrix[c & 0x7FFFF];\
33 Cb += cbmatrix[c & 0x7FFFF];\
34 Cr += crmatrix[c & 0x7FFFF];\
37 #define STORE16(buffer,idx,shift,psep,v1,v2,v3)\
38 buffer[(idx)] = (v1 >> ((shift) + 8));\
39 buffer[(idx) + 1] = (v1 >> (shift));\
40 buffer[(idx) + (psep)] = (v2 >> ((shift) + 8));\
41 buffer[(idx) + 1 + (psep)] = (v2 >> (shift));\
42 buffer[(idx) + 2 * (psep)] = (v3 >> ((shift) + 8));\
43 buffer[(idx) + 1 + 2 * (psep)] = (v3 >> (shift));
45 #define STORE8(buffer,idx,shift,psep,v1,v2,v3)\
46 buffer[(idx)] = (v1 >> ((shift) + 8));\
47 buffer[(idx) + (psep)] = (v2 >> ((shift) + 8));\
48 buffer[(idx) + 2 * (psep)] = (v3 >> ((shift) + 8);\
50 template<unsigned shift>
53 static const size_t esize
= 2;
54 static void store(unsigned char* buffer
, size_t idx
, size_t psep
, uint32_t v1
, uint32_t v2
,
57 *reinterpret_cast<uint16_t*>(buffer
+ idx
) = (v1
>> shift
);
58 *reinterpret_cast<uint16_t*>(buffer
+ idx
+ psep
) = (v2
>> shift
);
59 *reinterpret_cast<uint16_t*>(buffer
+ idx
+ 2 * psep
) = (v3
>> shift
);
63 template<unsigned shift
>
66 static const size_t esize
= 1;
67 static void store(unsigned char* buffer
, size_t idx
, size_t psep
, uint32_t v1
, uint32_t v2
,
70 buffer
[idx
] = (v1
>> (shift
+ 8));
71 buffer
[idx
+ psep
] = (v2
>> (shift
+ 8));
72 buffer
[idx
+ 2 * psep
] = (v3
>> (shift
+ 8));
79 static const size_t esize
= T::esize
;
80 static void store(unsigned char* buffer
, size_t idx
, size_t psep
, uint32_t v1
, uint32_t v2
,
83 T::store(buffer
, idx
, psep
, v1
, v2
, v3
);
90 static const size_t esize
= 2 * T::esize
;
91 static void store(unsigned char* buffer
, size_t idx
, size_t psep
, uint32_t v1
, uint32_t v2
,
94 T::store(buffer
, idx
, psep
, v1
, v2
, v3
);
95 T::store(buffer
, idx
+ T::esize
, psep
, v1
, v2
, v3
);
99 template<typename T
, size_t llen
>
102 static const size_t esize
= T::esize
;
103 static void store(unsigned char* buffer
, size_t idx
, size_t psep
, uint32_t v1
, uint32_t v2
,
106 T::store(buffer
, idx
, psep
, v1
, v2
, v3
);
107 T::store(buffer
, idx
+ T::esize
* llen
, psep
, v1
, v2
, v3
);
111 template<typename T
, size_t llen
>
114 static const size_t esize
= 2 * T::esize
;
115 static void store(unsigned char* buffer
, size_t idx
, size_t psep
, uint32_t v1
, uint32_t v2
,
118 T::store(buffer
, idx
, psep
, v1
, v2
, v3
);
119 T::store(buffer
, idx
+ T::esize
, psep
, v1
, v2
, v3
);
120 T::store(buffer
, idx
+ 2 * T::esize
* llen
, psep
, v1
, v2
, v3
);
121 T::store(buffer
, idx
+ 2 * T::esize
* llen
+ T::esize
, psep
, v1
, v2
, v3
);
128 static const size_t isize
= 4;
129 static const size_t esize
= 2 * T::esize
;
130 static void convert(unsigned char* obuffer
, size_t oidx
, size_t psep
, const unsigned char* ibuffer
,
136 TOYUV(ibuffer
, iidx
);
137 T::store(obuffer
, oidx
, psep
, Y
, Cb
, Cr
);
141 template<typename T
, size_t s
>
142 struct convert_x_helper
144 static void convert(unsigned char* obuffer
, size_t oidx
, size_t psep
, const unsigned char* ibuffer
,
150 TOYUV(ibuffer
, iidx
);
151 TOYUV(ibuffer
, iidx
+ s
);
152 T::store(obuffer
, oidx
, psep
, Y
, Cb
, Cr
);
159 static const size_t isize
= 8;
160 static const size_t esize
= T::esize
;
161 static void convert(unsigned char* obuffer
, size_t oidx
, size_t psep
, const unsigned char* ibuffer
,
164 convert_x_helper
<T
, 4>::convert(obuffer
, oidx
, psep
, ibuffer
, iidx
);
171 static const size_t isize
= 4;
172 static const size_t esize
= T::esize
;
173 static void convert(unsigned char* obuffer
, size_t oidx
, size_t psep
, const unsigned char* ibuffer
,
176 convert_x_helper
<T
, 2048>::convert(obuffer
, oidx
, psep
, ibuffer
, iidx
);
183 static const size_t isize
= 8;
184 static const size_t esize
= T::esize
;
185 static void convert(unsigned char* obuffer
, size_t oidx
, size_t psep
, const unsigned char* ibuffer
,
191 TOYUV(ibuffer
, iidx
);
192 TOYUV(ibuffer
, iidx
+ 4);
193 TOYUV(ibuffer
, iidx
+ 2048);
194 TOYUV(ibuffer
, iidx
+ 2052);
195 T::store(obuffer
, oidx
, psep
, Y
, Cb
, Cr
);
199 template<typename T
, size_t ents
>
202 static void convert(unsigned char* obuffer
, size_t psep
, const unsigned char* ibuffer
)
204 for(unsigned i
= 0; i
< ents
; i
++)
205 T::convert(obuffer
, T::esize
* i
, psep
, ibuffer
, T::isize
* i
);
209 #define RGB2YUV_SHIFT 14
211 void init_matrix(double Kb
, double Kr
, bool fullrange
)
214 double GY
= 1 - Kr
- Kb
;
216 double RPb
= -0.5 * Kr
/ (1 - Kb
);
217 double GPb
= -0.5 * (1 - Kr
- Kb
) / (1 - Kb
);
220 double GPr
= -0.5 * (1 - Kr
- Kb
) / (1 - Kr
);
221 double BPr
= -0.5 * Kb
/ (1 - Kr
);
222 for(uint32_t i
= 0; i
< 0x80000; i
++) {
223 uint32_t l
= (i
>> 15) & 0xF;
224 //Range of (r,g,b) is 0...465.
225 uint32_t r
= (l
* ((i
>> 0) & 0x1F));
226 uint32_t g
= (l
* ((i
>> 5) & 0x1F));
227 uint32_t b
= (l
* ((i
>> 10) & 0x1F));
228 double Y
= (RY
* r
+ GY
* g
+ BY
* b
) / 465 * (fullrange
? 255 : 219) + (fullrange
? 0 : 16);
229 double Cb
= (RPb
* r
+ GPb
* g
+ BPb
* b
) / 465 * (fullrange
? 255 : 224) + 128;
230 double Cr
= (RPr
* r
+ GPr
* g
+ BPr
* b
) / 465 * (fullrange
? 255 : 224) + 128;
231 ymatrix
[i
] = static_cast<uint32_t>(Y
* 4194304 + 0.5);
232 cbmatrix
[i
] = static_cast<uint32_t>(Cb
* 4194304 + 0.5);
233 crmatrix
[i
] = static_cast<uint32_t>(Cr
* 4194304 + 0.5);
237 //Load RGB to YUV conversion matrix.
238 void load_rgb2yuv_matrix(uint32_t flags
)
240 switch(flags
& (FLAG_CS_MASK
| FLAG_FULLRANGE
))
243 init_matrix(0.114, 0.229, false);
245 case FLAG_ITU601
| FLAG_FULLRANGE
:
246 init_matrix(0.114, 0.229, true);
249 init_matrix(0.0722, 0.2126, false);
251 case FLAG_ITU709
| FLAG_FULLRANGE
:
252 init_matrix(0.0722, 0.2126, true);
255 init_matrix(0.087, 0.212, false);
257 case FLAG_SMPTE240M
| FLAG_FULLRANGE
:
258 init_matrix(0.087, 0.212, true);
261 init_matrix(0.114, 0.229, false);
266 //Render a line pair of YUV.
267 void render_yuv(unsigned char* buffer
, const unsigned char* src
, size_t psep
, uint32_t flags
, bool hires
,
271 if(flags
& FLAG_WIDTH
)
273 if(flags
& FLAG_HEIGHT
)
279 if(flags
& FLAG_8BIT
)
282 case 0: { //256 x 224/240 -> 256 x 224/240 16 bit.
283 convert_line
<convert_11
<store_11
<store16
<14>>>, 256>::convert(buffer
, psep
, src
);
286 case 1: { //256 x 224/240 -> 512 x 224/240 16 bit.
287 convert_line
<convert_11
<store_12
<store16
<14>>>, 256>::convert(buffer
, psep
, src
);
290 case 2: { //256 x 224/240 -> 256 x 448/480 16 bit.
291 convert_line
<convert_11
<store_21
<store16
<14>, 256>>, 256>::convert(buffer
, psep
, src
);
294 case 3: { //256 x 224/240 -> 512 x 448/480 16 bit.
295 convert_line
<convert_11
<store_22
<store16
<14>, 256>>, 256>::convert(buffer
, psep
, src
);
298 case 4: { //512 x 224/240 -> 256 x 224/240 16 bit.
299 convert_line
<convert_12
<store_11
<store16
<15>>>, 256>::convert(buffer
, psep
, src
);
302 case 5: { //512 x 224/240 -> 512 x 224/240 16 bit.
303 convert_line
<convert_11
<store_11
<store16
<14>>>, 512>::convert(buffer
, psep
, src
);
306 case 6: { //512 x 224/240 -> 256 x 448/480 16 bit.
307 convert_line
<convert_12
<store_21
<store16
<15>, 256>>, 256>::convert(buffer
, psep
, src
);
310 case 7: { //512 x 224/240 -> 512 x 448/480 16 bit.
311 convert_line
<convert_11
<store_21
<store16
<14>, 512>>, 512>::convert(buffer
, psep
, src
);
314 case 8: { //256 x 448x480 -> 256 x 224/240 16 bit.
315 convert_line
<convert_21
<store_11
<store16
<15>>>, 256>::convert(buffer
, psep
, src
);
318 case 9: { //256 x 448x480 -> 512 x 224/240 16 bit.
319 convert_line
<convert_21
<store_12
<store16
<15>>>, 256>::convert(buffer
, psep
, src
);
322 case 10: { //256 x 448x480 -> 256 x 448/480 16 bit.
323 convert_line
<convert_11
<store_11
<store16
<14>>>, 256>::convert(buffer
, psep
, src
);
324 convert_line
<convert_11
<store_11
<store16
<14>>>, 256>::convert(buffer
+ 512, psep
, src
+ 2048);
327 case 11: { //256 x 448x480 -> 512 x 448/480 16 bit.
328 convert_line
<convert_11
<store_12
<store16
<14>>>, 256>::convert(buffer
, psep
, src
);
329 convert_line
<convert_11
<store_12
<store16
<14>>>, 256>::convert(buffer
+ 1024, psep
, src
+ 2048);
332 case 12: { //512 x 448x480 -> 256 x 224/240 16 bit.
333 convert_line
<convert_22
<store_11
<store16
<16>>>, 256>::convert(buffer
, psep
, src
);
336 case 13: { //512 x 448x480 -> 512 x 224/240 16 bit.
337 convert_line
<convert_21
<store_11
<store16
<15>>>, 512>::convert(buffer
, psep
, src
);
340 case 14: { //512 x 448x480 -> 256 x 448/480 16 bit.
341 convert_line
<convert_11
<store_21
<store16
<14>, 256>>, 256>::convert(buffer
, psep
, src
);
342 convert_line
<convert_11
<store_21
<store16
<14>, 256>>, 256>::convert(buffer
+ 512, psep
, src
+ 2048);
345 case 15: { //512 x 448x480 -> 512 x 448/480 16 bit.
346 convert_line
<convert_11
<store_11
<store16
<14>>>, 512>::convert(buffer
, psep
, src
);
347 convert_line
<convert_11
<store_11
<store16
<14>>>, 512>::convert(buffer
+ 1024, psep
, src
+ 2048);
350 case 16: { //256 x 224/240 -> 256 x 224/240 16 bit.
351 convert_line
<convert_11
<store_11
<store8
<14>>>, 256>::convert(buffer
, psep
, src
);
354 case 17: { //256 x 224/240 -> 512 x 224/240 16 bit.
355 convert_line
<convert_11
<store_12
<store8
<14>>>, 256>::convert(buffer
, psep
, src
);
358 case 18: { //256 x 224/240 -> 256 x 448/480 16 bit.
359 convert_line
<convert_11
<store_21
<store8
<14>, 256>>, 256>::convert(buffer
, psep
, src
);
362 case 19: { //256 x 224/240 -> 512 x 448/480 16 bit.
363 convert_line
<convert_11
<store_22
<store8
<14>, 256>>, 256>::convert(buffer
, psep
, src
);
366 case 20: { //512 x 224/240 -> 256 x 224/240 16 bit.
367 convert_line
<convert_12
<store_11
<store8
<15>>>, 256>::convert(buffer
, psep
, src
);
370 case 21: { //512 x 224/240 -> 512 x 224/240 16 bit.
371 convert_line
<convert_11
<store_11
<store8
<14>>>, 512>::convert(buffer
, psep
, src
);
374 case 22: { //512 x 224/240 -> 256 x 448/480 16 bit.
375 convert_line
<convert_12
<store_21
<store8
<15>, 256>>, 256>::convert(buffer
, psep
, src
);
378 case 23: { //512 x 224/240 -> 512 x 448/480 16 bit.
379 convert_line
<convert_11
<store_21
<store8
<14>, 512>>, 512>::convert(buffer
, psep
, src
);
382 case 24: { //256 x 448x480 -> 256 x 224/240 16 bit.
383 convert_line
<convert_21
<store_11
<store8
<15>>>, 256>::convert(buffer
, psep
, src
);
386 case 25: { //256 x 448x480 -> 512 x 224/240 16 bit.
387 convert_line
<convert_21
<store_12
<store8
<15>>>, 256>::convert(buffer
, psep
, src
);
390 case 26: { //256 x 448x480 -> 256 x 448/480 16 bit.
391 convert_line
<convert_11
<store_11
<store8
<14>>>, 256>::convert(buffer
, psep
, src
);
392 convert_line
<convert_11
<store_11
<store8
<14>>>, 256>::convert(buffer
+ 256, psep
, src
+ 2048);
395 case 27: { //256 x 448x480 -> 512 x 448/480 16 bit.
396 convert_line
<convert_11
<store_12
<store8
<14>>>, 256>::convert(buffer
, psep
, src
);
397 convert_line
<convert_11
<store_12
<store8
<14>>>, 256>::convert(buffer
+ 512, psep
, src
+ 2048);
400 case 28: { //512 x 448x480 -> 256 x 224/240 16 bit.
401 convert_line
<convert_22
<store_11
<store8
<16>>>, 256>::convert(buffer
, psep
, src
);
404 case 29: { //512 x 448x480 -> 512 x 224/240 16 bit.
405 convert_line
<convert_21
<store_11
<store8
<15>>>, 512>::convert(buffer
, psep
, src
);
408 case 30: { //512 x 448x480 -> 256 x 448/480 16 bit.
409 convert_line
<convert_11
<store_21
<store8
<14>, 256>>, 256>::convert(buffer
, psep
, src
);
410 convert_line
<convert_11
<store_21
<store8
<14>, 256>>, 256>::convert(buffer
+ 256, psep
, src
+ 2048);
413 case 31: { //512 x 448x480 -> 512 x 448/480 16 bit.
414 convert_line
<convert_11
<store_11
<store8
<14>>>, 512>::convert(buffer
, psep
, src
);
415 convert_line
<convert_11
<store_11
<store8
<14>>>, 512>::convert(buffer
+ 512, psep
, src
+ 2048);
421 uint64_t double_to_ieeefp(double v
)
434 for(unsigned i
= 0; i
< 52; i
++) {
436 v2
= 2 * v2
+ ((v
>= 1) ? 1 : 0);
443 void sdump2sox(std::istream
& in
, std::ostream
& yout
, std::ostream
& sout
, uint32_t flags
)
445 unsigned char header
[12];
446 in
.read(reinterpret_cast<char*>(header
), 12);
448 throw std::runtime_error("Can't read sdump header");
449 if(header
[0] != 'S' || header
[1] != 'D' || header
[2] != 'M' || header
[3] != 'P')
450 throw std::runtime_error("Bad sdump magic");
453 cpurate
= (static_cast<uint32_t>(header
[4]) << 24) |
454 (static_cast<uint32_t>(header
[5]) << 16) |
455 (static_cast<uint32_t>(header
[6]) << 8) |
456 static_cast<uint32_t>(header
[7]);
457 apurate
= (static_cast<uint32_t>(header
[8]) << 24) |
458 (static_cast<uint32_t>(header
[9]) << 16) |
459 (static_cast<uint32_t>(header
[10]) << 8) |
460 static_cast<uint32_t>(header
[11]);
461 uint64_t sndrateR
= double_to_ieeefp(static_cast<double>(apurate
) / 768.0);
462 unsigned char sox_header
[32] = {0};
463 sox_header
[0] = 0x2E; //Magic
464 sox_header
[1] = 0x53; //Magic
465 sox_header
[2] = 0x6F; //Magic
466 sox_header
[3] = 0x58; //Magic
467 sox_header
[4] = 0x1C; //Magic
468 sox_header
[16] = sndrateR
;
469 sox_header
[17] = sndrateR
>> 8;
470 sox_header
[18] = sndrateR
>> 16;
471 sox_header
[19] = sndrateR
>> 24;
472 sox_header
[20] = sndrateR
>> 32;
473 sox_header
[21] = sndrateR
>> 40;
474 sox_header
[22] = sndrateR
>> 48;
475 sox_header
[23] = sndrateR
>> 56;
477 sout
.write(reinterpret_cast<char*>(sox_header
), 32);
479 throw std::runtime_error("Can't write audio header");
480 uint64_t samples
= 0;
482 unsigned wrongrate
= 0;
484 load_rgb2yuv_matrix(flags
);
490 break; //End of stream.
491 if((cmd
& 0xF0) == 0) {
492 //Pictrue. Read the 1MiB of picture data one line pair at a time.
493 unsigned char buf
[4096];
494 unsigned physline
= 0;
495 bool hires
= (cmd
& 1);
496 bool interlaced
= (cmd
& 2);
497 bool overscan
= (cmd
& 4);
498 bool pal
= (cmd
& 8);
499 bool ohires
= (flags
& FLAG_WIDTH
);
500 bool ointerlaced
= (flags
& FLAG_HEIGHT
);
501 bool bits8
= (flags
& FLAG_8BIT
);
502 size_t psep
= (ohires
? 512 : 256) * (ointerlaced
? 2 : 1) * (pal
? 240 : 224) *
504 size_t lsep
= (ohires
? 512 : 256) * (ointerlaced
? 2 : 1) * (bits8
? 1 : 2);
505 for(unsigned i
= 0; i
< 256; i
++) {
506 in
.read(reinterpret_cast<char*>(buf
), 4096);
508 throw std::runtime_error("Can't read picture payload");
509 is_pal
= is_pal
|| pal
;
510 if(overscan
&& i
< 9)
512 if(!overscan
&& i
< 1)
514 if(pal
& physline
>= 239)
516 if(!pal
& physline
>= 224)
518 render_yuv(yuv_buffer
+ physline
* lsep
, buf
, psep
, flags
, hires
, interlaced
);
522 //Render a black line to pad the image.
523 memset(buf
, 0, 4096);
524 render_yuv(yuv_buffer
+ 239 * lsep
, buf
, psep
, flags
, hires
, interlaced
);
526 size_t yuvsize
= 3 * psep
;
528 if((flags
& FLAG_FRAMERATE
) == 0 && !is_pal
&& interlaced
) {
529 //This uses 357368 TU instead of 357366 TU.
530 //-> Every 178683rd frame is duplicated.
531 if(wrongrate
== 178682) {
537 if((flags
& FLAG_FRAMERATE
) != 0 && !is_pal
&& !interlaced
) {
538 //This uses 357366 TU instead of 357368 TU.
539 //-> Every 178684th frame is dropped.
540 if(wrongrate
== 178683) {
546 for(unsigned k
= 0; k
< times
; k
++)
547 yout
.write(reinterpret_cast<char*>(yuv_buffer
), yuvsize
);
549 throw std::runtime_error("Can't write frame");
552 } else if(cmd
== 16) {
553 //Sound packet. Interesting.
554 unsigned char ibuf
[4];
555 unsigned char obuf
[8];
556 in
.read(reinterpret_cast<char*>(ibuf
), 4);
558 throw std::runtime_error("Can't read sound packet payload");
567 sout
.write(reinterpret_cast<char*>(obuf
), 8);
569 throw std::runtime_error("Can't write audio sample");
572 std::ostringstream str
;
573 str
<< "Unknown command byte " << static_cast<unsigned>(cmd
);
574 throw std::runtime_error(str
.str());
576 if(lf
&& frames
% 100 == 0) {
577 std::cout
<< "\e[1G" << frames
<< " frames, " << samples
<< " samples." << std::flush
;
580 //Sox internally multiplies sample count by channel count.
581 sox_header
[8] = samples
<< 1;
582 sox_header
[9] = samples
>> 7;
583 sox_header
[10] = samples
>> 15;
584 sox_header
[11] = samples
>> 23;
585 sox_header
[12] = samples
>> 31;
586 sox_header
[13] = samples
>> 39;
587 sox_header
[14] = samples
>> 47;
588 sox_header
[15] = samples
>> 55;
589 sout
.seekp(0, std::ios::beg
);
591 throw std::runtime_error("Can't seek to fix .sox header");
592 sout
.write(reinterpret_cast<char*>(sox_header
), 32);
594 throw std::runtime_error("Can't fix audio header");
595 std::cout
<< "Sound sampling rate is " << static_cast<double>(apurate
) / 768.0 << "Hz" << std::endl
;
596 std::cout
<< "Wrote " << samples
<< " samples." << std::endl
;
597 std::cout
<< "Audio length is " << 768.0 * samples
/ apurate
<< "s." << std::endl
;
602 else if(flags
& FLAG_FRAMERATE
)
606 vrate
= cpurate
/ vrate2
;
607 std::cout
<< "Video frame rate is " << cpurate
<< "/" << vrate2
<< "Hz" << std::endl
;
608 std::cout
<< "Wrote " << frames
<< " frames." << std::endl
;
609 std::cout
<< "Video length is " << frames
/ vrate
<< "s." << std::endl
;
614 std::cerr
<< "Syntax: sdump2sox [<options>] <input-file> <yuv-output-file> <sox-output-file>" << std::endl
;
615 std::cerr
<< "-W\tDump 512-wide instead of 256-wide." << std::endl
;
616 std::cerr
<< "-H\tDump 448/480-high instead of 224/240-high." << std::endl
;
617 std::cerr
<< "-F\tDump at interlaced framerate instead of non-interlaced." << std::endl
;
618 std::cerr
<< "-f\tDump using full range instead of TV range." << std::endl
;
619 std::cerr
<< "-7\tDump using ITU.709 instead of ITU.601." << std::endl
;
620 std::cerr
<< "-2\tDump using SMPTE-240M instead of ITU.601." << std::endl
;
621 std::cerr
<< "-8\tDump using 8 bits instead of 16 bits." << std::endl
;
624 int main(int argc
, char** argv
)
634 for(unsigned i
= 1; i
< argc
; i
++) {
635 if(argv
[i
][0] == '-')
636 for(unsigned j
= 1; argv
[i
][j
]; j
++)
642 flags
|= FLAG_HEIGHT
;
645 flags
|= FLAG_FRAMERATE
;
648 flags
|= FLAG_FULLRANGE
;
651 if(flags
& FLAG_CS_MASK
) {
655 flags
|= FLAG_ITU709
;
658 if(flags
& FLAG_CS_MASK
) {
662 flags
|= FLAG_SMPTE240M
;
682 std::ifstream
in(argv
[idx1
], std::ios::in
| std::ios::binary
);
684 std::cerr
<< "Error: Can't open '" << argv
[idx1
] << "'" << std::endl
;
687 std::ofstream
yout(argv
[idx2
], std::ios::out
| std::ios::binary
);
689 std::cerr
<< "Error: Can't open '" << argv
[idx2
] << "'" << std::endl
;
692 std::ofstream
sout(argv
[idx3
], std::ios::out
| std::ios::binary
);
694 std::cerr
<< "Error: Can't open '" << argv
[idx3
] << "'" << std::endl
;
698 sdump2sox(in
, yout
, sout
, flags
);
702 } catch(std::exception
& e
) {
703 std::cerr
<< "Error: " << e
.what() << std::endl
;