UDP下嘅實時音視頻傳輸機制

前言

經歷咗一兩年係項目當中嘅實時音視頻實踐, 覺得要實現好嘅實時音視頻傳輸實屬不易. 以下呢套UDP下嘅實現流程, 係血嘅經驗, 每一點都是來之不易.

全局要點: 視頻可跳, 但聲音不斷.

發送方

  1. 開始時, 編碼I幀, 發送
  2. 接著, 發P幀 ( 聲音與視頻編碼是不同的, 每次真實發送幀前, 讀取錄音緩沖區, 並打包 ), 發N個P幀後, 跳到 a
  3. 如果在發P幀過程中, 接收到對方發來的 "重發I 幀" 請求, 馬上放棄目前所編碼的幀(視頻幀,不是聲音幀), 跳轉到 a

接收方

  1. 建立幀列表, 至少存儲3幀以上才開始播放, 使用順序插入法, 尋找相應幀序號的位置, 並插入.
  2. 播放開始時, 不停從幀列表中取得一幀(由於此時幀列表是順序的,故此取列表頭的那一幀即可), 如果是P幀時則放棄, 直到找到I幀才開始真正播放. 聲音幀不需要等I幀, 只要按著順序播放即可.
  3. 播放過程中, 不停從幀列表中取得一幀進行播放( 聲音播放與視頻播放線程需要分開!!切記 ...
more ...

班得瑞(Bandari)

最近先至發現原來有十幾首好好聽嘅歌,原來喺屬於 Bandari 兩個專輯嘅音樂。再搜索咗一下呢個樂隊嘅信息,好似幾有意思甘,似乎眾說紛紜,有人話呢個樂隊係假嘅,亦有人話呢個樂隊衹係平時好低調,仲有人話 Bandari 係瑞士唱片公司 Audio Video Communications AG(簡稱AVC)嘅產品,似乎最後一種講法比較靠譜,上他們的主頁可以揾到 Bandari 嘅專輯。

似乎 Bandari 華人區更受歡迎,試下係Google搜索一下就知道,如果查英文,基本揾唔到真正同 Bandari 專輯有關嘅信息,但搜索中文網頁就一大堆。

但無關系啦,只要好聽就得~~話知佢係假定系真啦~~

more ...

終於可以用Google音樂下載啦~~

前一排,聽講Google可以免費下載正版音樂,好開心,於是上Google,發現真係有Google音樂下載!但呢個試聽同下載服務僅對中國大陸境內提供。

但係好失望,我一點下載就彈出個網頁話 “403 forbidden”,頂!我本來就係大陸境內,冇理由唔得咖?!開始我以為係瀏覽器嘅安全選項問題,於是我將D防火牆啊、安全選項啊全部關晒,但係都唔得,搞左幾日,上網抄左幾日都冇見到有講呢個問題,無法子啦,只好唔搞~~

後尾翻到公司,啱好見到個同事用Google音樂聽緊歌,我以為係公司可以,於是嗱嗱臨開機試下,點知又係唔得,甘就出奇啦,我地公司係用一個IP出口嘅,冇理由,佢得我唔得咖?!於是我比較左下我台機同同事台機有乜唔同,比較之下先發現,佢個DNS同我個DNS唔一樣,改左個DNS之後,掂晒!!終於可以下載啦!

因為我用開嘅係 OpenDNS,所以所有我用嘅機都會設置個DNS為OpenDNS 嘅地址,估計係中國境內 Google 音樂下載網址解釋僅對中國境內DNS有效,所以在國際DNS服務器內解釋呢個地址到其它位置,於是通過OpenDNS解釋到其它嘅IP導致出現 forbidden 嘅現象。

more ...

點解要點解?

  記得係大學果陣,有一次有個課程設計要做一個C語言嘅詞法解釋器。

  果陣起左個念頭想做一個通用嘅語言編譯器,即係一個萬能既語言編譯器,類似於C語言編譯器、Pascal編譯器等等,但係唔需要硬性為每個語言寫程式(GCC就係呢類型嘅實作),只需要寫一個簡單嘅詞法語法配置文本文檔即可以支持編譯出不同平台嘅程式(二進制文件格式)。

  後來同老師講左下自己嘅諗法同埋一D唔成熟嘅思路,同埋打算用幾十年時間嚟做呢樣嘢。

  老師同我講(大概意思):「呢種編譯器到目前都未出現,起碼證明呢樣嘢難度好高或者幾乎唔可能實現,點解要做呢D無用功呢?何況你做咗出嚟,佢又有乜價值呢?又有乜市場呢?何況做通用嘅編譯器你嘅編譯速度就自然比特定嘅編譯器速度慢,甘你呢個編譯器又有乜用呢?」

  聽到老師甘講,有D愕然,講真啦,老師講得係啱,但係……我只係想做呢樣嘢,無話想攞佢嚟用,只係想做,點解一定要有用、一定要有價值、一定要有市場啫?就好似細路嘅玩具咁,只係因為有興趣,想玩就玩啫,當時亦係甘回答嘅。

  人嘅一生,短短百年,雖則現實一分錢可以逼死英雄漢,但我覺得人一世物一世,樣樣事情都講錢、講有用、講意義未免太無意思啦,更有意思嘅事情例如靜靜的聽一首歌、諗辦法實現一個自己諗法嘅程式、嘗試一個月坐看夕陽西下、學習一下道家無為之法……人死如燈滅,生前嘅一切名聲 ...

more ...

Linux or ReactOS ?

  用左 Linux 嚟做開發有一段時間,慢慢發覺,Linux 原來面對嘅用戶群應該喺程式撰寫員先至啱 =_=b

  剛開始用 Ubuntu 時,諗住佢好似 Windows 咁樣好容易上手嘅,點知到喺使用嘅過程中遇到好多奇奇怪怪嘅問題,Google 之後,先知道又翻到石器時代,大多數問題唔可以通過 GUI 嚟解決,基本上呢D問題都要直接喺命令行底下解決,或者需要從某D源代碼重新編譯安裝,慢慢咁,到最後,習慣左連GUI都唔用,只用命令行。講真啦,都喺鍾意乜嘢都用鼠標喺各個GUI裡面跳來跳去呢種直觀嘅方式嚟解決問題 -_-|||

  直到上年年尾,發現左一個好玩嘅 OS —— ReactOS,佢哋既目標似乎喺要做一個開源板嘅 Windows NT 內核 OS!哇哈哈,全部繼承左 Windows 系列嘅操作方式,而且完全兼容 Windows NT 及以上 OS 嘅軟體同埋驅動程式!!特別喺驅動程式 ...

more ...

啓明星

今日瀏覽網頁,無意中查左下啓明星,先知道,原來啓明星即系金星,亦系古時所講既「太白」或者「長庚」。傍晚出現時就稱之為「長庚」,清晨出現時稱「啟明」。其它既稱呼仲有:殷星,大正,營星,明星,觀星,大衣,大威,太(白+皋),終星,大相,大囂,爽星,太皓,序星。

可以通過維基百科查詢到更詳細的 金星資料

more ...

MinGW 下 編譯 wxSQLite

初始條件

首先確定環境變量只有 Mingw 的路徑而沒有 msys 的路徑,因為使用 msys 編譯會有些問題。

修改 makefile

打開 wxsqlite3build 下的 makefile.gcc,設定你需要的條件,如若妳不需要加密模塊並且擁有自己的SQLite3源代碼目錄,妳可以設定 SQLITE3_DIR

編譯

make -f makefile.gcc clean
make -f makefile.gcc
more ...

分佈式版本控制系統SVK搭配TortoiseSVN的使用

前言

SVK與Linus所開發的Git相似,是一種分布式的版本控制系統,但它並不是完全從頭編寫的版本控制系統,而是基于 Subversion 的分布式的版本控制系统。如 CVS,Subversion 這些集中式管理系统存在对唯一的版本库过分依赖的缺陷:一旦不能正常连接到集中式的版本库,整个系统陷入瘫痪。分布式的版本控制系統最大的好處在于可以维护分布式的版本库,分散的开发人员可以通过 SVK 建立远程的 CVS,Subversion,P4 协议的版本库镜像,选择工作在自己合适的镜像版本库,这个镜像甚至可以是本地的,整个工作可以离线进行,然后在需要的时候同步镜像版本库到主版本库。

假定條件

首先假定妳已經熟悉所有SVN的操作, 再假定 c:\svnlib 為SVN的對外的倉庫根目錄, 假定妳機子已經安裝好SVN服務, 若 c:\svnlib 下有一項目 test 倉庫(c:\svnlib\test), 假定妳能正確通過Tortoise讀寫其項目文件( svn://localhost/test ), 假定網絡版本庫為 svn://192.168.1 ...

more ...

MinGW 下編譯 gettext 0.17

這兩天編譯gettext搞得焦頭爛額,機子裡裝了大量的開源工具,結果各種動態鏈接庫版本不一致,編譯工具不一致,導致編譯時老是不成功,後來乾脆寫個批處理,把 path 環境變量只設置為 mingw 及 msys 的Bin,把 include 中除 mingw 及 msys的路徑外(例如Gtk)全刪除,然後在Dos下使用以下的編譯命令一次編譯成功:

sh ./configure --enable-threads=win32 --with-libiconv-prefix=d:/sb/sdks/libiconv

當前使用到的編譯環境變量(Mingw GCC4.21):

CPPFLAGS=-mno-cygwin -Wall -pipe -mthreads -fno-strict-aliasing
CFLAGS=-mno-cygwin -O2 -g -pipe -mthreads -fno-strict-aliasing
CXXFLAGS=-mno-cygwin ...
more ...

使用 OTL 連接 SQLite

本文章假定妳熟悉SQLite數據庫,假定妳對OTL有 一定了解,假定妳所使用的操作系統為Windows平台。

OTL 採用的是ODBC數據源機制,到 http://www.ch-werner.de/sqliteodbc/ 可下載到最新的SQLiteODBC數據源驅動。

假定你已經創建了一個名為 MyTestDB 的數據源連接到你的數據庫,數據庫中有一表 Users, 表中有字段 id 及 value,id 为整型,value為字符串50個字節。

代碼:

#include <iostream>
#include <string>

#define OTL_ODBC
#include <otlv4.h>

otl_connect db; // Database connection

void test_select( void )
{

  otl_stream dbstream( 1 , " select * from Users " , db );
  int ...
more ...