267 lines
7.8 KiB
C++
267 lines
7.8 KiB
C++
/*
|
|
* Copyright (C) 2014-2026 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* All information contained herein is Amlogic confidential.
|
|
*
|
|
* This software is provided to you pursuant to Software License Agreement
|
|
* (SLA) with Amlogic Inc ("Amlogic"). This software may be used
|
|
* only in accordance with the terms of this agreement.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification is strictly prohibited without prior written permission from
|
|
* Amlogic.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#include <string>
|
|
|
|
// Convert milliseconds to "00:00:00.000" format string.
|
|
static inline std::string ms2ClockString(int64_t ms) {
|
|
if (ms < 0) {
|
|
return "00:00:00.000";
|
|
}
|
|
|
|
int64_t totalSeconds = ms / 1000;
|
|
int milliseconds = (int)(ms % 1000);
|
|
int hours = (int)(totalSeconds / 3600);
|
|
int remainingSeconds = (int)(totalSeconds % 3600);
|
|
int minutes = remainingSeconds / 60;
|
|
int seconds = remainingSeconds % 60;
|
|
|
|
char buf[16];
|
|
snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d", hours, minutes, seconds, milliseconds);
|
|
return std::string(buf);
|
|
}
|
|
|
|
#endif
|
|
|
|
#define RETURN_CASE_STR(x) \
|
|
case x: \
|
|
return #x
|
|
|
|
static inline const char* strBoolean(bool val) {
|
|
return val ? "true" : "false";
|
|
}
|
|
|
|
static inline uint64_t getCurrentTimeMs() {
|
|
struct timespec ts;
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000);
|
|
}
|
|
|
|
static inline int64_t pts2Ms(int64_t pts) {
|
|
return pts / 90;
|
|
}
|
|
|
|
static inline int64_t ms2Pts(int64_t ms) {
|
|
return ms * 90;
|
|
}
|
|
|
|
static inline int64_t us2Pts(int64_t us) {
|
|
return ms2Pts(us / 1000);
|
|
}
|
|
|
|
static inline bool isMore32Bit(int64_t pts) {
|
|
return ((pts >> 32) & 0xFFFFFFFF) > 0;
|
|
}
|
|
|
|
static inline int64_t clockTime2Ms(int h, int m, int s, int ms) {
|
|
if (h < 0 || m < 0 || m >= 60 || s < 0 || s >= 60 || ms < 0 || ms >= 1000) {
|
|
return 0;
|
|
}
|
|
return ((int64_t)h * 3600 + (int64_t)m * 60 + (int64_t)s) * 1000 + (int64_t)ms;
|
|
}
|
|
|
|
// Function: Convert milliseconds to "hours:minutes:seconds.milliseconds" format (0:00:00.00)
|
|
// Returns error if duration exceeds 9:59:59.99 (10 hours exclusive)
|
|
// Parameter: ms - Input milliseconds (int64_t type)
|
|
// Parameter: outString - Output string buffer
|
|
// Parameter: outStringSize - Size of the output buffer, needs at least 10 characters
|
|
// Return value: 0 on success, -1 on failure (invalid parameters or exceeds 9:59:59.99)
|
|
static inline int ms2TimeClockString(int64_t ms, char* outString, size_t outStringSize) {
|
|
// Check parameter validity (buffer not null + enough space for "0:00:00.00")
|
|
if (outString == NULL || outStringSize < 10) {
|
|
return -1;
|
|
}
|
|
|
|
// Maximum allowed duration: 9h59m59.99s = 3599999 ms
|
|
// Calculation: 9*3600*1000 + 59*60*1000 + 59*1000 + 99 = 3599999
|
|
const int64_t MAX_MILLISECONDS = 3599999LL;
|
|
|
|
// Reject negative values and values exceeding 9:59:59.99
|
|
if (ms < 0 || ms > MAX_MILLISECONDS) {
|
|
return -1;
|
|
}
|
|
|
|
// Calculate each time unit
|
|
int64_t totalSeconds = ms / 1000;
|
|
int milliseconds = (int)(ms % 1000) / 10; // Keep 2 decimal places (00~99)
|
|
|
|
int hours = (int)(totalSeconds / 3600); // 0~9
|
|
int remainingSeconds = (int)(totalSeconds % 3600); // Remaining seconds after hours
|
|
int minutes = remainingSeconds / 60; // 0~59
|
|
int seconds = remainingSeconds % 60; // 0~59
|
|
|
|
// Format string to "h:mm:ss.ss"
|
|
snprintf(outString, outStringSize, "%d:%02d:%02d.%02d", hours, minutes, seconds, milliseconds);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Convert time clock string to milliseconds.
|
|
// String format: "h:mm:ss.ms" (e.g., "0:00:00.00" or "00:00:00.000" to "99:59:59.999")
|
|
// Note: Supports both 2-digit (centiseconds) and 3-digit (milliseconds) fractional seconds
|
|
// Return: milliseconds on success, -1 on failure
|
|
static inline int64_t timeClockString2ms(const char* timeClockStr) {
|
|
if (timeClockStr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
int hour = 0;
|
|
int minute = 0;
|
|
int second = 0;
|
|
int fractional = 0; // fractional seconds (centiseconds or milliseconds)
|
|
|
|
int parsedCount = sscanf(timeClockStr, "%d:%d:%d.%d", &hour, &minute, &second, &fractional);
|
|
if (parsedCount != 4) {
|
|
return -1;
|
|
}
|
|
|
|
if (hour < 0 || hour > 99) {
|
|
return -1;
|
|
}
|
|
if (minute < 0 || minute > 59) {
|
|
return -1;
|
|
}
|
|
if (second < 0 || second > 59) {
|
|
return -1;
|
|
}
|
|
|
|
// Determine if fractional part is centiseconds (2 digits) or milliseconds (3 digits)
|
|
int64_t totalMs =
|
|
(int64_t)hour * 3600000LL + (int64_t)minute * 60000LL + (int64_t)second * 1000LL;
|
|
|
|
// Check the fractional part
|
|
if (fractional < 0) {
|
|
return -1;
|
|
}
|
|
|
|
if (fractional <= 99) {
|
|
// 2 digits: centiseconds (00-99) -> multiply by 10 to get milliseconds
|
|
totalMs += (int64_t)fractional * 10LL;
|
|
} else if (fractional <= 999) {
|
|
// 3 digits: milliseconds (000-999) -> use directly
|
|
totalMs += (int64_t)fractional;
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
return totalMs;
|
|
}
|
|
|
|
static inline uint32_t bytestream_get_be32(const uint8_t** ptr) {
|
|
uint32_t tmp;
|
|
tmp = (*ptr)[3] | ((*ptr)[2] << 8) | ((*ptr)[1] << 16) | ((*ptr)[0] << 24);
|
|
*ptr += 4;
|
|
return tmp;
|
|
}
|
|
static inline uint32_t bytestream_get_be24(const uint8_t** ptr) {
|
|
uint32_t tmp;
|
|
tmp = (*ptr)[2] | ((*ptr)[1] << 8) | ((*ptr)[0] << 16);
|
|
*ptr += 3;
|
|
return tmp;
|
|
}
|
|
static inline uint32_t bytestream_get_be16(const uint8_t** ptr) {
|
|
uint32_t tmp;
|
|
tmp = (*ptr)[1] | ((*ptr)[0] << 8);
|
|
*ptr += 2;
|
|
return tmp;
|
|
}
|
|
static inline uint8_t bytestream_get_byte(const uint8_t** ptr) {
|
|
uint8_t tmp;
|
|
tmp = **ptr;
|
|
*ptr += 1;
|
|
return tmp;
|
|
}
|
|
|
|
/**
|
|
* return the literal value of ascii printed char
|
|
*/
|
|
static inline int subAscii2Value(char ascii) {
|
|
return ascii - '0';
|
|
}
|
|
|
|
/**
|
|
* Peek the buffer data, consider it to int 32 value.
|
|
*
|
|
* Peek, do not affect the buffer contents and pointer
|
|
*/
|
|
static inline int32_t subPeekAsInt32(const char* buffer) {
|
|
int32_t value = 0;
|
|
for (int i = 0; i < 4; ++i) {
|
|
value <<= 8;
|
|
value |= buffer[i];
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Peek the buffer data, consider it to unsigned int 32 value.
|
|
*
|
|
* Peek, do not affect the buffer contents and pointer
|
|
*/
|
|
static inline uint32_t subPeekAsUint32(const char* buffer) {
|
|
uint32_t value = 0;
|
|
for (int i = 0; i < 4; ++i) {
|
|
value <<= 8;
|
|
value |= buffer[i];
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Peek the buffer data, consider it to int 64 value.
|
|
*
|
|
* Peek, do not affect the buffer contents and pointer
|
|
*/
|
|
static inline int64_t subPeekAsInt64(const char* buffer) {
|
|
int64_t value = 0;
|
|
for (int i = 0; i < 8; ++i) {
|
|
value <<= 8;
|
|
value |= buffer[i];
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Peek the buffer data, consider it to unsigned int 64 value.
|
|
*
|
|
* Peek, do not affect the buffer contents and pointer
|
|
*/
|
|
static inline uint64_t subPeekAsUint64(const char* buffer) {
|
|
uint64_t value = 0;
|
|
for (int i = 0; i < 8; ++i) {
|
|
value <<= 8;
|
|
value |= buffer[i];
|
|
}
|
|
return value;
|
|
}
|