Image: Convert API to std::chrono
Utils: Remove TimespecDiff. It is not used anymore
This commit is contained in:
parent
1fe30c848d
commit
ff8c9f67c1
|
@ -294,17 +294,18 @@ bool Event::WriteFrameImage(
|
|||
|
||||
bool rc;
|
||||
|
||||
if ( !config.timestamp_on_capture ) {
|
||||
SystemTimePoint jpeg_timestamp =
|
||||
monitor->Exif() ? SystemTimePoint(zm::chrono::duration_cast<Microseconds>(timestamp)) : SystemTimePoint();
|
||||
|
||||
if (!config.timestamp_on_capture) {
|
||||
// stash the image we plan to use in another pointer regardless if timestamped.
|
||||
// exif is only timestamp at present this switches on or off for write
|
||||
Image *ts_image = new Image(*image);
|
||||
monitor->TimestampImage(ts_image, timestamp);
|
||||
rc = ts_image->WriteJpeg(event_file, thisquality,
|
||||
(monitor->Exif() ? timestamp : (timeval){0,0}));
|
||||
delete(ts_image);
|
||||
rc = ts_image->WriteJpeg(event_file, thisquality, jpeg_timestamp);
|
||||
delete ts_image;
|
||||
} else {
|
||||
rc = image->WriteJpeg(event_file, thisquality,
|
||||
(monitor->Exif() ? timestamp : (timeval){0,0}));
|
||||
rc = image->WriteJpeg(event_file, thisquality, jpeg_timestamp);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -1061,23 +1061,26 @@ cinfo->out_color_space = JCS_RGB;
|
|||
// Note quality=zero means default
|
||||
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override) const {
|
||||
return Image::WriteJpeg(filename, quality_override, (timeval){0,0}, false);
|
||||
return Image::WriteJpeg(filename, quality_override, {}, false);
|
||||
}
|
||||
bool Image::WriteJpeg(const char *filename) const {
|
||||
return Image::WriteJpeg(filename, 0, (timeval){0,0}, false);
|
||||
return Image::WriteJpeg(filename, 0, {}, false);
|
||||
}
|
||||
bool Image::WriteJpeg(const char *filename, bool on_blocking_abort) const {
|
||||
return Image::WriteJpeg(filename, 0, (timeval){0,0}, on_blocking_abort);
|
||||
return Image::WriteJpeg(filename, 0, {}, on_blocking_abort);
|
||||
}
|
||||
bool Image::WriteJpeg(const char *filename, struct timeval timestamp) const {
|
||||
bool Image::WriteJpeg(const char *filename, SystemTimePoint timestamp) const {
|
||||
return Image::WriteJpeg(filename, 0, timestamp, false);
|
||||
}
|
||||
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp) const {
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp) const {
|
||||
return Image::WriteJpeg(filename, quality_override, timestamp, false);
|
||||
}
|
||||
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort) const {
|
||||
bool Image::WriteJpeg(const char *filename,
|
||||
int quality_override,
|
||||
SystemTimePoint timestamp,
|
||||
bool on_blocking_abort) const {
|
||||
if ( config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8) ) {
|
||||
Image temp_image(*this);
|
||||
temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
|
||||
|
@ -1196,7 +1199,7 @@ cinfo->out_color_space = JCS_RGB;
|
|||
}
|
||||
// If we have a non-zero time (meaning a parameter was passed in), then form a simple exif segment with that time as DateTimeOriginal and SubsecTimeOriginal
|
||||
// No timestamp just leave off the exif section.
|
||||
if ( timestamp.tv_sec ) {
|
||||
if (timestamp.time_since_epoch() > Seconds(0)) {
|
||||
#define EXIFTIMES_MS_OFFSET 0x36 // three decimal digits for milliseconds
|
||||
#define EXIFTIMES_MS_LEN 0x03
|
||||
#define EXIFTIMES_OFFSET 0x3E // 19 characters format '2015:07:21 13:14:45' not including quotes
|
||||
|
@ -1205,9 +1208,15 @@ cinfo->out_color_space = JCS_RGB;
|
|||
|
||||
// This is a lot of stuff to allocate on the stack. Recommend char *timebuf[64];
|
||||
char timebuf[64], msbuf[64];
|
||||
|
||||
tm timestamp_tm = {};
|
||||
strftime(timebuf, sizeof timebuf, "%Y:%m:%d %H:%M:%S", localtime_r(×tamp.tv_sec, ×tamp_tm));
|
||||
snprintf(msbuf, sizeof msbuf, "%06d",(int)(timestamp.tv_usec)); // we only use milliseconds because that's all defined in exif, but this is the whole microseconds because we have it
|
||||
time_t timestamp_t = std::chrono::system_clock::to_time_t(timestamp);
|
||||
strftime(timebuf, sizeof timebuf, "%Y:%m:%d %H:%M:%S", localtime_r(×tamp_t, ×tamp_tm));
|
||||
Seconds ts_sec = std::chrono::duration_cast<Seconds>(timestamp.time_since_epoch());
|
||||
Microseconds ts_usec = std::chrono::duration_cast<Microseconds>(timestamp.time_since_epoch() - ts_sec);
|
||||
// we only use milliseconds because that's all defined in exif, but this is the whole microseconds because we have it
|
||||
snprintf(msbuf, sizeof msbuf, "%06d", static_cast<int32>(ts_usec.count()));
|
||||
|
||||
unsigned char exiftimes[82] = {
|
||||
0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x69, 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -1722,11 +1731,6 @@ void Image::Overlay( const Image &image, unsigned int x, unsigned int y ) {
|
|||
} // end void Image::Overlay( const Image &image, unsigned int x, unsigned int y )
|
||||
|
||||
void Image::Blend( const Image &image, int transparency ) {
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
struct timespec start,end,diff;
|
||||
unsigned long long executetime;
|
||||
unsigned long milpixels;
|
||||
#endif
|
||||
uint8_t* new_buffer;
|
||||
|
||||
if ( !(
|
||||
|
@ -1744,19 +1748,21 @@ void Image::Blend( const Image &image, int transparency ) {
|
|||
new_buffer = AllocBuffer(size);
|
||||
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start);
|
||||
TimePoint start = std::chrono::steady_clock::now();
|
||||
#endif
|
||||
|
||||
/* Do the blending */
|
||||
(*blend)(buffer, image.buffer, new_buffer, size, transparency);
|
||||
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end);
|
||||
TimespecDiff(&start,&end,&diff);
|
||||
TimePoint end = std::chrono::steady_clock::now();
|
||||
|
||||
executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec;
|
||||
milpixels = (unsigned long)((long double)size)/((((long double)executetime)/1000));
|
||||
Debug(5, "Blend: %u colours blended in %llu nanoseconds, %lu million colours/s\n",size,executetime,milpixels);
|
||||
std::chrono::nanoseconds diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
|
||||
uint64 mil_pixels = static_cast<uint64>(size / (static_cast<long double>(diff.count()) / 1000));
|
||||
Debug(5, "Blend: %u colours blended in %" PRIi64 " nanoseconds, % " PRIi64 " million colours/s\n",
|
||||
size,
|
||||
static_cast<int64>(diff.count()),
|
||||
mil_pixels);
|
||||
#endif
|
||||
|
||||
AssignDirect(width, height, colours, subpixelorder, new_buffer, size, ZM_BUFTYPE_ZM);
|
||||
|
@ -1860,12 +1866,6 @@ Image *Image::Highlight( unsigned int n_images, Image *images[], const Rgb thres
|
|||
|
||||
/* New function to allow buffer re-using instead of allocationg memory for the delta image every time */
|
||||
void Image::Delta(const Image &image, Image* targetimage) const {
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
struct timespec start,end,diff;
|
||||
unsigned long long executetime;
|
||||
unsigned long milpixels;
|
||||
#endif
|
||||
|
||||
if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) {
|
||||
Panic( "Attempt to get delta of different sized images, expected %dx%dx%d %d, got %dx%dx%d %d",
|
||||
width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder);
|
||||
|
@ -1878,7 +1878,7 @@ void Image::Delta(const Image &image, Image* targetimage) const {
|
|||
}
|
||||
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start);
|
||||
TimePoint start = std::chrono::steady_clock::now();
|
||||
#endif
|
||||
|
||||
switch ( colours ) {
|
||||
|
@ -1915,12 +1915,14 @@ void Image::Delta(const Image &image, Image* targetimage) const {
|
|||
}
|
||||
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end);
|
||||
TimespecDiff(&start,&end,&diff);
|
||||
TimePoint end = std::chrono::steady_clock::now();
|
||||
|
||||
executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec;
|
||||
milpixels = (unsigned long)((long double)pixels)/((((long double)executetime)/1000));
|
||||
Debug(5, "Delta: %u delta pixels generated in %llu nanoseconds, %lu million pixels/s",pixels,executetime,milpixels);
|
||||
std::chrono::nanoseconds diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
|
||||
uint64 mil_pixels = static_cast<uint64>(size / (static_cast<long double>(diff.count()) / 1000));
|
||||
Debug(5, "Delta: %u delta pixels generated in %" PRIi64 " nanoseconds, % " PRIi64 " million pixels/s",
|
||||
size,
|
||||
static_cast<int64>(diff.count()),
|
||||
mil_pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2119,17 +2121,18 @@ void Image::Annotate(
|
|||
}
|
||||
}
|
||||
|
||||
void Image::Timestamp(const char *label, const time_t when, const Vector2 &coord, const int size) {
|
||||
void Image::Timestamp(const char *label, SystemTimePoint when, const Vector2 &coord, int label_size) {
|
||||
char time_text[64];
|
||||
tm when_tm = {};
|
||||
strftime(time_text, sizeof(time_text), "%y/%m/%d %H:%M:%S", localtime_r(&when, &when_tm));
|
||||
if ( label ) {
|
||||
time_t when_t = std::chrono::system_clock::to_time_t(when);
|
||||
strftime(time_text, sizeof(time_text), "%y/%m/%d %H:%M:%S", localtime_r(&when_t, &when_tm));
|
||||
if (label) {
|
||||
// Assume label is max 64, + ' - ' + 64 chars of time_text
|
||||
char text[132];
|
||||
snprintf(text, sizeof(text), "%s - %s", label, time_text);
|
||||
Annotate(text, coord, size);
|
||||
Annotate(text, coord, label_size);
|
||||
} else {
|
||||
Annotate(time_text, coord, size);
|
||||
Annotate(time_text, coord, label_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "zm_logger.h"
|
||||
#include "zm_mem_utils.h"
|
||||
#include "zm_rgb.h"
|
||||
#include "zm_time.h"
|
||||
#include "zm_vector2.h"
|
||||
|
||||
#if HAVE_ZLIB_H
|
||||
|
@ -237,9 +238,9 @@ class Image {
|
|||
bool WriteJpeg(const char *filename) const;
|
||||
bool WriteJpeg(const char *filename, bool on_blocking_abort) const;
|
||||
bool WriteJpeg(const char *filename, int quality_override) const;
|
||||
bool WriteJpeg(const char *filename, struct timeval timestamp) const;
|
||||
bool WriteJpeg(const char *filename, int quality_override, struct timeval timestamp) const;
|
||||
bool WriteJpeg(const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort) const;
|
||||
bool WriteJpeg(const char *filename, SystemTimePoint timestamp) const;
|
||||
bool WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp) const;
|
||||
bool WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const;
|
||||
|
||||
bool DecodeJpeg(const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder);
|
||||
bool EncodeJpeg(JOCTET *outbuffer, int *outbuffer_size, int quality_override=0) const;
|
||||
|
@ -270,7 +271,7 @@ class Image {
|
|||
Rgb bg_colour = kRGBBlack);
|
||||
Image *HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p_subpixelorder, const Box *limits=0 );
|
||||
//Image *HighlightEdges( Rgb colour, const Polygon &polygon );
|
||||
void Timestamp(const char *label, const time_t when, const Vector2 &coord, const int size);
|
||||
void Timestamp(const char *label, SystemTimePoint when, const Vector2 &coord, int label_size);
|
||||
void Colourise(const unsigned int p_reqcolours, const unsigned int p_reqsubpixelorder);
|
||||
void DeColourise();
|
||||
|
||||
|
@ -300,8 +301,9 @@ class Edge {
|
|||
Edge(int32 min_y, int32 max_y, double min_x, double _1_m) : min_y(min_y), max_y(max_y), min_x(min_x), _1_m(_1_m) {}
|
||||
|
||||
static bool CompareYX(const Edge &e1, const Edge &e2) {
|
||||
if (e1.min_y == e2.min_y)
|
||||
if (e1.min_y == e2.min_y) {
|
||||
return e1.min_x < e2.min_x;
|
||||
}
|
||||
return e1.min_y < e2.min_y;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,16 +180,6 @@ std::string Base64Encode(const std::string &str) {
|
|||
return outString;
|
||||
}
|
||||
|
||||
void TimespecDiff(struct timespec *start, struct timespec *end, struct timespec *diff) {
|
||||
if (((end->tv_nsec) - (start->tv_nsec)) < 0) {
|
||||
diff->tv_sec = end->tv_sec - start->tv_sec - 1;
|
||||
diff->tv_nsec = 1000000000 + end->tv_nsec - start->tv_nsec;
|
||||
} else {
|
||||
diff->tv_sec = end->tv_sec - start->tv_sec;
|
||||
diff->tv_nsec = end->tv_nsec - start->tv_nsec;
|
||||
}
|
||||
}
|
||||
|
||||
std::string TimevalToString(timeval tv) {
|
||||
tm now = {};
|
||||
std::array<char, 26> tm_buf = {};
|
||||
|
|
|
@ -76,7 +76,6 @@ std::string ByteArrayToHexString(nonstd::span<const uint8> bytes);
|
|||
|
||||
std::string Base64Encode(const std::string &str);
|
||||
|
||||
void TimespecDiff(timespec *start, timespec *end, timespec *diff);
|
||||
std::string TimevalToString(timeval tv);
|
||||
|
||||
extern unsigned int sse_version;
|
||||
|
|
Loading…
Reference in New Issue