diff options
| author | Ed Tanous <ed.tanous@intel.com> | 2017-04-26 09:19:10 -0700 |
|---|---|---|
| committer | Ed Tanous <ed.tanous@intel.com> | 2017-04-26 09:19:10 -0700 |
| commit | e2fc45a1cd7645e50754d93ce52ec8935e723007 (patch) | |
| tree | 626f913e5622dd2d7f5c0fd6714362854da0fbdf /include | |
| parent | eb1b8620422c5bc6f9b4e00fe7baf0c64f92b68c (diff) | |
| download | bmcweb-e2fc45a1cd7645e50754d93ce52ec8935e723007.tar.gz bmcweb-e2fc45a1cd7645e50754d93ce52ec8935e723007.zip | |
incremental
Diffstat (limited to 'include')
| -rw-r--r-- | include/ast_video_puller.hpp | 179 | ||||
| -rw-r--r-- | include/web_kvm.hpp | 2 |
2 files changed, 123 insertions, 58 deletions
diff --git a/include/ast_video_puller.hpp b/include/ast_video_puller.hpp index 214e2df..fd29ca5 100644 --- a/include/ast_video_puller.hpp +++ b/include/ast_video_puller.hpp @@ -2,73 +2,76 @@ #include <assert.h> #include <ast_video_types.hpp> +#include <g3log/g3log.hpp> #include <iostream> +#include <mutex> #include <vector> +#include <boost/asio.hpp> namespace AstVideo { -class VideoPuller { - // - // Cursor struct is used in User Mode - // - typedef struct _cursor_attribution_tag { - unsigned int posX; - unsigned int posY; - unsigned int cur_width; - unsigned int cur_height; - unsigned int cur_type; // 0:mono 1:color 2:disappear cursor - unsigned int cur_change_flag; - } AST_CUR_ATTRIBUTION_TAG; - - // - // For storing Cursor Information - // - typedef struct _cursor_tag { - AST_CUR_ATTRIBUTION_TAG attr; - // unsigned char icon[MAX_CUR_OFFSETX*MAX_CUR_OFFSETY*2]; - unsigned char *icon; //[64*64*2]; - } AST_CURSOR_TAG; - - // - // For select image format, i.e. 422 JPG420, 444 JPG444, lumin/chrom table, 0 - // ~ 11, low to high - // - typedef struct _video_features { - short jpg_fmt; // 422:JPG420, 444:JPG444 - short lumin_tbl; - short chrom_tbl; - short tolerance_noise; - int w; - int h; - unsigned char *buf; - } FEATURES_TAG; - - // - // For configure video engine control registers - // - typedef struct _image_info { - short do_image_refresh; // Action 0:motion 1:fullframe 2:quick cursor - char qc_valid; // quick cursor enable/disable - unsigned int len; - int crypttype; - char cryptkey[16]; - union { - FEATURES_TAG features; - AST_CURSOR_TAG cursor_info; - } parameter; - } IMAGE_INFO; +// +// Cursor struct is used in User Mode +// +typedef struct _cursor_attribution_tag { + unsigned int posX; + unsigned int posY; + unsigned int cur_width; + unsigned int cur_height; + unsigned int cur_type; // 0:mono 1:color 2:disappear cursor + unsigned int cur_change_flag; +} AST_CUR_ATTRIBUTION_TAG; + +// +// For storing Cursor Information +// +typedef struct _cursor_tag { + AST_CUR_ATTRIBUTION_TAG attr; + // unsigned char icon[MAX_CUR_OFFSETX*MAX_CUR_OFFSETY*2]; + unsigned char *icon; //[64*64*2]; +} AST_CURSOR_TAG; + +// +// For select image format, i.e. 422 JPG420, 444 JPG444, lumin/chrom table, 0 +// ~ 11, low to high +// +typedef struct _video_features { + short jpg_fmt; // 422:JPG420, 444:JPG444 + short lumin_tbl; + short chrom_tbl; + short tolerance_noise; + int w; + int h; + unsigned char *buf; +} FEATURES_TAG; + +// +// For configure video engine control registers +// +typedef struct _image_info { + short do_image_refresh; // Action 0:motion 1:fullframe 2:quick cursor + char qc_valid; // quick cursor enable/disable + unsigned int len; + int crypttype; + char cryptkey[16]; + union { + FEATURES_TAG features; + AST_CURSOR_TAG cursor_info; + } parameter; +} IMAGE_INFO; + +class SimpleVideoPuller { public: - VideoPuller() : image_info(){}; + SimpleVideoPuller() : image_info(){}; void initialize() { std::cout << "Opening /dev/video\n"; video_fd = open("/dev/video", O_RDWR); if (!video_fd) { std::cout << "Failed to open /dev/video\n"; - // TODO(Ed) throw exception? - } else { - std::cout << "Opened successfully\n"; + throw std::runtime_error("Failed to open /dev/video"); } + std::cout << "Opened successfully\n"; } RawVideoBuffer read_video() { @@ -93,13 +96,13 @@ class VideoPuller { std::cout << "Write done\n"; */ - std::cout << "Reading\n"; + LOG(DEBUG) << "Reading\n"; status = read(video_fd, reinterpret_cast<char *>(&image_info), sizeof(image_info)); - std::cout << "Reading\n"; + LOG(DEBUG) << "Done reading\n"; if (status != 0) { - std::cout << "Read failed with status " << status << "\n"; + LOG(WARNING) << "Read failed with status " << status << "\n"; } raw.buffer.resize(image_info.len); @@ -118,4 +121,66 @@ class VideoPuller { int video_fd; IMAGE_INFO image_info; }; + +#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) +class AsyncVideoPuller { + public: + typedef std::function<void(RawVideoBuffer &)> video_callback; + + AsyncVideoPuller(boost::asio::io_service &io_service) + : image_info(), dev_video(io_service, open("/dev/video", O_RDWR)) { + videobuf = std::make_shared<RawVideoBuffer>(); + + image_info.do_image_refresh = 1; // full frame refresh + image_info.qc_valid = 0; // quick cursor disabled + image_info.parameter.features.buf = + reinterpret_cast<unsigned char *>(videobuf->buffer.data()); + image_info.crypttype = -1; + }; + + void register_callback(video_callback &callback) { + std::lock_guard<std::mutex> lock(callback_mutex); + callbacks.push_back(callback); + start_read(); + } + + void start_read() { + auto mutable_buffer = boost::asio::buffer(&image_info, sizeof(image_info)); + boost::asio::async_read( + dev_video, mutable_buffer, [this](const boost::system::error_code &ec, + std::size_t bytes_transferred) { + if (ec) { + LOG(WARNING) << "Read failed with status " << ec << "\n"; + } else { + this->read_done(); + } + }); + } + + void read_done() { + LOG(DEBUG) << "Done reading\n"; + videobuf->buffer.resize(image_info.len); + + videobuf->height = image_info.parameter.features.h; + videobuf->width = image_info.parameter.features.w; + if (image_info.parameter.features.jpg_fmt == 422) { + videobuf->mode = YuvMode::YUV420; + } else { + videobuf->mode = YuvMode::YUV444; + } + std::lock_guard<std::mutex> lock(callback_mutex); + for (auto &callback : callbacks) { + // TODO(ed) call callbacks async and double buffer frames + callback(*videobuf); + } + } + + private: + std::shared_ptr<RawVideoBuffer> videobuf; + boost::asio::posix::stream_descriptor dev_video; + IMAGE_INFO image_info; + std::mutex callback_mutex; + std::vector<video_callback> callbacks; +}; +#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) } diff --git a/include/web_kvm.hpp b/include/web_kvm.hpp index 10291ca..1671382 100644 --- a/include/web_kvm.hpp +++ b/include/web_kvm.hpp @@ -282,7 +282,7 @@ void request_routes(Crow<Middlewares...>& app) { // Todo(ed) lifecycle of the video puller and decoder // should be // with the websocket, not recreated every time - AstVideo::VideoPuller p; + AstVideo::SimpleVideoPuller p; p.initialize(); auto out = p.read_video(); AstVideo::AstJpegDecoder d; |

