1 #include "yuv4mpeg.hpp"
2 #include "parseval.hpp"
4 #include "rendertext.hpp"
7 void swap_buffers(char* a
, char* b
, size_t s
)
9 for(size_t i
= 0; i
< s
; i
++)
10 std::swap(a
[i
], b
[i
]);
13 void do_flip(char* content
, size_t fsize
, size_t height
, unsigned mode
)
16 //Mode 0: Flip RGB or greyscale.
17 size_t lsize
= fsize
/ height
;
18 for(size_t i
= 0; i
< height
/ 2; i
++)
19 swap_buffers(content
+ lsize
* i
, content
+ lsize
* (height
- i
- 1), lsize
);
20 } else if(mode
== 1) {
21 //Mode 1: Flip YUV420.
22 size_t psize
= fsize
* 2 / 3;
23 do_flip(content
, psize
, height
, 0);
24 do_flip(content
+ psize
, psize
>> 2, height
>> 1, 0);
25 do_flip(content
+ psize
+ (psize
>> 2), psize
>> 2, height
>> 1, 0);
26 } else if(mode
== 2) {
27 //Mode 2: Flip YUV422.
28 size_t psize
= fsize
/ 2;
29 do_flip(content
, psize
, height
, 0);
30 do_flip(content
+ psize
, psize
>> 1, height
>> 1, 0);
31 do_flip(content
+ psize
+ (psize
>> 1), psize
>> 1, height
>> 1, 0);
32 } else if(mode
== 3) {
33 //Mode 3: Flip YUV444.
34 size_t psize
= fsize
/ 3;
35 do_flip(content
, psize
, height
, 0);
36 do_flip(content
+ psize
, psize
, height
, 0);
37 do_flip(content
+ psize
+ psize
, psize
, height
, 0);
41 int main(int argc
, char** argv
)
44 for(int i
= 1; i
< argc
; i
++) {
45 std::string arg
= argv
[i
];
47 std::cerr
<< "vflip: Unrecognized option '" << arg
<< "'" << std::endl
;
49 } catch(std::exception
& e
) {
50 std::cerr
<< "vflip: Error in option '" << arg
<< "': " << e
.what() << std::endl
;
58 mark_pipe_as_binary(in
);
59 mark_pipe_as_binary(out
);
64 struct yuv4mpeg_stream_header
strmh(in
);
65 if(strmh
.chroma
== "rgb") {
66 framesize
= 3 * strmh
.width
* strmh
.height
; mode
= 0;
67 } else if(strmh
.chroma
== "420") {
68 framesize
= 3 * strmh
.width
* strmh
.height
/ 2; mode
= 1;
69 } else if(strmh
.chroma
== "420p16") {
70 framesize
= 6 * strmh
.width
* strmh
.height
/ 2; mode
= 1;
71 } else if(strmh
.chroma
== "422") {
72 framesize
= 2 * strmh
.width
* strmh
.height
; mode
= 2;
73 } else if(strmh
.chroma
== "422p16") {
74 framesize
= 4 * strmh
.width
* strmh
.height
; mode
= 2;
75 } else if(strmh
.chroma
== "444") {
76 framesize
= 3 * strmh
.width
* strmh
.height
; mode
= 3;
77 } else if(strmh
.chroma
== "444p16") {
78 framesize
= 6 * strmh
.width
* strmh
.height
; mode
= 3;
80 throw std::runtime_error("Unsupported input chroma type '" + strmh
.chroma
+ "'");
81 write_or_die(out
, static_cast<std::string
>(strmh
));
83 std::string _framh
, _framh2
;
84 std::vector
<char> buffer
;
85 buffer
.resize(framesize
);
86 struct yuv4mpeg_frame_header framh
;
90 if(!read_line2(in
, _framh
))
92 framh
= yuv4mpeg_frame_header(_framh
);
93 read_or_die(in
, &buffer
[0], buffer
.size());
94 do_flip(&buffer
[0], framesize
, strmh
.height
, mode
);
95 write_or_die(out
, static_cast<std::string
>(framh
));
96 write_or_die(out
, &buffer
[0], buffer
.size());
98 } catch(std::exception
& e
) {
99 std::cerr
<< "vflip: Error: " << e
.what() << std::endl
;