Selaa lähdekoodia

1. add hendian.h
2. add SleepPolicy for HThread

ithewei 7 vuotta sitten
vanhempi
commit
1c33ccbaa5
4 muutettua tiedostoa jossa 123 lisäystä ja 7 poistoa
  1. 1 0
      hbuf.h
  2. 56 0
      hendian.h
  3. 11 2
      hgl.h
  4. 55 5
      hthread.h

+ 1 - 0
hbuf.h

@@ -20,6 +20,7 @@ typedef struct hbuf_s{
         this->len  = len;
     }
 
+    // warn: must call cleanup when no longer in use, otherwise memory leak.
     void init(size_t cap){
         if (cap == len) return;
 

+ 56 - 0
hendian.h

@@ -0,0 +1,56 @@
+#ifndef H_ENDIAN_H
+#define H_ENDIAN_H
+
+#include "hdef.h"
+
+#define LITTLE_ENDIAN   0
+#define BIG_ENDIAN      1
+#define NET_ENDIAN      BIG_ENDIAN
+
+int check_endian(){
+    union{
+        char c;
+        short s;
+    }u;
+    u.s = 0x1122;
+    if (u.c == 0x11){
+        return BIG_ENDIAN;
+    }
+    return LITTLE_ENDIAN;
+}
+
+template <typename T>
+uint8* serialize(uint8* buf, T value, int host_endian = LITTLE_ENDIAN, int buf_endian = BIG_ENDIAN){
+    size_t size = sizeof(T);
+    uint8* pDst = buf;
+    uint8* pSrc = (uint8*)&value;
+
+    if (host_endian == buf_endian){
+        memcpy(pDst, pSrc, size);
+    }else{
+        for (int i = 0; i < size; ++i){
+            pDst[i] = pSrc[size-i-1];
+        }
+    }
+
+    return buf+size;
+}
+
+template <typename T>
+uint8* deserialize(uint8* buf, T* value, int host_endian = LITTLE_ENDIAN, int buf_endian = BIG_ENDIAN){
+    size_t size = sizeof(T);
+    uint8* pSrc = buf;
+    uint8* pDst = (uint8*)value;
+
+    if (host_endian == buf_endian){
+        memcpy(pDst, pSrc, size);
+    }else{
+        for (int i = 0; i < size; ++i){
+            pDst[i] = pSrc[size-i-1];
+        }
+    }
+
+    return buf+size;
+}
+
+#endif // H_ENDIAN_H

+ 11 - 2
hgl.h

@@ -5,10 +5,19 @@
 #include "hframe.h"
 
 // GL PixelFormat extend
-#define GL_I420				0x1910
+#define GL_I420				0x1910  // YYYYYYYYUUVV
+#define GL_YV12             0x1911  // YYYYYYYYVVUU
+#define GL_NV12             0x1912  // YYYYYYYYUVUV
+#define GL_NV21             0x1913  // YYYYYYYYVUVU
+
+//#define GL_RGB  0x1907            // RGBRGB
+//#define GL_RGBA 0x1908            // RGBARGBA
+
+//#define GL_BGR 0x80E0             // BGRBGR       .bmp
+//#define GL_BGRA 0x80E1            // BGRABGRA
 
 typedef struct GLTexture_s{
-    GLuint id; // glGenTextures分配的ID
+    GLuint id; // for glGenTextures
     HFrame frame;
 }GLTexture;
 

+ 55 - 5
hthread.h

@@ -5,6 +5,7 @@
 #include "hplatform.h"
 #include <thread>
 #include <atomic>
+#include <chrono>
 
 #ifdef _MSC_VER
 inline uint32 getpid(){
@@ -31,6 +32,9 @@ class HThread{
 public:
     HThread() {
         status = STOP;
+        status_switch = false;
+        sleep_policy = YIELD;
+        sleep_ms = 0;
     }
 
     virtual ~HThread() {
@@ -39,7 +43,7 @@ public:
 
     virtual int start() {
         if (status == STOP) {
-            status = RUNNING;
+            switchStatus(RUNNING);
             dotask_cnt = 0;
 
             thread = std::thread([this]{
@@ -53,7 +57,7 @@ public:
 
     virtual int stop() {
         if (status != STOP) {
-            status = STOP;
+            switchStatus(STOP);
             thread.join(); // wait thread exit
         }
         return 0;
@@ -61,14 +65,14 @@ public:
 
     virtual int pause() {
         if (status == RUNNING) {
-            status = PAUSE;
+            switchStatus(PAUSE);
         }
         return 0;
     }
 
     virtual int resume() {
         if (status == PAUSE) {
-            status = RUNNING;
+            switchStatus(RUNNING);
         }
         return 0;
     }
@@ -82,7 +86,7 @@ public:
             doTask();
             dotask_cnt++;
 
-            std::this_thread::yield();
+            sleep();
         }
     }
 
@@ -98,6 +102,52 @@ public:
     };
     std::atomic<Status> status;
     uint32 dotask_cnt;
+
+    enum SleepPolicy {
+        YIELD,
+        SLEEP_FOR,
+        SLEEP_UNTIL,
+        NO_SLEEP,
+    };
+
+    void setSleepPolicy(SleepPolicy policy, long long ms = 0) {
+        status_switch = true;
+        sleep_policy = policy;
+        sleep_ms = ms;
+    }
+
+protected:
+    void switchStatus(Status stat) {
+        status_switch = true;
+        status = stat;
+    }
+
+    void sleep() {
+        switch (sleep_policy) {
+        case YIELD: 
+            std::this_thread::yield();  
+            break;
+        case SLEEP_FOR: 
+            std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));    
+            break;
+        case SLEEP_UNTIL: {
+            if (status_switch) {
+                status_switch = false;
+                base_tp = std::chrono::system_clock::now();
+            }
+            base_tp += std::chrono::milliseconds(sleep_ms);
+            std::this_thread::sleep_until(base_tp); 
+        }
+            break;
+        default:    // donothing, go all out.
+            break;
+        }
+    }
+
+    std::atomic<bool> status_switch;
+    SleepPolicy sleep_policy;
+    std::chrono::system_clock::time_point base_tp;   // for SLEEP_UNTIL
+    long long sleep_ms;
 };
 
 #endif // H_THREAD_H