blob: fd29ca5b2cd588b7817612f10619aa1c3daf49c1 [file] [log] [blame]
Ed Tanous93f987d2017-04-17 17:52:36 -07001#pragma once
2
Ed Tanous93f987d2017-04-17 17:52:36 -07003#include <assert.h>
Ed Tanous1ff48782017-04-18 12:45:08 -07004#include <ast_video_types.hpp>
Ed Tanouse2fc45a2017-04-26 09:19:10 -07005#include <g3log/g3log.hpp>
Ed Tanous93f987d2017-04-17 17:52:36 -07006#include <iostream>
Ed Tanouse2fc45a2017-04-26 09:19:10 -07007#include <mutex>
Ed Tanous1ff48782017-04-18 12:45:08 -07008#include <vector>
Ed Tanouse2fc45a2017-04-26 09:19:10 -07009#include <boost/asio.hpp>
Ed Tanous93f987d2017-04-17 17:52:36 -070010
11namespace AstVideo {
Ed Tanousd5f39992017-04-18 13:41:22 -070012
Ed Tanouse2fc45a2017-04-26 09:19:10 -070013//
14// Cursor struct is used in User Mode
15//
16typedef struct _cursor_attribution_tag {
17 unsigned int posX;
18 unsigned int posY;
19 unsigned int cur_width;
20 unsigned int cur_height;
21 unsigned int cur_type; // 0:mono 1:color 2:disappear cursor
22 unsigned int cur_change_flag;
23} AST_CUR_ATTRIBUTION_TAG;
Ed Tanousd5f39992017-04-18 13:41:22 -070024
Ed Tanouse2fc45a2017-04-26 09:19:10 -070025//
26// For storing Cursor Information
27//
28typedef struct _cursor_tag {
29 AST_CUR_ATTRIBUTION_TAG attr;
30 // unsigned char icon[MAX_CUR_OFFSETX*MAX_CUR_OFFSETY*2];
31 unsigned char *icon; //[64*64*2];
32} AST_CURSOR_TAG;
Ed Tanousd5f39992017-04-18 13:41:22 -070033
Ed Tanouse2fc45a2017-04-26 09:19:10 -070034//
35// For select image format, i.e. 422 JPG420, 444 JPG444, lumin/chrom table, 0
36// ~ 11, low to high
37//
38typedef struct _video_features {
39 short jpg_fmt; // 422:JPG420, 444:JPG444
40 short lumin_tbl;
41 short chrom_tbl;
42 short tolerance_noise;
43 int w;
44 int h;
45 unsigned char *buf;
46} FEATURES_TAG;
Ed Tanousd5f39992017-04-18 13:41:22 -070047
Ed Tanouse2fc45a2017-04-26 09:19:10 -070048//
49// For configure video engine control registers
50//
51typedef struct _image_info {
52 short do_image_refresh; // Action 0:motion 1:fullframe 2:quick cursor
53 char qc_valid; // quick cursor enable/disable
54 unsigned int len;
55 int crypttype;
56 char cryptkey[16];
57 union {
58 FEATURES_TAG features;
59 AST_CURSOR_TAG cursor_info;
60 } parameter;
61} IMAGE_INFO;
62
63class SimpleVideoPuller {
Ed Tanous93f987d2017-04-17 17:52:36 -070064 public:
Ed Tanouse2fc45a2017-04-26 09:19:10 -070065 SimpleVideoPuller() : image_info(){};
Ed Tanous93f987d2017-04-17 17:52:36 -070066
67 void initialize() {
68 std::cout << "Opening /dev/video\n";
69 video_fd = open("/dev/video", O_RDWR);
70 if (!video_fd) {
71 std::cout << "Failed to open /dev/video\n";
Ed Tanouse2fc45a2017-04-26 09:19:10 -070072 throw std::runtime_error("Failed to open /dev/video");
Ed Tanous93f987d2017-04-17 17:52:36 -070073 }
Ed Tanouse2fc45a2017-04-26 09:19:10 -070074 std::cout << "Opened successfully\n";
Ed Tanous93f987d2017-04-17 17:52:36 -070075 }
76
77 RawVideoBuffer read_video() {
78 assert(video_fd != 0);
79 RawVideoBuffer raw;
80
Ed Tanous93f987d2017-04-17 17:52:36 -070081 image_info.do_image_refresh = 1; // full frame refresh
82 image_info.qc_valid = 0; // quick cursor disabled
Ed Tanous93f987d2017-04-17 17:52:36 -070083 image_info.parameter.features.buf =
84 reinterpret_cast<unsigned char *>(raw.buffer.data());
85 image_info.crypttype = -1;
86 std::cout << "Writing\n";
87
88 int status;
89 /*
90 status = write(video_fd, reinterpret_cast<char*>(&image_info),
91 sizeof(image_info));
92 if (status != sizeof(image_info)) {
93 std::cout << "Write failed. Return: " << status << "\n";
94 perror("perror output:");
95 }
Ed Tanous1ff48782017-04-18 12:45:08 -070096
Ed Tanous93f987d2017-04-17 17:52:36 -070097 std::cout << "Write done\n";
98 */
Ed Tanouse2fc45a2017-04-26 09:19:10 -070099 LOG(DEBUG) << "Reading\n";
Ed Tanous93f987d2017-04-17 17:52:36 -0700100 status = read(video_fd, reinterpret_cast<char *>(&image_info),
101 sizeof(image_info));
Ed Tanouse2fc45a2017-04-26 09:19:10 -0700102 LOG(DEBUG) << "Done reading\n";
Ed Tanous93f987d2017-04-17 17:52:36 -0700103
104 if (status != 0) {
Ed Tanouse2fc45a2017-04-26 09:19:10 -0700105 LOG(WARNING) << "Read failed with status " << status << "\n";
Ed Tanous93f987d2017-04-17 17:52:36 -0700106 }
107
108 raw.buffer.resize(image_info.len);
109
110 raw.height = image_info.parameter.features.h;
111 raw.width = image_info.parameter.features.w;
112 if (image_info.parameter.features.jpg_fmt == 422) {
113 raw.mode = YuvMode::YUV420;
114 } else {
115 raw.mode = YuvMode::YUV444;
116 }
117 return raw;
118 }
119
120 private:
121 int video_fd;
122 IMAGE_INFO image_info;
123};
Ed Tanouse2fc45a2017-04-26 09:19:10 -0700124
125#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
126class AsyncVideoPuller {
127 public:
128 typedef std::function<void(RawVideoBuffer &)> video_callback;
129
130 AsyncVideoPuller(boost::asio::io_service &io_service)
131 : image_info(), dev_video(io_service, open("/dev/video", O_RDWR)) {
132 videobuf = std::make_shared<RawVideoBuffer>();
133
134 image_info.do_image_refresh = 1; // full frame refresh
135 image_info.qc_valid = 0; // quick cursor disabled
136 image_info.parameter.features.buf =
137 reinterpret_cast<unsigned char *>(videobuf->buffer.data());
138 image_info.crypttype = -1;
139 };
140
141 void register_callback(video_callback &callback) {
142 std::lock_guard<std::mutex> lock(callback_mutex);
143 callbacks.push_back(callback);
144 start_read();
145 }
146
147 void start_read() {
148 auto mutable_buffer = boost::asio::buffer(&image_info, sizeof(image_info));
149 boost::asio::async_read(
150 dev_video, mutable_buffer, [this](const boost::system::error_code &ec,
151 std::size_t bytes_transferred) {
152 if (ec) {
153 LOG(WARNING) << "Read failed with status " << ec << "\n";
154 } else {
155 this->read_done();
156 }
157 });
158 }
159
160 void read_done() {
161 LOG(DEBUG) << "Done reading\n";
162 videobuf->buffer.resize(image_info.len);
163
164 videobuf->height = image_info.parameter.features.h;
165 videobuf->width = image_info.parameter.features.w;
166 if (image_info.parameter.features.jpg_fmt == 422) {
167 videobuf->mode = YuvMode::YUV420;
168 } else {
169 videobuf->mode = YuvMode::YUV444;
170 }
171 std::lock_guard<std::mutex> lock(callback_mutex);
172 for (auto &callback : callbacks) {
173 // TODO(ed) call callbacks async and double buffer frames
174 callback(*videobuf);
175 }
176 }
177
178 private:
179 std::shared_ptr<RawVideoBuffer> videobuf;
180 boost::asio::posix::stream_descriptor dev_video;
181 IMAGE_INFO image_info;
182 std::mutex callback_mutex;
183 std::vector<video_callback> callbacks;
184};
185#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
Ed Tanous93f987d2017-04-17 17:52:36 -0700186}