c/c++语言开发共享SDL2:封装媒体显示播放Csdl2

Github https://github.com/gongluck/SDL2 study/tree/master/Csdl2 Csdl2.h Csdl2.cpp 测试 C++ include “Csdl2.h” include include include define TESTCHECKRET …


github

https://github.com/gongluck/sdl2-study/tree/master/csdl2

csdl2.h

#ifndef __csdl2_h__ #define __csdl2_h__  #include <sdl.h> #include <string> #include <mutex>  class csdl2 { public:     // 状态     enum status { stop = 0b00, lockedv = 0b01, lockeda = 0b10, lockedboth = 0b11 };      // 全局的初始化     bool global_init(uint32 flags, std::string& err);     // 全局的反初始化     bool global_uninit(std::string& err);      // 设置(windows)窗口     bool set_window(const void* hwnd, std::string& err);     // 设置图像格式(sdl_pixelformat_???)     bool set_pix_fmt(uint32 fmt, int w, int h, std::string& err);     // 渲染数据,pitch是图像一行的字节大小,rect是渲染目标矩形,angle旋转角度,center旋转中心(在rect,{0,0}为左上),flip翻转     bool render(const void* data, int pitch, const sdl_rect* rect,          const double angle, const sdl_point* center, const sdl_rendererflip flip, std::string& err);     // 清理图像格式资源     bool clear_pix_fmt(std::string& err);     // 销毁关联资源     bool detach_window(std::string& err);      // 设置音频格式和处理回调     bool set_audio_fmt(int freq, sdl_audioformat fmt, uint8 channels, uint16 samples, sdl_audiocallback callback, void* userdata, std::string& err);     // 开始音频播放     bool start_audio(std::string& err);     // 停止音频播放     bool stop_audio(std::string& err);  private:     status status_ = stop;     std::recursive_mutex mutex_;      sdl_window* win_ = nullptr;     sdl_renderer* renderer_ = nullptr;     sdl_texture* texture_ = nullptr;      sdl_audiospec reqspec_ = { 0 };     sdl_audiospec recspec_ = { 0 }; };  #endif//__csdl2_h__

csdl2.cpp

#include "csdl2.h"  // 递归锁 #define lockcsdl2() std::lock_guard<std::recursive_mutex> _lock(this->mutex_)  // 检查停止状态 #define checkcsdl2stop(err)  if(this->status_ != stop) {     err = "status is not stop.";     return false; } // 检查视频停止 #define checkcsdl2stopv(err)  if(this->status_ & 1 != 0) {     err = "statusv is not stop.";     return false; } // 检查音频停止 #define checkcsdl2stopa(err)  if((this->status_ >> 1) & 1 != 0) {     err = "statusa is not stop.";     return false; } // 检查视频未停止 #define checkcsdl2nstopv(err)  if(this->status_ & 1 == 0) {     err = "statusv is stop.";     return false; } // 检查音频未停止 #define checkcsdl2nstopa(err)  if((this->status_ >> 1) & 1 == 0) {     err = "statusa is stop.";     return false; }  // 返回成功 #define optsucceed() {     err = "opt succeed.";     return true; }  // 返回失败 #define optfailed() {     err = sdl_geterror();     return false;  }  // 判断结果,并返回(必定退出函数!!!) #define checksdlret(ret) if(ret == 0) {     optsucceed(); } else {     optfailed(); }  bool csdl2::global_init(uint32 flags, std::string& err) {     lockcsdl2();     checkcsdl2stop(err);     if (sdl_init(flags) < 0)     {         optfailed();     }     else     {         optsucceed();     } }  bool csdl2::global_uninit(std::string& err) {     lockcsdl2();     checkcsdl2stop(err);     sdl_quit();     optsucceed(); }  bool csdl2::set_window(const void* hwnd, std::string& err) {     lockcsdl2();     checkcsdl2stopv(err);     detach_window(err);     win_ = sdl_createwindowfrom(hwnd);     if (win_ != nullptr)     {         renderer_ = sdl_createrenderer(win_, -1, sdl_renderer_accelerated | sdl_renderer_presentvsync);         if (renderer_ != nullptr)         {             optsucceed();         }         else         {             std::string e;             detach_window(e);             optfailed();         }     }     else     {         optfailed();     } }  bool csdl2::set_pix_fmt(uint32 fmt, int w, int h, std::string& err) {     lockcsdl2();     checkcsdl2stopv(err);     clear_pix_fmt(err);     if (renderer_ == nullptr)     {         err = "renderer is nullptr.";         return false;     }     texture_ = sdl_createtexture(renderer_, fmt, sdl_textureaccess_streaming, w, h);     if (texture_ != nullptr)     {         status_ = static_cast<status>(static_cast<unsigned int>(status_) | lockedv);         optsucceed();     }     else     {         optfailed();     } }  bool csdl2::render(const void* data, int pitch, const sdl_rect* rect,      const double angle, const sdl_point* center, const sdl_rendererflip flip,      std::string& err) {     lockcsdl2();     checkcsdl2nstopv(err);     if (texture_ == nullptr || renderer_ == nullptr)     {         err = texture_ == nullptr ? "texture is nullptr." : "renderer is nullptr.";         return false;     }     if (sdl_updatetexture(texture_, nullptr, data, pitch) != 0)     {         optfailed();     }     else     {         if (sdl_renderclear(renderer_) != 0)         {             optfailed();         }         else         {             if (sdl_rendercopyex(renderer_, texture_, nullptr, rect, angle, center, flip) != 0)             {                 optfailed();             }             else             {                 sdl_renderpresent(renderer_);                 optsucceed();             }         }     } }  bool csdl2::clear_pix_fmt(std::string& err) {     lockcsdl2();     if (texture_ != nullptr)     {         sdl_destroytexture(texture_);         texture_ = nullptr;     }     status_ = static_cast<status>(static_cast<unsigned int>(status_) & ~lockedv);     optsucceed(); }  bool csdl2::detach_window(std::string& err) {     lockcsdl2();     checkcsdl2stopv(err);     if (renderer_ != nullptr)     {         sdl_destroyrenderer(renderer_);         renderer_ = nullptr;     }     if (win_ != nullptr)     {         sdl_destroywindow(win_);         win_ = nullptr;     }     optsucceed(); }  bool csdl2::set_audio_fmt(int freq, sdl_audioformat fmt, uint8 channels, uint16 samples, sdl_audiocallback callback, void* userdata, std::string& err) {     lockcsdl2();     checkcsdl2stopa(err);     reqspec_ = { 0 };     recspec_ = { 0 };     reqspec_.freq = freq;     reqspec_.format = fmt;     reqspec_.channels = channels;     reqspec_.samples = samples;     reqspec_.callback = callback;     reqspec_.userdata = userdata;     if (sdl_openaudio(&reqspec_, &recspec_) != 0)     {         optfailed();     }     else     {         status_ = static_cast<status>(static_cast<unsigned int>(status_) | lockeda);         optsucceed();     } }  bool csdl2::start_audio(std::string& err) {     lockcsdl2();     checkcsdl2nstopa(err);     sdl_pauseaudio(0);     optsucceed(); }  bool csdl2::stop_audio(std::string& err) {     lockcsdl2();     checkcsdl2nstopa(err);     sdl_pauseaudio(1);     status_ = static_cast<status>(static_cast<unsigned int>(status_) & ~lockeda);     optsucceed(); }

测试

#include "csdl2.h" #include <iostream> #include <fstream> #include <windows.h>  #define testcheckret(ret) if(!ret) {     std::cerr << err << std::endl;     std::cout << "input to end." << std::endl;     getchar();     return sdl_error(sdl_lasterror); }  csdl2 g_test; void sdlcall sdl_audiocb(void* userdata, uint8* stream, int len) {     static std::ifstream f("in.pcm", std::ios::binary);     sdl_memset(stream, 0, len);     void* buf = malloc(len);     f.read((char*)buf, len);     sdl_mixaudio(stream, (const uint8*)buf, len, sdl_mix_maxvolume);     free(buf);     if (f.eof())     {         std::cout << "end" << std::endl;         f.close();         std::string err;         g_test.stop_audio(err);     }     }  int main(int argc, char* argv[]) {     std::string err;     rect rect = { 0 };     sdl_point p = { 0, 50 };     std::ifstream file("in.rgb", std::ios::binary);     if (!file.is_open())     {         std::cerr << "open file failed " << std::endl;         getchar();         return 0;     }     int size = 320 * 240 * 3;     void* buf = malloc(size);      file.read(static_cast<char*>(buf), size);      testcheckret(g_test.global_init(sdl_init_video | sdl_init_audio, err));      hwnd hwnd = createwindow(text("static"), text("test csdl2"), ws_visible,         cw_usedefault, cw_usedefault, 800, 500, nullptr, nullptr, getmodulehandle(nullptr), nullptr);     //sdl_window* hwnd = sdl_createwindow("test csdl2", sdl_windowpos_undefined, sdl_windowpos_undefined, 320, 240, sdl_window_shown);     if (hwnd == nullptr)     {         std::cerr << "create window failed " << getlasterror() << std::endl;         goto end;     }     testcheckret(g_test.set_window(hwnd, err));     testcheckret(g_test.set_pix_fmt(sdl_pixelformat_rgb24, 320, 240, err));     testcheckret(g_test.render(buf, size / 240, nullptr, 2, &p, sdl_flip_none, err));     std::cout << "render succeed." << std::endl;      testcheckret(g_test.set_audio_fmt(44100, audio_f32, 2, 1024, sdl_audiocb, nullptr, err));     testcheckret(g_test.start_audio(err));     std::cout << "open audio succeed." << std::endl;  end:     std::cout << "input to end." << std::endl;     getchar();     testcheckret(g_test.clear_pix_fmt(err));     testcheckret(g_test.detach_window(err));     if (hwnd != nullptr)     {         destroywindow(hwnd);         hwnd = nullptr;     }     testcheckret(g_test.stop_audio(err));     testcheckret(g_test.global_uninit(err));     if (buf != nullptr)     {         free(buf);         buf = nullptr;     }     return 0; }

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/602972.html

(0)
上一篇 2021年5月11日
下一篇 2021年5月11日

精彩推荐