| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- #include "media_common.h"
- #include "logger.h"
- #include <algorithm>
- #include <sstream>
- #include <fstream>
- #include <filesystem>
- #include <cctype>
- #include <iomanip>
- #include <cstring>
- #include <limits>
- // FFmpeg头文件
- extern "C" {
- #include <libavutil/avutil.h>
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- #include <libswresample/swresample.h>
- #include <libavutil/log.h>
- #include <libavutil/error.h>
- #include <libavutil/pixfmt.h>
- #include <libavutil/pixdesc.h>
- #include <libavutil/samplefmt.h>
- #include <libavutil/frame.h>
- #include <libavcodec/packet.h>
- }
- namespace av {
- // 字符串工具实现
- namespace string_utils {
- std::vector<std::string> split(const std::string& str, char delimiter) {
- std::vector<std::string> result;
- std::stringstream ss(str);
- std::string item;
-
- while (std::getline(ss, item, delimiter)) {
- result.push_back(item);
- }
-
- return result;
- }
- std::vector<std::string> split(const std::string& str, const std::string& delimiter) {
- std::vector<std::string> result;
- size_t start = 0;
- size_t end = str.find(delimiter);
-
- while (end != std::string::npos) {
- result.push_back(str.substr(start, end - start));
- start = end + delimiter.length();
- end = str.find(delimiter, start);
- }
-
- result.push_back(str.substr(start));
- return result;
- }
- std::string trim(const std::string& str) {
- return trimLeft(trimRight(str));
- }
- std::string trimLeft(const std::string& str) {
- auto start = str.begin();
- while (start != str.end() && std::isspace(*start)) {
- start++;
- }
- return std::string(start, str.end());
- }
- std::string trimRight(const std::string& str) {
- auto end = str.end();
- while (end != str.begin() && std::isspace(*(end - 1))) {
- end--;
- }
- return std::string(str.begin(), end);
- }
- std::string replace(const std::string& str, const std::string& from, const std::string& to) {
- std::string result = str;
- size_t pos = 0;
-
- while ((pos = result.find(from, pos)) != std::string::npos) {
- result.replace(pos, from.length(), to);
- pos += to.length();
- }
-
- return result;
- }
- std::string toLower(const std::string& str) {
- std::string result = str;
- std::transform(result.begin(), result.end(), result.begin(), ::tolower);
- return result;
- }
- std::string toUpper(const std::string& str) {
- std::string result = str;
- std::transform(result.begin(), result.end(), result.begin(), ::toupper);
- return result;
- }
- bool startsWith(const std::string& str, const std::string& prefix) {
- return str.length() >= prefix.length() &&
- str.compare(0, prefix.length(), prefix) == 0;
- }
- bool endsWith(const std::string& str, const std::string& suffix) {
- return str.length() >= suffix.length() &&
- str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
- }
- bool contains(const std::string& str, const std::string& substr) {
- return str.find(substr) != std::string::npos;
- }
- } // namespace string_utils
- // 文件路径工具实现
- namespace path_utils {
- std::string join(const std::string& path1, const std::string& path2) {
- if (path1.empty()) return path2;
- if (path2.empty()) return path1;
-
- std::filesystem::path p1(path1);
- std::filesystem::path p2(path2);
- return (p1 / p2).string();
- }
- std::string getDirectory(const std::string& path) {
- std::filesystem::path p(path);
- return p.parent_path().string();
- }
- std::string getFilename(const std::string& path) {
- std::filesystem::path p(path);
- return p.filename().string();
- }
- std::string getExtension(const std::string& path) {
- std::filesystem::path p(path);
- return p.extension().string();
- }
- std::string removeExtension(const std::string& path) {
- std::filesystem::path p(path);
- return p.replace_extension().string();
- }
- std::string normalize(const std::string& path) {
- std::filesystem::path p(path);
- return std::filesystem::weakly_canonical(p).string();
- }
- std::string toNative(const std::string& path) {
- std::filesystem::path p(path);
- return p.make_preferred().string();
- }
- bool exists(const std::string& path) {
- return std::filesystem::exists(path);
- }
- bool isFile(const std::string& path) {
- return std::filesystem::is_regular_file(path);
- }
- bool isDirectory(const std::string& path) {
- return std::filesystem::is_directory(path);
- }
- bool isAbsolute(const std::string& path) {
- std::filesystem::path p(path);
- return p.is_absolute();
- }
- bool createDirectory(const std::string& path) {
- try {
- return std::filesystem::create_directories(path);
- } catch (const std::exception& e) {
- AV_LOGGER_ERRORF("Failed to create directory '{}': {}", path, e.what());
- return false;
- }
- }
- bool removeFile(const std::string& path) {
- try {
- return std::filesystem::remove(path);
- } catch (const std::exception& e) {
- AV_LOGGER_ERRORF("Failed to remove file '{}': {}", path, e.what());
- return false;
- }
- }
- } // namespace path_utils
- // 时间工具实现
- namespace time_utils {
- int64_t getCurrentTimeMs() {
- return std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::steady_clock::now().time_since_epoch()).count();
- }
- int64_t getCurrentTimeUs() {
- return std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now().time_since_epoch()).count();
- }
- std::string formatTime(int64_t timeMs, const std::string& format) {
- auto time_t = std::chrono::system_clock::to_time_t(
- std::chrono::system_clock::time_point(
- std::chrono::milliseconds(timeMs)));
-
- std::ostringstream oss;
- oss << std::put_time(std::localtime(&time_t), format.c_str());
- return oss.str();
- }
- std::string formatDuration(int64_t durationMs) {
- int64_t hours = durationMs / (1000 * 60 * 60);
- int64_t minutes = (durationMs % (1000 * 60 * 60)) / (1000 * 60);
- int64_t seconds = (durationMs % (1000 * 60)) / 1000;
- int64_t ms = durationMs % 1000;
-
- std::ostringstream oss;
- if (hours > 0) {
- oss << hours << ":" << std::setfill('0') << std::setw(2) << minutes
- << ":" << std::setw(2) << seconds;
- } else {
- oss << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
- }
-
- if (ms > 0) {
- oss << "." << std::setw(3) << ms;
- }
-
- return oss.str();
- }
- // Timer实现
- Timer::Timer() {
- reset();
- }
- void Timer::start() {
- m_startTime = std::chrono::high_resolution_clock::now();
- m_running = true;
- }
- void Timer::stop() {
- if (m_running) {
- m_endTime = std::chrono::high_resolution_clock::now();
- m_running = false;
- }
- }
- void Timer::reset() {
- m_startTime = std::chrono::high_resolution_clock::now();
- m_endTime = m_startTime;
- m_running = false;
- }
- int64_t Timer::elapsedMs() const {
- auto endTime = m_running ? std::chrono::high_resolution_clock::now() : m_endTime;
- return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - m_startTime).count();
- }
- int64_t Timer::elapsedUs() const {
- auto endTime = m_running ? std::chrono::high_resolution_clock::now() : m_endTime;
- return std::chrono::duration_cast<std::chrono::microseconds>(endTime - m_startTime).count();
- }
- bool Timer::isRunning() const {
- return m_running;
- }
- // ScopedTimer实现
- ScopedTimer::ScopedTimer(const std::string& name) : m_name(name) {
- m_timer.start();
- }
- ScopedTimer::~ScopedTimer() {
- m_timer.stop();
- AV_LOGGER_INFOF("[Timer] {} took {} ms", m_name, m_timer.elapsedMs());
- }
- } // namespace time_utils
- // 内存工具实现
- namespace memory_utils {
- size_t alignSize(size_t size, size_t alignment) {
- return (size + alignment - 1) & ~(alignment - 1);
- }
- void* alignedAlloc(size_t size, size_t alignment) {
- #ifdef _WIN32
- return _aligned_malloc(size, alignment);
- #else
- void* ptr = nullptr;
- if (posix_memalign(&ptr, alignment, size) != 0) {
- return nullptr;
- }
- return ptr;
- #endif
- }
- void alignedFree(void* ptr) {
- #ifdef _WIN32
- _aligned_free(ptr);
- #else
- free(ptr);
- #endif
- }
- // MemoryPool实现
- MemoryPool::MemoryPool(size_t blockSize, size_t blockCount)
- : m_blockSize(blockSize) {
- size_t totalSize = blockSize * blockCount;
- m_memory.resize(totalSize);
-
- // 初始化空闲块列表
- for (size_t i = 0; i < blockCount; ++i) {
- m_freeBlocks.push_back(m_memory.data() + i * blockSize);
- }
- }
- MemoryPool::~MemoryPool() {
- // 析构函数自动清理
- }
- void* MemoryPool::allocate() {
- std::lock_guard<std::mutex> lock(m_mutex);
-
- if (m_freeBlocks.empty()) {
- return nullptr;
- }
-
- void* ptr = m_freeBlocks.back();
- m_freeBlocks.pop_back();
- return ptr;
- }
- void MemoryPool::deallocate(void* ptr) {
- if (!ptr) return;
-
- std::lock_guard<std::mutex> lock(m_mutex);
-
- // 验证指针是否属于这个内存池
- uint8_t* bytePtr = static_cast<uint8_t*>(ptr);
- if (bytePtr >= m_memory.data() &&
- bytePtr < m_memory.data() + m_memory.size()) {
- m_freeBlocks.push_back(ptr);
- }
- }
- size_t MemoryPool::getAvailableBlocks() const {
- std::lock_guard<std::mutex> lock(m_mutex);
- return m_freeBlocks.size();
- }
- } // namespace memory_utils
- // FFmpeg工具实现
- namespace ffmpeg_utils {
- std::string errorToString(int errorCode) {
- char buffer[AV_ERROR_MAX_STRING_SIZE];
- av_strerror(errorCode, buffer, sizeof(buffer));
- return std::string(buffer);
- }
- bool checkError(int ret, const std::string& operation) {
- if (ret < 0) {
- AV_LOGGER_ERRORF("{} failed: {}", operation, errorToString(ret));
- return false;
- }
- return true;
- }
- std::string pixelFormatToString(AVPixelFormat format) {
- const char* name = av_get_pix_fmt_name(format);
- return name ? std::string(name) : "unknown";
- }
- std::string sampleFormatToString(AVSampleFormat format) {
- const char* name = av_get_sample_fmt_name(format);
- return name ? std::string(name) : "unknown";
- }
- std::string codecTypeToString(AVMediaType type) {
- const char* name = av_get_media_type_string(type);
- return name ? std::string(name) : "unknown";
- }
- bool isValidPixelFormat(AVPixelFormat format) {
- return format != AV_PIX_FMT_NONE && av_get_pix_fmt_name(format) != nullptr;
- }
- bool isValidSampleFormat(AVSampleFormat format) {
- return format != AV_SAMPLE_FMT_NONE && av_get_sample_fmt_name(format) != nullptr;
- }
- bool isValidSampleRate(int sampleRate) {
- return sampleRate > 0 && sampleRate <= 192000;
- }
- bool isValidChannels(int channels) {
- return channels > 0 && channels <= 32;
- }
- AVFrame* allocateFrame(AVPixelFormat format, int width, int height) {
- AVFrame* frame = av_frame_alloc();
- if (!frame) {
- return nullptr;
- }
-
- frame->format = format;
- frame->width = width;
- frame->height = height;
-
- if (av_frame_get_buffer(frame, 32) < 0) {
- av_frame_free(&frame);
- return nullptr;
- }
-
- return frame;
- }
- AVFrame* allocateAudioFrame(AVSampleFormat format, int sampleRate, int channels, int nbSamples) {
- AVFrame* frame = av_frame_alloc();
- if (!frame) {
- return nullptr;
- }
-
- frame->format = format;
- frame->sample_rate = sampleRate;
- frame->ch_layout.nb_channels = channels;
- frame->nb_samples = nbSamples;
-
- if (av_frame_get_buffer(frame, 0) < 0) {
- av_frame_free(&frame);
- return nullptr;
- }
-
- return frame;
- }
- void freeFrame(AVFrame** frame) {
- if (frame && *frame) {
- av_frame_free(frame);
- }
- }
- AVPacket* allocatePacket() {
- return av_packet_alloc();
- }
- void freePacket(AVPacket** packet) {
- if (packet && *packet) {
- av_packet_free(packet);
- }
- }
- bool initializeFFmpeg() {
- static bool initialized = false;
- if (initialized) {
- return true;
- }
-
- try {
- // FFmpeg 4.0+ 不需要显式注册
- av_log_set_level(AV_LOG_QUIET);
- initialized = true;
- AV_LOGGER_INFO("FFmpeg initialized successfully");
- return true;
- } catch (const std::exception& e) {
- AV_LOGGER_ERRORF("Failed to initialize FFmpeg: {}", e.what());
- return false;
- }
- }
- void cleanupFFmpeg() {
- // FFmpeg 4.0+ 不需要显式清理
- AV_LOGGER_INFO("FFmpeg cleanup completed");
- }
- } // namespace ffmpeg_utils
- } // namespace av
|