incremental
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e9b3e75..501c2c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,9 +94,10 @@
set(Boost_USE_STATIC_LIBS ON)
hunter_add_package(Boost)
find_package(Boost)
+include_directories(${Boost_INCLUDE_DIRS})
#Openssl
-hunter_add_package(OpenSSL)
+#hunter_add_package(OpenSSL)
find_package(OpenSSL REQUIRED)
#g3 logging
@@ -200,7 +201,7 @@
src/test_utils.cpp
src/msan_test.cpp
src/ci_map_tests.cpp
-
+ src/ast_video_puller_test.cpp
${CMAKE_BINARY_DIR}/generated/blns.hpp
)
diff --git a/aspeed_purley.cmake b/aspeed_purley.cmake
new file mode 100644
index 0000000..2c48ed2
--- /dev/null
+++ b/aspeed_purley.cmake
@@ -0,0 +1,32 @@
+# this one is important
+SET(CMAKE_SYSTEM_NAME Linux)
+#this one not so much
+SET(CMAKE_SYSTEM_VERSION 1)
+SET(CMAKE_SYSTEM_PROCESSOR "armv6")
+set(ARCH "armv6")
+
+SET(CMAKE_CROSSCOMPILING True)
+
+# specify the cross compiler
+#SET(CMAKE_C_COMPILER arm-linux-gnueabi-gcc-4.9)
+#SET(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++-4.9)
+#SET(CMAKE_C_LINK_EXECUTABLE "clang <OBJECTS> -o <TARGET> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
+#SET(CMAKE_CXX_LINK_EXECUTABLE "clang++ <OBJECTS> -o <TARGET> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
+
+set(CMAKE_C_COMPILER /home/ed/deg-bmcfw-core/ToolChain/Host/AST2500/x-tools/arm-aspeed-linux-gnueabi/bin/arm-linux-gcc)
+set(CMAKE_CXX_COMPILER /home/ed/deg-bmcfw-core/ToolChain/Host/AST2500/x-tools/arm-aspeed-linux-gnueabi/bin/arm-linux-g++)
+
+
+set(triple arm-linux-gnueabi)
+set(CMAKE_C_COMPILER_TARGET ${triple})
+set(CMAKE_CXX_COMPILER_TARGET ${triple})
+
+# where is the target environment
+SET(CMAKE_FIND_ROOT_PATH /home/ed/deg-bmcfw-core/_sysroot/AST2500)
+
+# search for programs in the build host directories
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+# for libraries and headers in the target directories
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
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;
+//
+// 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 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 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 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;
+//
+// 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 @@
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 @@
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 @@
// 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;
diff --git a/src/ast_video_puller_test.cpp b/src/ast_video_puller_test.cpp
new file mode 100644
index 0000000..ef1cbe3
--- /dev/null
+++ b/src/ast_video_puller_test.cpp
@@ -0,0 +1,49 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ast_jpeg_decoder.hpp>
+#include <ast_video_puller.hpp>
+#include <chrono>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <thread>
+#include <vector>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+TEST(AstvideoPuller, BasicRead) {
+ std::cout << "Started\n";
+ AstVideo::RawVideoBuffer out;
+ bool have_hardware = false;
+ if (access("/dev/video", F_OK) != -1) {
+ AstVideo::SimpleVideoPuller p;
+ p.initialize();
+ out = p.read_video();
+ } else {
+ FILE *fp = fopen("test_resources/ubuntu_444_800x600_0chrom_0lum.bin", "rb");
+ if (fp) {
+ size_t newLen = fread(out.buffer.data(), sizeof(char),
+ out.buffer.size() * sizeof(long), fp);
+ if (ferror(fp) != 0) {
+ fputs("Error reading file", stderr);
+ }
+ fclose(fp);
+ out.buffer.resize(newLen);
+ out.mode = AstVideo::YuvMode::YUV444;
+ out.width = 800;
+ out.height = 600;
+ out.y_selector = 0;
+ out.uv_selector = 0;
+ }
+ }
+
+ FILE *fp = fopen("/tmp/screendata.bin", "wb");
+ fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
+
+ AstVideo::AstJpegDecoder d;
+ std::cout << "MODE " << static_cast<int>(out.mode);
+ d.decode(out.buffer, out.width, out.height, out.mode, out.y_selector,
+ out.uv_selector);
+}
diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp
index 8c92bd3..33885ee 100644
--- a/src/getvideo_main.cpp
+++ b/src/getvideo_main.cpp
@@ -24,7 +24,7 @@
AstVideo::RawVideoBuffer out;
bool have_hardware = false;
if (access("/dev/video", F_OK) != -1) {
- AstVideo::VideoPuller p;
+ AstVideo::SimpleVideoPuller p;
p.initialize();
out = p.read_video();
} else {