From 4edc38495a4fe748c8089a35dbe03e2fc712cb59 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Mon, 29 Oct 2018 13:47:06 +0000 Subject: [PATCH 01/36] Issue #9: Epiphan SDK video source now supports BGRA captures --- src/epiphansdk/epiphansdk_video_source.cpp | 57 +++++++++++++++++----- src/epiphansdk/epiphansdk_video_source.h | 7 ++- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index fff34e90..a0a7725f 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -10,6 +10,7 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( , _frame_grabber(nullptr) , _flags(0) , _daemon(nullptr) + , _bgra_data(nullptr) { FrmGrab_Init(); @@ -21,7 +22,7 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( return; } - if (colour_space != V2U_GRABFRAME_FORMAT_I420 and colour_space != V2U_GRABFRAME_FORMAT_BGR24) + if (colour_space != V2U_GRABFRAME_FORMAT_I420 and colour_space != V2U_GRABFRAME_FORMAT_ARGB32) { // TODO - exception GiftGrab#42 std::cerr << "Colour space " << colour_space << " not supported" << std::endl; @@ -42,6 +43,12 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( */ _full.width = 1920; _full.height = 1080; + if (_colour == BGRA) + { + _bgra_data = reinterpret_cast(realloc( + _bgra_data, 4 * _full.width * _full.height * sizeof(unsigned char) + )); + } get_full_frame(); // TODO - exception GiftGrab#42 if (not get_frame(frame)) return; @@ -55,6 +62,11 @@ VideoSourceEpiphanSDK::~VideoSourceEpiphanSDK() delete _daemon; if (_frame_grabber) FrmGrab_Close(_frame_grabber); FrmGrab_Deinit(); + if (_colour == BGRA && _bgra_data != nullptr) + { + free(_bgra_data); + _bgra_data = nullptr; + } } bool VideoSourceEpiphanSDK::get_frame_dimensions(int & width, int & height) @@ -73,17 +85,40 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) _buffer = FrmGrab_Frame(_frame_grabber, _flags, &_roi); if (_buffer) { + unsigned char *data = static_cast(_buffer->pixbuf); + size_t frame_data_length = _buffer->imagelen; + /* TODO #54 specified _roi not always + * respected by FrmGrab_Frame, hence + * constructing with _buffer->crop + * instead of _roi to avoid alignment + * problems when saving to video files + */ + size_t frame_width = _buffer->crop.width, + frame_height = _buffer->crop.height; + unsigned char *frame_data = nullptr; + switch(_colour) + { + case I420: + frame_data = data; + break; + case BGRA: + for (size_t i = 0; i < frame_data_length; i += 4) + { + _bgra_data[i] = data[i + 3]; + _bgra_data[i + 1] = data[i + 2]; + _bgra_data[i + 2] = data[i + 1]; + _bgra_data[i + 3] = data[i]; + } + frame_data = _bgra_data; + break; + default: + // TODO + break; + } frame.init_from_specs( - static_cast(_buffer->pixbuf), - _buffer->imagelen, - /* TODO #54 specified _roi not always - * respected by FrmGrab_Frame, hence - * constructing with _buffer->crop - * instead of _roi to avoid alignment - * problems when saving to video files - */ - _buffer->crop.width, _buffer->crop.height - ); + frame_data, frame_data_length, + frame_width, frame_height + ); FrmGrab_Release(_frame_grabber, _buffer); return true; } diff --git a/src/epiphansdk/epiphansdk_video_source.h b/src/epiphansdk/epiphansdk_video_source.h index bf0c7dd6..10b8bc3b 100644 --- a/src/epiphansdk/epiphansdk_video_source.h +++ b/src/epiphansdk/epiphansdk_video_source.h @@ -42,6 +42,11 @@ class VideoSourceEpiphanSDK : public IVideoSource //! gg::BroadcastDaemon * _daemon; + //! + //! \brief Buffer for converting from ARGB to BGRA + //! + unsigned char *_bgra_data; + public: //! //! \brief Connects to specified port of an Epiphan @@ -50,7 +55,7 @@ class VideoSourceEpiphanSDK : public IVideoSource //! as \c \#define'd in Epiphan device properties //! header //! \param colour_space \c V2U_GRABFRAME_FORMAT_I420 - //! or \c V2U_GRABFRAME_FORMAT_BGR24 + //! or \c V2U_GRABFRAME_FORMAT_ARGB32 //! \throw VideoSourceError if connection attempt //! fails, with a detailed error message //! From 8d1378f5eaf462d37d416ba289fc8c300b95fef7 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Mon, 29 Oct 2018 13:47:41 +0000 Subject: [PATCH 02/36] Issue #9: VideoSourceFactory uses Epiphan SDK video source for BGRA captures using Epiphan cards --- src/api/videosourcefactory.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/api/videosourcefactory.cpp b/src/api/videosourcefactory.cpp index 5546a79a..28bf3d02 100644 --- a/src/api/videosourcefactory.cpp +++ b/src/api/videosourcefactory.cpp @@ -63,11 +63,12 @@ IVideoSource * VideoSourceFactory::get_device(Device device, // BGRA ======================================== case BGRA: -#ifdef USE_OPENCV - src = new VideoSourceOpenCV(0); +#ifdef USE_EPIPHANSDK + src = new VideoSourceEpiphanSDK(Epiphan_DVI2PCIeDuo_DVI, + V2U_GRABFRAME_FORMAT_ARGB32); #else throw VideoSourceError( - "BGRA colour space on Epiphan DVI2PCIe Duo supported only with OpenCV"); + "BGRA colour space on Epiphan DVI2PCIe Duo supported only with Epiphan SDK"); #endif break; @@ -115,11 +116,12 @@ IVideoSource * VideoSourceFactory::get_device(Device device, // BGRA ======================================== case BGRA: -#ifdef USE_OPENCV - src = new VideoSourceOpenCV(1); +#ifdef USE_EPIPHANSDK + src = new VideoSourceEpiphanSDK(Epiphan_DVI2PCIeDuo_SDI, + V2U_GRABFRAME_FORMAT_ARGB32); #else throw VideoSourceError( - "BGRA colour space on Epiphan DVI2PCIe Duo supported only with OpenCV"); + "BGRA colour space on Epiphan DVI2PCIe Duo supported only with Epiphan SDK"); #endif break; From ba99c1685536aa0e525a793671e51cb3d15bb58e Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Mon, 29 Oct 2018 13:54:15 +0000 Subject: [PATCH 03/36] Issue #9: using malloc instead of realloc --- src/epiphansdk/epiphansdk_video_source.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index a0a7725f..63afcd0b 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -45,8 +45,8 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( _full.height = 1080; if (_colour == BGRA) { - _bgra_data = reinterpret_cast(realloc( - _bgra_data, 4 * _full.width * _full.height * sizeof(unsigned char) + _bgra_data = reinterpret_cast(malloc( + 4 * _full.width * _full.height * sizeof(unsigned char) )); } get_full_frame(); From ccebfed51d2f60694ab09375a07d2211f554d6b0 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Mon, 29 Oct 2018 15:19:10 +0000 Subject: [PATCH 04/36] Issue #9: explicitly resetting Epiphan SDK frame buffer --- src/epiphansdk/epiphansdk_video_source.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index 63afcd0b..7183a240 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -11,6 +11,7 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( , _flags(0) , _daemon(nullptr) , _bgra_data(nullptr) + , _buffer(nullptr) { FrmGrab_Init(); @@ -120,6 +121,7 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) frame_width, frame_height ); FrmGrab_Release(_frame_grabber, _buffer); + _buffer = nullptr; return true; } else From de4cd9087d062cfa6db72bfde29925a109782cca Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 08:28:11 +0000 Subject: [PATCH 05/36] Issue #9: added an app for profiling ARGB => BGRA conversions --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 125 +++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/tests/rgbswap/profile_argb_to_bgra.cpp diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp new file mode 100644 index 00000000..55e512b3 --- /dev/null +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#ifdef USE_FFMPEG +extern "C" { +#include +} +#endif + +using namespace std; +using namespace std::chrono; + +template +void copy_strided(T begin , T end, T dest, int length) +{ + int num_copied = 0; + copy_if(begin, end, dest, [&num_copied,length]( double x ) + { + return (num_copied++ % length == 0); + } + ); +} + +bool argb_same_as_bgra(const unsigned char *argb, + const unsigned char *bgra, + size_t l) +{ + for (size_t i = 0; i < l; i += 4) + if (argb[i] != bgra[i+3] or argb[i+1] != bgra[i+2] or + argb[i+2] != bgra[i+1] or argb[i+3] != bgra[i]) + return false; + return true; +} + +int main(int argc, char *argv[]) +{ + // ARGB with random values + size_t w = 1920, h = 1080; + if (argc >= 3) + { + w = atoi(argv[1]); + h = atoi(argv[2]); + } + cout << "Profiling ARGB => BGRA conversion for " + << w << " x " << h << " image" << endl; + size_t l = 4 * w * h; + unsigned char *argb = nullptr; + argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); + for (size_t i = 0; i < l; i++) + { + argb[i] = i % 32; + argb[i+1] = argb[i] * 4; + argb[i+2] = i % 256; + argb[i+3] = 255; + } + + // ARGB => BGRA in a strided loop + unsigned char *bgra_loop = nullptr; + bgra_loop = reinterpret_cast(malloc(l * sizeof(unsigned char))); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + for (size_t i = 0; i < l; i += 4) + { + bgra_loop[i] = argb[i+3]; + bgra_loop[i+1] = argb[i+2]; + bgra_loop[i+2] = argb[i+1]; + bgra_loop[i+3] = argb[i]; + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + auto duration = duration_cast( t2 - t1 ).count(); + cout << "Loop (" << (argb_same_as_bgra(argb, bgra_loop, l) ? "success" : "failure") + << ") took: " << duration << " usec" << endl; + free(bgra_loop); + + // simple memcopy (no ARGB => BGRA) + unsigned char *argb_memcpy = nullptr; + argb_memcpy = reinterpret_cast(malloc(l * sizeof(unsigned char))); + t1 = high_resolution_clock::now(); + memcpy(argb, argb_memcpy, l * sizeof(unsigned char)); + t2 = high_resolution_clock::now(); + duration = duration_cast( t2 - t1 ).count(); + cout << "memcpy took: " << duration << " usec" << endl; + free(argb_memcpy); + + // ARGB => BGRA with a functor + unsigned char *bgra_functor = nullptr; + bgra_functor = reinterpret_cast(malloc(l * sizeof(unsigned char))); + t1 = high_resolution_clock::now(); + copy_strided(argb + 3, argb + l, bgra_functor, 4); + copy_strided(argb + 2, argb + l, bgra_functor + 1, 4); + copy_strided(argb + 1, argb + l, bgra_functor + 2, 4); + copy_strided(argb, argb + l, bgra_functor + 3, 4); + t2 = high_resolution_clock::now(); + duration = duration_cast( t2 - t1 ).count(); + cout << "functor (" << (argb_same_as_bgra(argb, bgra_functor, l) ? "success" : "failure") + << ") took: " << duration << " usec" << endl; + free(bgra_functor); + +#ifdef USE_FFMPEG + // ARGB => BGRA using FFmpeg + unsigned char *bgra_ffmpeg = nullptr; + bgra_ffmpeg = reinterpret_cast(malloc(l * sizeof(unsigned char))); + unsigned char *srcSlice[] = {argb}; + int srcStride[] = {4}; + int srcSliceY = 0; + int srcSliceH = h; + unsigned char *dst[] = {bgra_ffmpeg}; + int dstStride[] = {4}; + int srcW = w, srcH = h, dstW = w, dstH = h; + AVPixelFormat srcFormat = AV_PIX_FMT_ARGB, dstFormat = AV_PIX_FMT_BGRA; + SwsContext *c = sws_getCachedContext(nullptr, srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0, nullptr, nullptr, nullptr); + t1 = high_resolution_clock::now(); + sws_scale(c, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride); + t2 = high_resolution_clock::now(); + duration = duration_cast( t2 - t1 ).count(); + cout << "ffmpeg (" << (argb_same_as_bgra(argb, bgra_ffmpeg, l) ? "success" : "failure") + << ") took: " << duration << " usec" << endl; + free(bgra_ffmpeg); +#endif + + // free all memory + free(argb); + return EXIT_SUCCESS; +} From 3f0e01143cc88f11b0ff6309b84d9dc7f21bd6a0 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 08:28:25 +0000 Subject: [PATCH 06/36] Issue #9: activated newly added profiling app in CMake --- src/tests/CMakeLists.txt | 3 +++ src/tests/rgbswap/CMakeLists.txt | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/tests/rgbswap/CMakeLists.txt diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index d44206cb..1b9138ce 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -74,3 +74,6 @@ endif(USE_FILES) # VideoSourceFactory leak checker ADD_SUBDIRECTORY(videosourcefactory) + +# Simple colour space conversion profiling +ADD_SUBDIRECTORY(rgbswap) diff --git a/src/tests/rgbswap/CMakeLists.txt b/src/tests/rgbswap/CMakeLists.txt new file mode 100644 index 00000000..cae348f2 --- /dev/null +++ b/src/tests/rgbswap/CMakeLists.txt @@ -0,0 +1,11 @@ +SET(ARGB_TO_BGRA_PROFILER argb_to_bgra_profiler) +ADD_EXECUTABLE( + ${ARGB_TO_BGRA_PROFILER} + ${CMAKE_SOURCE_DIR}/tests/rgbswap/profile_argb_to_bgra.cpp +) +if(USE_FFMPEG) + SET(ARGB_TO_BGRA_PROFILER_LIBS ${FFmpeg_LIBS}) +endif(USE_FFMPEG) +TARGET_LINK_LIBRARIES( + ${ARGB_TO_BGRA_PROFILER} ${ARGB_TO_BGRA_PROFILER_LIBS} +) From 2b770cc0ac9e0adea3659ab34f7804b5cb89b592 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 08:42:11 +0000 Subject: [PATCH 07/36] Issue #9: revised concepts in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index 55e512b3..11594975 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) copy_strided(argb, argb + l, bgra_functor + 3, 4); t2 = high_resolution_clock::now(); duration = duration_cast( t2 - t1 ).count(); - cout << "functor (" << (argb_same_as_bgra(argb, bgra_functor, l) ? "success" : "failure") + cout << "Function (" << (argb_same_as_bgra(argb, bgra_functor, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; free(bgra_functor); @@ -114,7 +114,7 @@ int main(int argc, char *argv[]) sws_scale(c, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride); t2 = high_resolution_clock::now(); duration = duration_cast( t2 - t1 ).count(); - cout << "ffmpeg (" << (argb_same_as_bgra(argb, bgra_ffmpeg, l) ? "success" : "failure") + cout << "FFmpeg (" << (argb_same_as_bgra(argb, bgra_ffmpeg, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; free(bgra_ffmpeg); #endif From 530a1a6cdd8910f1af48ebf44fd8f6ad7a6fd0df Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:04:41 +0000 Subject: [PATCH 08/36] Issue #46: added an ArgbToBgraConverter class stub --- src/epiphansdk/argb_to_bgra_converter.cpp | 6 ++++++ src/epiphansdk/argb_to_bgra_converter.h | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/epiphansdk/argb_to_bgra_converter.cpp create mode 100644 src/epiphansdk/argb_to_bgra_converter.h diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp new file mode 100644 index 00000000..202c6075 --- /dev/null +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -0,0 +1,6 @@ +#include "argb_to_bgra_converter.h" + +namespace gg +{ + +} diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/argb_to_bgra_converter.h new file mode 100644 index 00000000..8fd6b0e3 --- /dev/null +++ b/src/epiphansdk/argb_to_bgra_converter.h @@ -0,0 +1,17 @@ +#pragma once + +namespace gg +{ + +//! +//! \brief Epiphan SDK seems to support ARGB but not BGRA. +//! This class abstracts the conversion of captured ARGB +//! data to BGRA. +//! \sa VideoSourceEpiphanSDK +//! +class ArgbToBgraConverter +{ + +}; + +} From f890e275d54aad0da7fbaf8d6fbe25a93b511e93 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:05:06 +0000 Subject: [PATCH 09/36] Issue #46: added the ArgbToBgraConverter class to CMake config --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a91bcf6d..656aa20e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -264,7 +264,9 @@ if(USE_EPIPHANSDK) INCLUDE_DIRECTORIES(epiphansdk) LIST(APPEND HEADERS epiphansdk/epiphansdk_video_source.h) + LIST(APPEND HEADERS epiphansdk/argb_to_bgra_converter.h) LIST(APPEND SOURCES epiphansdk/epiphansdk_video_source.cpp) + LIST(APPEND SOURCES epiphansdk/argb_to_bgra_converter.cpp) endif(USE_EPIPHANSDK) # Blackmagic SDK video source From ff7f63e9905d8486645cbe70b27a94c5226ea927 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:15:04 +0000 Subject: [PATCH 10/36] Issue #46: added basic constructor and method stubs to ArgbToBgraConverter --- src/epiphansdk/argb_to_bgra_converter.cpp | 22 +++++++++++++++ src/epiphansdk/argb_to_bgra_converter.h | 34 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index 202c6075..1e8153ee 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -3,4 +3,26 @@ namespace gg { +ArgbToBgraConverter::ArgbToBgraConverter() +{ + +} + +ArgbToBgraConverter::~ArgbToBgraConverter() +{ + +} + +void ArgbToBgraConverter::convert(const unsigned char *argb, + unsigned char *bgra) +{ + +} + +void ArgbToBgraConverter::set_frame_dimensions(size_t width, + size_t height) +{ + +} + } diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/argb_to_bgra_converter.h index 8fd6b0e3..3fd3c67b 100644 --- a/src/epiphansdk/argb_to_bgra_converter.h +++ b/src/epiphansdk/argb_to_bgra_converter.h @@ -1,5 +1,7 @@ #pragma once +#include + namespace gg { @@ -11,7 +13,39 @@ namespace gg //! class ArgbToBgraConverter { +public: + //! + //! \brief Create a converter, which should be + //! initialised by informing it of the frame + //! dimensions + //! \sa set_frame_dimensions + //! + ArgbToBgraConverter(); + + //! + //! \brief Free all allocated resources + //! + ~ArgbToBgraConverter(); + +public: + //! + //! \brief Convert ARGB data in passed buffer to BGRA + //! data, saving it into the passed output buffer. + //! \param argb should be in line with the frame + //! dimensions set before + //! \param bgra should be at least as large as the + //! input buffer + //! \sa set_frame_dimensions + //! + void convert(const unsigned char *argb, unsigned char *bgra); + //! + //! \brief Allocate all resources needed for ARGB to + //! BGRA conversion based on passed frame dimensions + //! \param width + //! \param height + //! + void set_frame_dimensions(size_t width, size_t height); }; } From ddd4487d55a3ed06ce70ee759553c9ca4dd3fc63 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:19:08 +0000 Subject: [PATCH 11/36] Issue #46: added width and height properties to ArgbToBgraConverter --- src/epiphansdk/argb_to_bgra_converter.cpp | 8 +++++++- src/epiphansdk/argb_to_bgra_converter.h | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index 1e8153ee..4a379410 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -1,9 +1,12 @@ #include "argb_to_bgra_converter.h" +#include namespace gg { ArgbToBgraConverter::ArgbToBgraConverter() + : _width(0) + , _height(0) { } @@ -22,7 +25,10 @@ void ArgbToBgraConverter::convert(const unsigned char *argb, void ArgbToBgraConverter::set_frame_dimensions(size_t width, size_t height) { - + assert(width > 0); + assert(height > 0); + _width = width; + _height = height; } } diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/argb_to_bgra_converter.h index 3fd3c67b..710287d7 100644 --- a/src/epiphansdk/argb_to_bgra_converter.h +++ b/src/epiphansdk/argb_to_bgra_converter.h @@ -13,6 +13,17 @@ namespace gg //! class ArgbToBgraConverter { +protected: + //! + //! \brief Width of frames passed for conversion + //! + size_t _width; + + //! + //! \brief Height of frames passed for conversion + //! + size_t _height; + public: //! //! \brief Create a converter, which should be From 34b24eb0cb0103f8a1d24c528885f3c451aef3a6 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:21:52 +0000 Subject: [PATCH 12/36] Issue #46: implemented naive conversion in ArgbToBgraConverter --- src/epiphansdk/argb_to_bgra_converter.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index 4a379410..615f66b9 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -19,7 +19,14 @@ ArgbToBgraConverter::~ArgbToBgraConverter() void ArgbToBgraConverter::convert(const unsigned char *argb, unsigned char *bgra) { - + size_t length = 4 * _width * _height; + for (size_t i = 0; i < length; i += 4) + { + bgra[i] = argb[i+3]; + bgra[i+1] = argb[i+2]; + bgra[i+2] = argb[i+1]; + bgra[i+3] = argb[i]; + } } void ArgbToBgraConverter::set_frame_dimensions(size_t width, From 0edc6773ada44c20713b7cda83c5f1643816560e Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:43:16 +0000 Subject: [PATCH 13/36] Issue #46: added FFmpeg-related members to ArgbToBgraConverter --- src/epiphansdk/argb_to_bgra_converter.cpp | 8 +++++++- src/epiphansdk/argb_to_bgra_converter.h | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index 615f66b9..eb5bfa23 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -7,13 +7,19 @@ namespace gg ArgbToBgraConverter::ArgbToBgraConverter() : _width(0) , _height(0) +#ifdef USE_FFMPEG + , _sws_context(nullptr) +#endif { } ArgbToBgraConverter::~ArgbToBgraConverter() { - +#ifdef USE_FFMPEG + sws_freeContext(_sws_context); + _sws_context = nullptr; +#endif } void ArgbToBgraConverter::convert(const unsigned char *argb, diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/argb_to_bgra_converter.h index 710287d7..9f432be8 100644 --- a/src/epiphansdk/argb_to_bgra_converter.h +++ b/src/epiphansdk/argb_to_bgra_converter.h @@ -1,6 +1,11 @@ #pragma once #include +#ifdef USE_FFMPEG +extern "C" { +#include +} +#endif namespace gg { @@ -24,6 +29,16 @@ class ArgbToBgraConverter //! size_t _height; +#ifdef USE_FFMPEG + unsigned char *_sws_srcSlice[1]; + int _sws_srcStride[1] = {4}; + unsigned char *_sws_dst[1]; + int _sws_dstStride[1] = {4}; + AVPixelFormat _sws_srcFormat = AV_PIX_FMT_ARGB; + AVPixelFormat _sws_dstFormat = AV_PIX_FMT_BGRA; + SwsContext *_sws_context; +#endif + public: //! //! \brief Create a converter, which should be From b299611502c55ea5c14f12ed6e2ba1858f28f013 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 09:44:45 +0000 Subject: [PATCH 14/36] Issue #46: implemented FFmpeg-supported ARGB-to-BGRA conversion in ArgbToBgraConverter --- src/epiphansdk/argb_to_bgra_converter.cpp | 18 +++++++++++++++++- src/epiphansdk/argb_to_bgra_converter.h | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index eb5bfa23..775666f1 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -22,9 +22,16 @@ ArgbToBgraConverter::~ArgbToBgraConverter() #endif } -void ArgbToBgraConverter::convert(const unsigned char *argb, +void ArgbToBgraConverter::convert(unsigned char *argb, unsigned char *bgra) { +#ifdef USE_FFMPEG + _sws_srcSlice[0] = argb; + _sws_dst[0] = bgra; + sws_scale(_sws_context, + _sws_srcSlice, _sws_srcStride, 0, _height, + _sws_dst, _sws_dstStride); +#else size_t length = 4 * _width * _height; for (size_t i = 0; i < length; i += 4) { @@ -33,6 +40,7 @@ void ArgbToBgraConverter::convert(const unsigned char *argb, bgra[i+2] = argb[i+1]; bgra[i+3] = argb[i]; } +#endif } void ArgbToBgraConverter::set_frame_dimensions(size_t width, @@ -42,6 +50,14 @@ void ArgbToBgraConverter::set_frame_dimensions(size_t width, assert(height > 0); _width = width; _height = height; +#ifdef USE_FFMPEG + _sws_context = sws_getCachedContext( + _sws_context, + _width, _height, _sws_srcFormat, + _width, _height, _sws_dstFormat, + 0, nullptr, nullptr, nullptr // advanced + ); +#endif } } diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/argb_to_bgra_converter.h index 9f432be8..56b6e38b 100644 --- a/src/epiphansdk/argb_to_bgra_converter.h +++ b/src/epiphansdk/argb_to_bgra_converter.h @@ -63,7 +63,7 @@ class ArgbToBgraConverter //! input buffer //! \sa set_frame_dimensions //! - void convert(const unsigned char *argb, unsigned char *bgra); + void convert(unsigned char *argb, unsigned char *bgra); //! //! \brief Allocate all resources needed for ARGB to From ab5406571093d08b42656bca2969b0dbc43bb061 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 10:01:52 +0000 Subject: [PATCH 15/36] Issue #46: set_frame_dimensions is now no-op if dims do not change --- src/epiphansdk/argb_to_bgra_converter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index 775666f1..e726eabb 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -48,6 +48,9 @@ void ArgbToBgraConverter::set_frame_dimensions(size_t width, { assert(width > 0); assert(height > 0); + if (_width == width and _height == height) + return; + _width = width; _height = height; #ifdef USE_FFMPEG From aa1ed4421f05db38cd4873090f2507f468cc2941 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 10:06:54 +0000 Subject: [PATCH 16/36] Issue #46: EpiphanSDK video source now uses ArgbToBgraConverter to abstract colour conversion out --- src/epiphansdk/epiphansdk_video_source.cpp | 9 ++------- src/epiphansdk/epiphansdk_video_source.h | 6 ++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index 7183a240..e0e8f6f8 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -103,13 +103,8 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) frame_data = data; break; case BGRA: - for (size_t i = 0; i < frame_data_length; i += 4) - { - _bgra_data[i] = data[i + 3]; - _bgra_data[i + 1] = data[i + 2]; - _bgra_data[i + 2] = data[i + 1]; - _bgra_data[i + 3] = data[i]; - } + _argb_to_bgra.set_frame_dimensions(frame_width, frame_height); + _argb_to_bgra.convert(data, _bgra_data); frame_data = _bgra_data; break; default: diff --git a/src/epiphansdk/epiphansdk_video_source.h b/src/epiphansdk/epiphansdk_video_source.h index 10b8bc3b..b44dc311 100644 --- a/src/epiphansdk/epiphansdk_video_source.h +++ b/src/epiphansdk/epiphansdk_video_source.h @@ -3,6 +3,7 @@ #include "ivideosource.h" #include "macros.h" #include "broadcastdaemon.h" +#include "argb_to_bgra_converter.h" namespace gg { @@ -47,6 +48,11 @@ class VideoSourceEpiphanSDK : public IVideoSource //! unsigned char *_bgra_data; + //! + //! \brief ARGB to BGRA converter + //! + ArgbToBgraConverter _argb_to_bgra; + public: //! //! \brief Connects to specified port of an Epiphan From 25a351053a6c9e4228c1f7b3909585001ab4524e Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 13:09:03 +0000 Subject: [PATCH 17/36] Issue #46: protecting frame capture with a mutex in Epiphan SDK video source --- src/epiphansdk/epiphansdk_video_source.cpp | 2 ++ src/epiphansdk/epiphansdk_video_source.h | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index e0e8f6f8..dac6c49c 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -83,6 +83,8 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) // TODO - exception GiftGrab#42 return false; + std::lock_guard buffer_lock_guard(_buffer_lock); + _buffer = FrmGrab_Frame(_frame_grabber, _flags, &_roi); if (_buffer) { diff --git a/src/epiphansdk/epiphansdk_video_source.h b/src/epiphansdk/epiphansdk_video_source.h index b44dc311..7d61f225 100644 --- a/src/epiphansdk/epiphansdk_video_source.h +++ b/src/epiphansdk/epiphansdk_video_source.h @@ -38,6 +38,13 @@ class VideoSourceEpiphanSDK : public IVideoSource //! V2U_GrabFrame2 * _buffer; + //! + //! \brief This mutex to be locked when + //! accessing the buffer + //! \sa _buffer + //! + std::mutex _buffer_lock; + //! //! \brief //! From aa2ac5ee6d6c4613fabba33862c8a4c93e1fe316 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 13:36:47 +0000 Subject: [PATCH 18/36] Issue #46: using BGRA-specific frame rate in Epiphan SDK video source --- src/epiphansdk/epiphansdk_video_source.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index dac6c49c..85c64fbc 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -127,6 +127,7 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) double VideoSourceEpiphanSDK::get_frame_rate() { + double frame_rate = -1; if (_frame_grabber) { #if defined(Epiphan_DVI2PCIeDuo_DVI) and \ @@ -135,9 +136,18 @@ double VideoSourceEpiphanSDK::get_frame_rate() defined(Epiphan_DVI2PCIeDuo_SDI_MAX_FRAME_RATE) std::string port_id = FrmGrab_GetId(_frame_grabber); if (port_id == Epiphan_DVI2PCIeDuo_DVI) - return Epiphan_DVI2PCIeDuo_DVI_MAX_FRAME_RATE; + frame_rate = Epiphan_DVI2PCIeDuo_DVI_MAX_FRAME_RATE; else if (port_id == Epiphan_DVI2PCIeDuo_SDI) - return Epiphan_DVI2PCIeDuo_SDI_MAX_FRAME_RATE; + frame_rate = Epiphan_DVI2PCIeDuo_SDI_MAX_FRAME_RATE; + if (frame_rate > 0) + { + /* The above max frame rates are defined for I420, + * and are halved for BGRA, due to hardware bandwidth + */ + if (_colour == BGRA) + frame_rate /= 2.0; + return frame_rate; + } #endif } From a7886f8661a44f6a90eaf2b04201f38993e821d4 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 14:49:04 +0000 Subject: [PATCH 19/36] Issue #46: fixed image stride definitions --- src/epiphansdk/argb_to_bgra_converter.cpp | 2 ++ src/epiphansdk/argb_to_bgra_converter.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index e726eabb..7dd4066b 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -27,7 +27,9 @@ void ArgbToBgraConverter::convert(unsigned char *argb, { #ifdef USE_FFMPEG _sws_srcSlice[0] = argb; + _sws_srcStride[0] = _width; _sws_dst[0] = bgra; + _sws_dstStride[0] = _width; sws_scale(_sws_context, _sws_srcSlice, _sws_srcStride, 0, _height, _sws_dst, _sws_dstStride); diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/argb_to_bgra_converter.h index 56b6e38b..53c7cc77 100644 --- a/src/epiphansdk/argb_to_bgra_converter.h +++ b/src/epiphansdk/argb_to_bgra_converter.h @@ -31,9 +31,9 @@ class ArgbToBgraConverter #ifdef USE_FFMPEG unsigned char *_sws_srcSlice[1]; - int _sws_srcStride[1] = {4}; + int _sws_srcStride[1]; unsigned char *_sws_dst[1]; - int _sws_dstStride[1] = {4}; + int _sws_dstStride[1]; AVPixelFormat _sws_srcFormat = AV_PIX_FMT_ARGB; AVPixelFormat _sws_dstFormat = AV_PIX_FMT_BGRA; SwsContext *_sws_context; From 4b025b70fc8e89ffe01b0360cbd44ed8765518c2 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 18:29:33 +0000 Subject: [PATCH 20/36] Issue #46: conversion profiler now supports reading an image and also saving the result of FFmpeg conversion --- src/tests/rgbswap/CMakeLists.txt | 5 ++- src/tests/rgbswap/profile_argb_to_bgra.cpp | 45 +++++++++++++++++----- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/tests/rgbswap/CMakeLists.txt b/src/tests/rgbswap/CMakeLists.txt index cae348f2..89297b8e 100644 --- a/src/tests/rgbswap/CMakeLists.txt +++ b/src/tests/rgbswap/CMakeLists.txt @@ -4,8 +4,11 @@ ADD_EXECUTABLE( ${CMAKE_SOURCE_DIR}/tests/rgbswap/profile_argb_to_bgra.cpp ) if(USE_FFMPEG) - SET(ARGB_TO_BGRA_PROFILER_LIBS ${FFmpeg_LIBS}) + LIST(APPEND ARGB_TO_BGRA_PROFILER_LIBS ${FFmpeg_LIBS}) endif(USE_FFMPEG) +if(USE_OPENCV) + LIST(APPEND ARGB_TO_BGRA_PROFILER_LIBS ${OpenCV_LIBS}) +endif(USE_OPENCV) TARGET_LINK_LIBRARIES( ${ARGB_TO_BGRA_PROFILER} ${ARGB_TO_BGRA_PROFILER_LIBS} ) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index 11594975..d286a46e 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -8,6 +8,9 @@ extern "C" { #include } #endif +#ifdef USE_OPENCV +#include +#endif using namespace std; using namespace std::chrono; @@ -38,22 +41,43 @@ int main(int argc, char *argv[]) { // ARGB with random values size_t w = 1920, h = 1080; - if (argc >= 3) + size_t l; + unsigned char *argb = nullptr; + bool compose = true; + if (argc == 2) + { +#ifdef USE_OPENCV + cv::Mat orig = cv::imread(argv[1]), _bgra; + w = orig.cols; + h = orig.rows; + cv::cvtColor(orig, _bgra, cv::COLOR_BGR2BGRA); + cv::Mat _argb(_bgra.size(), _bgra.type()); + int from_to[] = { 0,3, 1,2, 2,1, 3,0 }; + cv::mixChannels(&_bgra, 1, &_argb, 1, from_to, 4); + compose = false; + l = 4 * w * h; + argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); + memcpy(argb, _argb.data, l * sizeof(unsigned char)); +#endif + } + else if (argc == 3) { w = atoi(argv[1]); h = atoi(argv[2]); } cout << "Profiling ARGB => BGRA conversion for " << w << " x " << h << " image" << endl; - size_t l = 4 * w * h; - unsigned char *argb = nullptr; - argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); - for (size_t i = 0; i < l; i++) + if (compose) { - argb[i] = i % 32; - argb[i+1] = argb[i] * 4; - argb[i+2] = i % 256; - argb[i+3] = 255; + l = 4 * w * h; + argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); + for (size_t i = 0; i < l; i++) + { + argb[i] = i % 32; + argb[i+1] = argb[i] * 4; + argb[i+2] = i % 256; + argb[i+3] = 255; + } } // ARGB => BGRA in a strided loop @@ -118,6 +142,9 @@ int main(int argc, char *argv[]) << ") took: " << duration << " usec" << endl; free(bgra_ffmpeg); #endif +#ifdef USE_OPENCV + cv::imwrite("bgra_ffmpeg.png", cv::Mat(h, w, CV_8UC4, bgra_ffmpeg)); +#endif // free all memory free(argb); From 88681c57220a1f224e6fc45cf70291ad445ca4c4 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 18:30:35 +0000 Subject: [PATCH 21/36] Issue #46: renamed all functor => function for clarity --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index d286a46e..a5d2f5d7 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -107,19 +107,19 @@ int main(int argc, char *argv[]) cout << "memcpy took: " << duration << " usec" << endl; free(argb_memcpy); - // ARGB => BGRA with a functor - unsigned char *bgra_functor = nullptr; - bgra_functor = reinterpret_cast(malloc(l * sizeof(unsigned char))); + // ARGB => BGRA with a function + unsigned char *bgra_function = nullptr; + bgra_function = reinterpret_cast(malloc(l * sizeof(unsigned char))); t1 = high_resolution_clock::now(); - copy_strided(argb + 3, argb + l, bgra_functor, 4); - copy_strided(argb + 2, argb + l, bgra_functor + 1, 4); - copy_strided(argb + 1, argb + l, bgra_functor + 2, 4); - copy_strided(argb, argb + l, bgra_functor + 3, 4); + copy_strided(argb + 3, argb + l, bgra_function, 4); + copy_strided(argb + 2, argb + l, bgra_function + 1, 4); + copy_strided(argb + 1, argb + l, bgra_function + 2, 4); + copy_strided(argb, argb + l, bgra_function + 3, 4); t2 = high_resolution_clock::now(); duration = duration_cast( t2 - t1 ).count(); - cout << "Function (" << (argb_same_as_bgra(argb, bgra_functor, l) ? "success" : "failure") + cout << "Function (" << (argb_same_as_bgra(argb, bgra_function, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; - free(bgra_functor); + free(bgra_function); #ifdef USE_FFMPEG // ARGB => BGRA using FFmpeg From a167db600be24a7830908cd764566bec3586013f Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 18:43:54 +0000 Subject: [PATCH 22/36] Issue #46: profiler app writes looped conversion image as well --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index a5d2f5d7..dcdbe870 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -96,6 +96,13 @@ int main(int argc, char *argv[]) cout << "Loop (" << (argb_same_as_bgra(argb, bgra_loop, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; free(bgra_loop); +#ifdef USE_OPENCV + { + cv::Mat _bgra(h, w, CV_8UC4, bgra_loop), bgr; + cv::cvtColor(_bgra, bgr, cv::COLOR_BGRA2BGR); + cv::imwrite("bgra_loop.png", bgr); + } +#endif // simple memcopy (no ARGB => BGRA) unsigned char *argb_memcpy = nullptr; @@ -143,7 +150,11 @@ int main(int argc, char *argv[]) free(bgra_ffmpeg); #endif #ifdef USE_OPENCV - cv::imwrite("bgra_ffmpeg.png", cv::Mat(h, w, CV_8UC4, bgra_ffmpeg)); + { + cv::Mat _bgra(h, w, CV_8UC4, bgra_ffmpeg), bgr; + cv::cvtColor(_bgra, bgr, cv::COLOR_BGRA2BGR); + cv::imwrite("bgra_ffmpeg.png", bgr); + } #endif // free all memory From b80276d07c1befda70f2cf43ce9360dcc0d3a3bf Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Tue, 30 Oct 2018 18:44:11 +0000 Subject: [PATCH 23/36] Issue #46: fixed FFmpeg strides in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index dcdbe870..081d96ef 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -133,11 +133,11 @@ int main(int argc, char *argv[]) unsigned char *bgra_ffmpeg = nullptr; bgra_ffmpeg = reinterpret_cast(malloc(l * sizeof(unsigned char))); unsigned char *srcSlice[] = {argb}; - int srcStride[] = {4}; + int srcStride[] = {4 * w}; int srcSliceY = 0; int srcSliceH = h; unsigned char *dst[] = {bgra_ffmpeg}; - int dstStride[] = {4}; + int dstStride[] = {4 * w}; int srcW = w, srcH = h, dstW = w, dstH = h; AVPixelFormat srcFormat = AV_PIX_FMT_ARGB, dstFormat = AV_PIX_FMT_BGRA; SwsContext *c = sws_getCachedContext(nullptr, srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0, nullptr, nullptr, nullptr); From 496539682f4d0dca8e6ad5e9a2757c634449731b Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 07:16:07 +0000 Subject: [PATCH 24/36] Issue #46: stride is now width not packed pixel size --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index 081d96ef..0d102ce1 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -133,11 +133,11 @@ int main(int argc, char *argv[]) unsigned char *bgra_ffmpeg = nullptr; bgra_ffmpeg = reinterpret_cast(malloc(l * sizeof(unsigned char))); unsigned char *srcSlice[] = {argb}; - int srcStride[] = {4 * w}; + int srcStride[] = {static_cast(w)}; int srcSliceY = 0; int srcSliceH = h; unsigned char *dst[] = {bgra_ffmpeg}; - int dstStride[] = {4 * w}; + int dstStride[] = {static_cast(w)}; int srcW = w, srcH = h, dstW = w, dstH = h; AVPixelFormat srcFormat = AV_PIX_FMT_ARGB, dstFormat = AV_PIX_FMT_BGRA; SwsContext *c = sws_getCachedContext(nullptr, srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0, nullptr, nullptr, nullptr); From 2c91da47ce580b6fdb6427bcc44729a8c4df9581 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 07:20:00 +0000 Subject: [PATCH 25/36] Issue #46: fixed memcpy src-dst order in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index 0d102ce1..90516311 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -108,7 +108,7 @@ int main(int argc, char *argv[]) unsigned char *argb_memcpy = nullptr; argb_memcpy = reinterpret_cast(malloc(l * sizeof(unsigned char))); t1 = high_resolution_clock::now(); - memcpy(argb, argb_memcpy, l * sizeof(unsigned char)); + memcpy(argb_memcpy, argb, l * sizeof(unsigned char)); t2 = high_resolution_clock::now(); duration = duration_cast( t2 - t1 ).count(); cout << "memcpy took: " << duration << " usec" << endl; From 5b62e59679cb9b83f53bf09f039e29d7fb2694e5 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 07:54:26 +0000 Subject: [PATCH 26/36] Issue #46: writing original BGR out, and composing ARGB from BGR data in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index 90516311..de994ce3 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -47,17 +47,20 @@ int main(int argc, char *argv[]) if (argc == 2) { #ifdef USE_OPENCV - cv::Mat orig = cv::imread(argv[1]), _bgra; + cv::Mat orig = cv::imread(argv[1]); + cv::imwrite("bgr_orig.png", orig); w = orig.cols; h = orig.rows; - cv::cvtColor(orig, _bgra, cv::COLOR_BGR2BGRA); - cv::Mat _argb(_bgra.size(), _bgra.type()); - int from_to[] = { 0,3, 1,2, 2,1, 3,0 }; - cv::mixChannels(&_bgra, 1, &_argb, 1, from_to, 4); compose = false; l = 4 * w * h; argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); - memcpy(argb, _argb.data, l * sizeof(unsigned char)); + for (size_t i = 0, j = 0; i < l; i +=4, j += 3) + { + argb[i] = 255; + argb[i+1] = orig.data[j+2]; + argb[i+2] = orig.data[j+1]; + argb[i+3] = orig.data[j]; + } #endif } else if (argc == 3) From 4117583fcd5e826d18d5b1a0208b21c7db6255ce Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 07:57:22 +0000 Subject: [PATCH 27/36] Issue #46: using copy_strided as last one in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index de994ce3..ed47103d 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -117,20 +117,6 @@ int main(int argc, char *argv[]) cout << "memcpy took: " << duration << " usec" << endl; free(argb_memcpy); - // ARGB => BGRA with a function - unsigned char *bgra_function = nullptr; - bgra_function = reinterpret_cast(malloc(l * sizeof(unsigned char))); - t1 = high_resolution_clock::now(); - copy_strided(argb + 3, argb + l, bgra_function, 4); - copy_strided(argb + 2, argb + l, bgra_function + 1, 4); - copy_strided(argb + 1, argb + l, bgra_function + 2, 4); - copy_strided(argb, argb + l, bgra_function + 3, 4); - t2 = high_resolution_clock::now(); - duration = duration_cast( t2 - t1 ).count(); - cout << "Function (" << (argb_same_as_bgra(argb, bgra_function, l) ? "success" : "failure") - << ") took: " << duration << " usec" << endl; - free(bgra_function); - #ifdef USE_FFMPEG // ARGB => BGRA using FFmpeg unsigned char *bgra_ffmpeg = nullptr; @@ -160,6 +146,20 @@ int main(int argc, char *argv[]) } #endif + // ARGB => BGRA with a function + unsigned char *bgra_function = nullptr; + bgra_function = reinterpret_cast(malloc(l * sizeof(unsigned char))); + t1 = high_resolution_clock::now(); + copy_strided(argb + 3, argb + l, bgra_function, 4); + copy_strided(argb + 2, argb + l, bgra_function + 1, 4); + copy_strided(argb + 1, argb + l, bgra_function + 2, 4); + copy_strided(argb, argb + l, bgra_function + 3, 4); + t2 = high_resolution_clock::now(); + duration = duration_cast( t2 - t1 ).count(); + cout << "Function (" << (argb_same_as_bgra(argb, bgra_function, l) ? "success" : "failure") + << ") took: " << duration << " usec" << endl; + free(bgra_function); + // free all memory free(argb); return EXIT_SUCCESS; From cb00184521a657a0717f139bc7b1d7ab1fc6232e Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 08:01:20 +0000 Subject: [PATCH 28/36] Issue #46: outputting bgra_function result as well in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index ed47103d..d960af2e 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -159,6 +159,13 @@ int main(int argc, char *argv[]) cout << "Function (" << (argb_same_as_bgra(argb, bgra_function, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; free(bgra_function); +#ifdef USE_OPENCV + { + cv::Mat _bgra(h, w, CV_8UC4, bgra_function), bgr; + cv::cvtColor(_bgra, bgr, cv::COLOR_BGRA2BGR); + cv::imwrite("bgra_function.png", bgr); + } +#endif // free all memory free(argb); From 8f8f26b91738c20e64d12f2fc7cac12069455224 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 11:16:07 +0000 Subject: [PATCH 29/36] Issue #46: fixed pointer freeing order in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index d960af2e..4949e91d 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -98,14 +98,13 @@ int main(int argc, char *argv[]) auto duration = duration_cast( t2 - t1 ).count(); cout << "Loop (" << (argb_same_as_bgra(argb, bgra_loop, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; - free(bgra_loop); #ifdef USE_OPENCV { - cv::Mat _bgra(h, w, CV_8UC4, bgra_loop), bgr; - cv::cvtColor(_bgra, bgr, cv::COLOR_BGRA2BGR); - cv::imwrite("bgra_loop.png", bgr); + cv::Mat _bgra(h, w, CV_8UC4, bgra_loop); + cv::imwrite("bgra_loop.png", _bgra); } #endif + free(bgra_loop); // simple memcopy (no ARGB => BGRA) unsigned char *argb_memcpy = nullptr; @@ -136,8 +135,6 @@ int main(int argc, char *argv[]) duration = duration_cast( t2 - t1 ).count(); cout << "FFmpeg (" << (argb_same_as_bgra(argb, bgra_ffmpeg, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; - free(bgra_ffmpeg); -#endif #ifdef USE_OPENCV { cv::Mat _bgra(h, w, CV_8UC4, bgra_ffmpeg), bgr; @@ -145,6 +142,8 @@ int main(int argc, char *argv[]) cv::imwrite("bgra_ffmpeg.png", bgr); } #endif + free(bgra_ffmpeg); +#endif // ARGB => BGRA with a function unsigned char *bgra_function = nullptr; From 32f576d45fed59275c6432ed5d043491e7572476 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 11:19:25 +0000 Subject: [PATCH 30/36] Revert "Issue #46: stride is now width not packed pixel size" This reverts commit 496539682f4d0dca8e6ad5e9a2757c634449731b. --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index 4949e91d..b756605b 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -121,11 +121,11 @@ int main(int argc, char *argv[]) unsigned char *bgra_ffmpeg = nullptr; bgra_ffmpeg = reinterpret_cast(malloc(l * sizeof(unsigned char))); unsigned char *srcSlice[] = {argb}; - int srcStride[] = {static_cast(w)}; + int srcStride[] = {4 * w}; int srcSliceY = 0; int srcSliceH = h; unsigned char *dst[] = {bgra_ffmpeg}; - int dstStride[] = {static_cast(w)}; + int dstStride[] = {4 * w}; int srcW = w, srcH = h, dstW = w, dstH = h; AVPixelFormat srcFormat = AV_PIX_FMT_ARGB, dstFormat = AV_PIX_FMT_BGRA; SwsContext *c = sws_getCachedContext(nullptr, srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0, nullptr, nullptr, nullptr); From 62246d2cb1ef3a3a338042b70960ff17a3d5c1ba Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 11:21:49 +0000 Subject: [PATCH 31/36] Issue #46: added a static cast from size_t to int to make FFmpeg function happy in profiler app --- src/tests/rgbswap/profile_argb_to_bgra.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_argb_to_bgra.cpp index b756605b..13e7d475 100644 --- a/src/tests/rgbswap/profile_argb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_argb_to_bgra.cpp @@ -121,11 +121,11 @@ int main(int argc, char *argv[]) unsigned char *bgra_ffmpeg = nullptr; bgra_ffmpeg = reinterpret_cast(malloc(l * sizeof(unsigned char))); unsigned char *srcSlice[] = {argb}; - int srcStride[] = {4 * w}; + int srcStride[] = {static_cast(4 * w)}; int srcSliceY = 0; int srcSliceH = h; unsigned char *dst[] = {bgra_ffmpeg}; - int dstStride[] = {4 * w}; + int dstStride[] = {static_cast(4 * w)}; int srcW = w, srcH = h, dstW = w, dstH = h; AVPixelFormat srcFormat = AV_PIX_FMT_ARGB, dstFormat = AV_PIX_FMT_BGRA; SwsContext *c = sws_getCachedContext(nullptr, srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0, nullptr, nullptr, nullptr); From e738da5cdc7f279355864706b4679e43acee2c38 Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Wed, 31 Oct 2018 11:24:25 +0000 Subject: [PATCH 32/36] Issue #46: ArgbToBgraConverter now uses 4*width as stride --- src/epiphansdk/argb_to_bgra_converter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/argb_to_bgra_converter.cpp index 7dd4066b..b1f56f61 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/argb_to_bgra_converter.cpp @@ -27,9 +27,9 @@ void ArgbToBgraConverter::convert(unsigned char *argb, { #ifdef USE_FFMPEG _sws_srcSlice[0] = argb; - _sws_srcStride[0] = _width; + _sws_srcStride[0] = 4 * _width; _sws_dst[0] = bgra; - _sws_dstStride[0] = _width; + _sws_dstStride[0] = 4 * _width; sws_scale(_sws_context, _sws_srcSlice, _sws_srcStride, 0, _height, _sws_dst, _sws_dstStride); From 3774ec9907ee627edea2907c1a51442b7136c15c Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Thu, 1 Nov 2018 16:17:26 +0000 Subject: [PATCH 33/36] Issue #46: using buttom-up flag with for ARGB captures --- src/epiphansdk/epiphansdk_video_source.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index 85c64fbc..f8507610 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -32,7 +32,10 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( else if (colour_space == V2U_GRABFRAME_FORMAT_I420) _colour = I420; else + { _colour = BGRA; + _flags |= V2U_GRABFRAME_BOTTOM_UP_FLAG; // for some reason without this the image is flipped + } _flags |= colour_space; VideoFrame frame(_colour); From f0ba32dabf4bb614ea3e0422b93fdc08d483f9ee Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Fri, 2 Nov 2018 07:30:00 +0000 Subject: [PATCH 34/36] Issue #46: EpiphanSDK video source uses RGB to capture with BGRA format --- src/CMakeLists.txt | 4 +-- src/api/videosourcefactory.cpp | 4 +-- src/epiphansdk/epiphansdk_video_source.cpp | 21 +++++++------- src/epiphansdk/epiphansdk_video_source.h | 12 ++++---- ...onverter.cpp => rgb_to_bgra_converter.cpp} | 28 +++++++++---------- ...ra_converter.h => rgb_to_bgra_converter.h} | 20 ++++++------- ...gb_to_bgra.cpp => profile_rgb_to_bgra.cpp} | 0 7 files changed, 45 insertions(+), 44 deletions(-) rename src/epiphansdk/{argb_to_bgra_converter.cpp => rgb_to_bgra_converter.cpp} (61%) rename src/epiphansdk/{argb_to_bgra_converter.h => rgb_to_bgra_converter.h} (72%) rename src/tests/rgbswap/{profile_argb_to_bgra.cpp => profile_rgb_to_bgra.cpp} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 656aa20e..01c3dab4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -264,9 +264,9 @@ if(USE_EPIPHANSDK) INCLUDE_DIRECTORIES(epiphansdk) LIST(APPEND HEADERS epiphansdk/epiphansdk_video_source.h) - LIST(APPEND HEADERS epiphansdk/argb_to_bgra_converter.h) + LIST(APPEND HEADERS epiphansdk/rgb_to_bgra_converter.h) LIST(APPEND SOURCES epiphansdk/epiphansdk_video_source.cpp) - LIST(APPEND SOURCES epiphansdk/argb_to_bgra_converter.cpp) + LIST(APPEND SOURCES epiphansdk/rgb_to_bgra_converter.cpp) endif(USE_EPIPHANSDK) # Blackmagic SDK video source diff --git a/src/api/videosourcefactory.cpp b/src/api/videosourcefactory.cpp index 28bf3d02..6373e8cd 100644 --- a/src/api/videosourcefactory.cpp +++ b/src/api/videosourcefactory.cpp @@ -65,7 +65,7 @@ IVideoSource * VideoSourceFactory::get_device(Device device, case BGRA: #ifdef USE_EPIPHANSDK src = new VideoSourceEpiphanSDK(Epiphan_DVI2PCIeDuo_DVI, - V2U_GRABFRAME_FORMAT_ARGB32); + V2U_GRABFRAME_FORMAT_RGB24); #else throw VideoSourceError( "BGRA colour space on Epiphan DVI2PCIe Duo supported only with Epiphan SDK"); @@ -118,7 +118,7 @@ IVideoSource * VideoSourceFactory::get_device(Device device, case BGRA: #ifdef USE_EPIPHANSDK src = new VideoSourceEpiphanSDK(Epiphan_DVI2PCIeDuo_SDI, - V2U_GRABFRAME_FORMAT_ARGB32); + V2U_GRABFRAME_FORMAT_RGB24); #else throw VideoSourceError( "BGRA colour space on Epiphan DVI2PCIe Duo supported only with Epiphan SDK"); diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index f8507610..18a8b71e 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -10,7 +10,7 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( , _frame_grabber(nullptr) , _flags(0) , _daemon(nullptr) - , _bgra_data(nullptr) + , _rgb_data(nullptr) , _buffer(nullptr) { FrmGrab_Init(); @@ -23,7 +23,7 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( return; } - if (colour_space != V2U_GRABFRAME_FORMAT_I420 and colour_space != V2U_GRABFRAME_FORMAT_ARGB32) + if (colour_space != V2U_GRABFRAME_FORMAT_I420 and colour_space != V2U_GRABFRAME_FORMAT_RGB24) { // TODO - exception GiftGrab#42 std::cerr << "Colour space " << colour_space << " not supported" << std::endl; @@ -49,8 +49,9 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( _full.height = 1080; if (_colour == BGRA) { - _bgra_data = reinterpret_cast(malloc( - 4 * _full.width * _full.height * sizeof(unsigned char) + // 3: RGB + _rgb_data = reinterpret_cast(malloc( + 3 * _full.width * _full.height * sizeof(unsigned char) )); } get_full_frame(); @@ -66,10 +67,10 @@ VideoSourceEpiphanSDK::~VideoSourceEpiphanSDK() delete _daemon; if (_frame_grabber) FrmGrab_Close(_frame_grabber); FrmGrab_Deinit(); - if (_colour == BGRA && _bgra_data != nullptr) + if (_colour == BGRA && _rgb_data != nullptr) { - free(_bgra_data); - _bgra_data = nullptr; + free(_rgb_data); + _rgb_data = nullptr; } } @@ -108,9 +109,9 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) frame_data = data; break; case BGRA: - _argb_to_bgra.set_frame_dimensions(frame_width, frame_height); - _argb_to_bgra.convert(data, _bgra_data); - frame_data = _bgra_data; + _rgb_to_bgra.set_frame_dimensions(frame_width, frame_height); + _rgb_to_bgra.convert(data, _rgb_data); + frame_data = _rgb_data; break; default: // TODO diff --git a/src/epiphansdk/epiphansdk_video_source.h b/src/epiphansdk/epiphansdk_video_source.h index 7d61f225..9d3cb6fe 100644 --- a/src/epiphansdk/epiphansdk_video_source.h +++ b/src/epiphansdk/epiphansdk_video_source.h @@ -3,7 +3,7 @@ #include "ivideosource.h" #include "macros.h" #include "broadcastdaemon.h" -#include "argb_to_bgra_converter.h" +#include "rgb_to_bgra_converter.h" namespace gg { @@ -51,14 +51,14 @@ class VideoSourceEpiphanSDK : public IVideoSource gg::BroadcastDaemon * _daemon; //! - //! \brief Buffer for converting from ARGB to BGRA + //! \brief Buffer for converting from RGB to BGRA //! - unsigned char *_bgra_data; + unsigned char *_rgb_data; //! - //! \brief ARGB to BGRA converter + //! \brief RGB to BGRA converter //! - ArgbToBgraConverter _argb_to_bgra; + RgbToBgraConverter _rgb_to_bgra; public: //! @@ -68,7 +68,7 @@ class VideoSourceEpiphanSDK : public IVideoSource //! as \c \#define'd in Epiphan device properties //! header //! \param colour_space \c V2U_GRABFRAME_FORMAT_I420 - //! or \c V2U_GRABFRAME_FORMAT_ARGB32 + //! or \c V2U_GRABFRAME_FORMAT_RGB24 //! \throw VideoSourceError if connection attempt //! fails, with a detailed error message //! diff --git a/src/epiphansdk/argb_to_bgra_converter.cpp b/src/epiphansdk/rgb_to_bgra_converter.cpp similarity index 61% rename from src/epiphansdk/argb_to_bgra_converter.cpp rename to src/epiphansdk/rgb_to_bgra_converter.cpp index b1f56f61..641e2b79 100644 --- a/src/epiphansdk/argb_to_bgra_converter.cpp +++ b/src/epiphansdk/rgb_to_bgra_converter.cpp @@ -1,10 +1,10 @@ -#include "argb_to_bgra_converter.h" +#include "rgb_to_bgra_converter.h" #include namespace gg { -ArgbToBgraConverter::ArgbToBgraConverter() +RgbToBgraConverter::RgbToBgraConverter() : _width(0) , _height(0) #ifdef USE_FFMPEG @@ -14,7 +14,7 @@ ArgbToBgraConverter::ArgbToBgraConverter() } -ArgbToBgraConverter::~ArgbToBgraConverter() +RgbToBgraConverter::~RgbToBgraConverter() { #ifdef USE_FFMPEG sws_freeContext(_sws_context); @@ -22,12 +22,12 @@ ArgbToBgraConverter::~ArgbToBgraConverter() #endif } -void ArgbToBgraConverter::convert(unsigned char *argb, - unsigned char *bgra) +void RgbToBgraConverter::convert(unsigned char *rgb, + unsigned char *bgra) { #ifdef USE_FFMPEG - _sws_srcSlice[0] = argb; - _sws_srcStride[0] = 4 * _width; + _sws_srcSlice[0] = rgb; + _sws_srcStride[0] = 3 * _width; _sws_dst[0] = bgra; _sws_dstStride[0] = 4 * _width; sws_scale(_sws_context, @@ -35,18 +35,18 @@ void ArgbToBgraConverter::convert(unsigned char *argb, _sws_dst, _sws_dstStride); #else size_t length = 4 * _width * _height; - for (size_t i = 0; i < length; i += 4) + for (size_t i = 0, j = 0; i < length; i += 4, j += 3) { - bgra[i] = argb[i+3]; - bgra[i+1] = argb[i+2]; - bgra[i+2] = argb[i+1]; - bgra[i+3] = argb[i]; + bgra[i] = rgb[j+2]; + bgra[i+1] = rgb[j+1]; + bgra[i+2] = rgb[j]; + bgra[i+3] = 255; } #endif } -void ArgbToBgraConverter::set_frame_dimensions(size_t width, - size_t height) +void RgbToBgraConverter::set_frame_dimensions(size_t width, + size_t height) { assert(width > 0); assert(height > 0); diff --git a/src/epiphansdk/argb_to_bgra_converter.h b/src/epiphansdk/rgb_to_bgra_converter.h similarity index 72% rename from src/epiphansdk/argb_to_bgra_converter.h rename to src/epiphansdk/rgb_to_bgra_converter.h index 53c7cc77..5036dad7 100644 --- a/src/epiphansdk/argb_to_bgra_converter.h +++ b/src/epiphansdk/rgb_to_bgra_converter.h @@ -11,12 +11,12 @@ namespace gg { //! -//! \brief Epiphan SDK seems to support ARGB but not BGRA. -//! This class abstracts the conversion of captured ARGB +//! \brief Epiphan SDK seems to support RGB but not BGRA. +//! This class abstracts the conversion of captured RGB //! data to BGRA. //! \sa VideoSourceEpiphanSDK //! -class ArgbToBgraConverter +class RgbToBgraConverter { protected: //! @@ -34,7 +34,7 @@ class ArgbToBgraConverter int _sws_srcStride[1]; unsigned char *_sws_dst[1]; int _sws_dstStride[1]; - AVPixelFormat _sws_srcFormat = AV_PIX_FMT_ARGB; + AVPixelFormat _sws_srcFormat = AV_PIX_FMT_RGB24; AVPixelFormat _sws_dstFormat = AV_PIX_FMT_BGRA; SwsContext *_sws_context; #endif @@ -46,27 +46,27 @@ class ArgbToBgraConverter //! dimensions //! \sa set_frame_dimensions //! - ArgbToBgraConverter(); + RgbToBgraConverter(); //! //! \brief Free all allocated resources //! - ~ArgbToBgraConverter(); + ~RgbToBgraConverter(); public: //! - //! \brief Convert ARGB data in passed buffer to BGRA + //! \brief Convert RGB data in passed buffer to BGRA //! data, saving it into the passed output buffer. - //! \param argb should be in line with the frame + //! \param rgb should be in line with the frame //! dimensions set before //! \param bgra should be at least as large as the //! input buffer //! \sa set_frame_dimensions //! - void convert(unsigned char *argb, unsigned char *bgra); + void convert(unsigned char *rgb, unsigned char *bgra); //! - //! \brief Allocate all resources needed for ARGB to + //! \brief Allocate all resources needed for RGB to //! BGRA conversion based on passed frame dimensions //! \param width //! \param height diff --git a/src/tests/rgbswap/profile_argb_to_bgra.cpp b/src/tests/rgbswap/profile_rgb_to_bgra.cpp similarity index 100% rename from src/tests/rgbswap/profile_argb_to_bgra.cpp rename to src/tests/rgbswap/profile_rgb_to_bgra.cpp From 27dc5969dcbb075bc41c1a92d3797fe95282bcfb Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Fri, 2 Nov 2018 07:48:07 +0000 Subject: [PATCH 35/36] Issue #46: converted ARGB-to-BGRA profiler to RGB-to-BGRA profiler --- src/tests/rgbswap/CMakeLists.txt | 12 +-- src/tests/rgbswap/profile_rgb_to_bgra.cpp | 114 ++++++++-------------- 2 files changed, 47 insertions(+), 79 deletions(-) diff --git a/src/tests/rgbswap/CMakeLists.txt b/src/tests/rgbswap/CMakeLists.txt index 89297b8e..0870d81c 100644 --- a/src/tests/rgbswap/CMakeLists.txt +++ b/src/tests/rgbswap/CMakeLists.txt @@ -1,14 +1,14 @@ -SET(ARGB_TO_BGRA_PROFILER argb_to_bgra_profiler) +SET(RGB_TO_BGRA_PROFILER rgb_to_bgra_profiler) ADD_EXECUTABLE( - ${ARGB_TO_BGRA_PROFILER} - ${CMAKE_SOURCE_DIR}/tests/rgbswap/profile_argb_to_bgra.cpp + ${RGB_TO_BGRA_PROFILER} + ${CMAKE_SOURCE_DIR}/tests/rgbswap/profile_rgb_to_bgra.cpp ) if(USE_FFMPEG) - LIST(APPEND ARGB_TO_BGRA_PROFILER_LIBS ${FFmpeg_LIBS}) + LIST(APPEND RGB_TO_BGRA_PROFILER_LIBS ${FFmpeg_LIBS}) endif(USE_FFMPEG) if(USE_OPENCV) - LIST(APPEND ARGB_TO_BGRA_PROFILER_LIBS ${OpenCV_LIBS}) + LIST(APPEND RGB_TO_BGRA_PROFILER_LIBS ${OpenCV_LIBS}) endif(USE_OPENCV) TARGET_LINK_LIBRARIES( - ${ARGB_TO_BGRA_PROFILER} ${ARGB_TO_BGRA_PROFILER_LIBS} + ${RGB_TO_BGRA_PROFILER} ${RGB_TO_BGRA_PROFILER_LIBS} ) diff --git a/src/tests/rgbswap/profile_rgb_to_bgra.cpp b/src/tests/rgbswap/profile_rgb_to_bgra.cpp index 13e7d475..e6e866e8 100644 --- a/src/tests/rgbswap/profile_rgb_to_bgra.cpp +++ b/src/tests/rgbswap/profile_rgb_to_bgra.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #ifdef USE_FFMPEG extern "C" { #include @@ -15,34 +14,23 @@ extern "C" { using namespace std; using namespace std::chrono; -template -void copy_strided(T begin , T end, T dest, int length) +bool rgb_same_as_bgra(const unsigned char *rgb, + const unsigned char *bgra, + size_t l) { - int num_copied = 0; - copy_if(begin, end, dest, [&num_copied,length]( double x ) - { - return (num_copied++ % length == 0); - } - ); -} - -bool argb_same_as_bgra(const unsigned char *argb, - const unsigned char *bgra, - size_t l) -{ - for (size_t i = 0; i < l; i += 4) - if (argb[i] != bgra[i+3] or argb[i+1] != bgra[i+2] or - argb[i+2] != bgra[i+1] or argb[i+3] != bgra[i]) + for (size_t i = 0, j = 0; i < l; i += 4, j += 3) + if (rgb[j] != bgra[i+2] or rgb[j+1] != bgra[i+1] or + rgb[j+2] != bgra[i]) return false; return true; } int main(int argc, char *argv[]) { - // ARGB with random values + // RGB with random values size_t w = 1920, h = 1080; size_t l; - unsigned char *argb = nullptr; + unsigned char *rgb = nullptr; bool compose = true; if (argc == 2) { @@ -52,14 +40,13 @@ int main(int argc, char *argv[]) w = orig.cols; h = orig.rows; compose = false; - l = 4 * w * h; - argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); - for (size_t i = 0, j = 0; i < l; i +=4, j += 3) + l = 3 * w * h; + rgb = reinterpret_cast(malloc(l * sizeof(unsigned char))); + for (size_t i = 0; i < l; i +=3) { - argb[i] = 255; - argb[i+1] = orig.data[j+2]; - argb[i+2] = orig.data[j+1]; - argb[i+3] = orig.data[j]; + rgb[i] = orig.data[i+2]; + rgb[i+1] = orig.data[i+1]; + rgb[i+2] = orig.data[i]; } #endif } @@ -68,35 +55,35 @@ int main(int argc, char *argv[]) w = atoi(argv[1]); h = atoi(argv[2]); } - cout << "Profiling ARGB => BGRA conversion for " + cout << "Profiling RGB => BGRA conversion for " << w << " x " << h << " image" << endl; if (compose) { - l = 4 * w * h; - argb = reinterpret_cast(malloc(l * sizeof(unsigned char))); + l = 3 * w * h; + rgb = reinterpret_cast(malloc(l * sizeof(unsigned char))); for (size_t i = 0; i < l; i++) { - argb[i] = i % 32; - argb[i+1] = argb[i] * 4; - argb[i+2] = i % 256; - argb[i+3] = 255; + rgb[i] = i % 32; + rgb[i+1] = rgb[i] * 4; + rgb[i+2] = i % 256; } } - // ARGB => BGRA in a strided loop + // RGB => BGRA in a strided loop + l = 4 * w * h; unsigned char *bgra_loop = nullptr; bgra_loop = reinterpret_cast(malloc(l * sizeof(unsigned char))); high_resolution_clock::time_point t1 = high_resolution_clock::now(); - for (size_t i = 0; i < l; i += 4) + for (size_t i = 0, j = 0; i < l; i += 4, j += 3) { - bgra_loop[i] = argb[i+3]; - bgra_loop[i+1] = argb[i+2]; - bgra_loop[i+2] = argb[i+1]; - bgra_loop[i+3] = argb[i]; + bgra_loop[i] = rgb[j+2]; + bgra_loop[i+1] = rgb[j+1]; + bgra_loop[i+2] = rgb[j]; + bgra_loop[i+3] = 255; } high_resolution_clock::time_point t2 = high_resolution_clock::now(); auto duration = duration_cast( t2 - t1 ).count(); - cout << "Loop (" << (argb_same_as_bgra(argb, bgra_loop, l) ? "success" : "failure") + cout << "Loop (" << (rgb_same_as_bgra(rgb, bgra_loop, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; #ifdef USE_OPENCV { @@ -106,34 +93,36 @@ int main(int argc, char *argv[]) #endif free(bgra_loop); - // simple memcopy (no ARGB => BGRA) - unsigned char *argb_memcpy = nullptr; - argb_memcpy = reinterpret_cast(malloc(l * sizeof(unsigned char))); + // simple memcopy (no RGB => BGRA) + l = 3 * w * h; + unsigned char *rgb_memcpy = nullptr; + rgb_memcpy = reinterpret_cast(malloc(l * sizeof(unsigned char))); t1 = high_resolution_clock::now(); - memcpy(argb_memcpy, argb, l * sizeof(unsigned char)); + memcpy(rgb_memcpy, rgb, l * sizeof(unsigned char)); t2 = high_resolution_clock::now(); duration = duration_cast( t2 - t1 ).count(); cout << "memcpy took: " << duration << " usec" << endl; - free(argb_memcpy); + free(rgb_memcpy); #ifdef USE_FFMPEG - // ARGB => BGRA using FFmpeg + l = 4 * w * h; + // RGB => BGRA using FFmpeg unsigned char *bgra_ffmpeg = nullptr; bgra_ffmpeg = reinterpret_cast(malloc(l * sizeof(unsigned char))); - unsigned char *srcSlice[] = {argb}; - int srcStride[] = {static_cast(4 * w)}; + unsigned char *srcSlice[] = {rgb}; + int srcStride[] = {static_cast(3 * w)}; int srcSliceY = 0; int srcSliceH = h; unsigned char *dst[] = {bgra_ffmpeg}; int dstStride[] = {static_cast(4 * w)}; int srcW = w, srcH = h, dstW = w, dstH = h; - AVPixelFormat srcFormat = AV_PIX_FMT_ARGB, dstFormat = AV_PIX_FMT_BGRA; + AVPixelFormat srcFormat = AV_PIX_FMT_RGB24, dstFormat = AV_PIX_FMT_BGRA; SwsContext *c = sws_getCachedContext(nullptr, srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0, nullptr, nullptr, nullptr); t1 = high_resolution_clock::now(); sws_scale(c, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride); t2 = high_resolution_clock::now(); duration = duration_cast( t2 - t1 ).count(); - cout << "FFmpeg (" << (argb_same_as_bgra(argb, bgra_ffmpeg, l) ? "success" : "failure") + cout << "FFmpeg (" << (rgb_same_as_bgra(rgb, bgra_ffmpeg, l) ? "success" : "failure") << ") took: " << duration << " usec" << endl; #ifdef USE_OPENCV { @@ -145,28 +134,7 @@ int main(int argc, char *argv[]) free(bgra_ffmpeg); #endif - // ARGB => BGRA with a function - unsigned char *bgra_function = nullptr; - bgra_function = reinterpret_cast(malloc(l * sizeof(unsigned char))); - t1 = high_resolution_clock::now(); - copy_strided(argb + 3, argb + l, bgra_function, 4); - copy_strided(argb + 2, argb + l, bgra_function + 1, 4); - copy_strided(argb + 1, argb + l, bgra_function + 2, 4); - copy_strided(argb, argb + l, bgra_function + 3, 4); - t2 = high_resolution_clock::now(); - duration = duration_cast( t2 - t1 ).count(); - cout << "Function (" << (argb_same_as_bgra(argb, bgra_function, l) ? "success" : "failure") - << ") took: " << duration << " usec" << endl; - free(bgra_function); -#ifdef USE_OPENCV - { - cv::Mat _bgra(h, w, CV_8UC4, bgra_function), bgr; - cv::cvtColor(_bgra, bgr, cv::COLOR_BGRA2BGR); - cv::imwrite("bgra_function.png", bgr); - } -#endif - // free all memory - free(argb); + free(rgb); return EXIT_SUCCESS; } From 5185540b85e0db692210d23a2dbbc11de936543c Mon Sep 17 00:00:00 2001 From: Dzhoshkun Ismail Shakir Date: Fri, 2 Nov 2018 08:07:10 +0000 Subject: [PATCH 36/36] Issue #46: fixed BGRA buffer allocation --- src/epiphansdk/epiphansdk_video_source.cpp | 17 ++++++++--------- src/epiphansdk/epiphansdk_video_source.h | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/epiphansdk/epiphansdk_video_source.cpp b/src/epiphansdk/epiphansdk_video_source.cpp index 18a8b71e..628231c5 100644 --- a/src/epiphansdk/epiphansdk_video_source.cpp +++ b/src/epiphansdk/epiphansdk_video_source.cpp @@ -10,7 +10,7 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( , _frame_grabber(nullptr) , _flags(0) , _daemon(nullptr) - , _rgb_data(nullptr) + , _bgra_data(nullptr) , _buffer(nullptr) { FrmGrab_Init(); @@ -49,9 +49,8 @@ VideoSourceEpiphanSDK::VideoSourceEpiphanSDK( _full.height = 1080; if (_colour == BGRA) { - // 3: RGB - _rgb_data = reinterpret_cast(malloc( - 3 * _full.width * _full.height * sizeof(unsigned char) + _bgra_data = reinterpret_cast(malloc( + 4 * _full.width * _full.height * sizeof(unsigned char) )); } get_full_frame(); @@ -67,10 +66,10 @@ VideoSourceEpiphanSDK::~VideoSourceEpiphanSDK() delete _daemon; if (_frame_grabber) FrmGrab_Close(_frame_grabber); FrmGrab_Deinit(); - if (_colour == BGRA && _rgb_data != nullptr) + if (_colour == BGRA && _bgra_data != nullptr) { - free(_rgb_data); - _rgb_data = nullptr; + free(_bgra_data); + _bgra_data = nullptr; } } @@ -110,8 +109,8 @@ bool VideoSourceEpiphanSDK::get_frame(VideoFrame & frame) break; case BGRA: _rgb_to_bgra.set_frame_dimensions(frame_width, frame_height); - _rgb_to_bgra.convert(data, _rgb_data); - frame_data = _rgb_data; + _rgb_to_bgra.convert(data, _bgra_data); + frame_data = _bgra_data; break; default: // TODO diff --git a/src/epiphansdk/epiphansdk_video_source.h b/src/epiphansdk/epiphansdk_video_source.h index 9d3cb6fe..91719c89 100644 --- a/src/epiphansdk/epiphansdk_video_source.h +++ b/src/epiphansdk/epiphansdk_video_source.h @@ -53,7 +53,7 @@ class VideoSourceEpiphanSDK : public IVideoSource //! //! \brief Buffer for converting from RGB to BGRA //! - unsigned char *_rgb_data; + unsigned char *_bgra_data; //! //! \brief RGB to BGRA converter