看到 Delphi 盒子有人問視頻處理的問題,這里針對此問題做一些原理上的解釋,
先說能做什么:
1. 簡單的,媒體播放器,播放本地視頻檔案;
2. 捕獲本地攝像頭的視頻,編碼壓縮,網路傳輸出去;網路接收視頻資料,解碼后顯示;
3. 把任意來源的視頻資料,編碼壓縮后保存為錄像檔案;
4. 對視頻資料進行一些處理,比如,疊加字幕,
5. 你能想象到的任何視頻/音頻處理,都能做,
用 Delphi 做媒體處理,比如做一個播放器,或者做一個抓取視頻,錄像成檔案的程式,最方便的是使用 DsPack 那套控制元件,
Dspack 是基于 windows 的 DirectShow 框架的,這個 DirectShow 我之前也不懂,買了兩本書看了半天,發現書也沒講得很明白,當然,按照書上講的做,也能做出 Demo 來,
直到我自己做了一些東西以后,從做的程序中,逐漸猜到它究竟是個什么,這里面,要說清楚,得寫一本書,這里我簡單地說一下:
1. DirectShow 框架是基于 DCOM 的;
2. DirectShow 里面的 Filter 其實就是一個 DCOM,當然它必須滿足 DirectShow 的規范,
3. DirectShow 的架構:
3.1. 假設我們是做一個播放器,從本地打開一個視頻檔案,播放到螢屏上,我們需要:1. 打開檔案,加載資料;2. 解碼檔案,從檔案里面解出視頻幀;3. 逐幀讀入資料,丟給分離器,將幀里面的視頻資料和音頻資料分離;4. 將壓縮的視頻資料解碼;5. 將音頻資料解碼;6. 將解碼后的視頻資料顯示到螢屏上;7. 將解碼后的音頻資料從聲卡播放出來,
3.2. 上述程序,每一步,是一個獨立的功能,為了代碼重用,獨立的功能,傳統的 WINDOWS 程式,就編譯為一個獨立的 DLL,需要某個功能的地方呼叫 DLL 就好了,在 DirectShow 框架里面,就是做成一個一個獨立的 Filter,然后把這些 Filter 串接起來,就可以完成上述功能,
3.3. 這些 Filter,在概念上,模擬為一個電路里面的芯片,把多個芯片連接起來,就是一個完整的視頻播放器,要串接多個 Filter,所以,每個 Filter 必須要有輸入和輸出引腳(引腳的概念,也來自芯片),在 DirectShow 上面,就是說的一個 PIN,在電子元件上面,也是說 PIN 腳,前面一個 Filter 的輸出 PIN,連接后面一個 Filter 的輸出 PIN,如何連接,則是依靠 DirectShow 整個框架,具體的代碼,就是這個框架提供的連接函式,另外,源頭的 Filter 可能只有輸出引腳,最末端的 Filter 可能只有輸入引腳,
3.4. DirectShow 框架,比如你用 Dspack 構建一個視頻播放器,最終在 DirectShow 框架里面,你是構建了一個由多個 Filter 組成的鏈條,如果你做過硬體,就知道,每個 Filter 其實就相當于是一個電子元件,是一個芯片,把整個視頻信號處理的程序,分解為多個不同的功能需要,每個功能,用一個芯片來解決,資料流,流經每個芯片,最終得到視頻畫面,
3.5. 這些 Filter 在系統里面,是以二進制可執行檔案的形態存在,檔案名多半是 .ax,和撰寫它的具體語言無關,它必須符合 DirectShow 的框架,有標準的輸入輸出引腳(PIN),這個引腳,其實也就是符合 DCOM 標準的函式,在 Delphi 語言看來,就是一些【介面 -- Interface】,以及介面底下的函式,
3.6. 上述程序中,你可能想加入一個功能,比如你想在影像畫面上,加入字幕,那就找一個現成的,或者自己寫一個在影像上加字幕的代碼,把這個代碼,按照 DirectShow 的標準,封裝編譯,它就是一個所謂的 Filter,檔案名后綴是 .ax,其實就是一個 DCOM 控制元件,在 DirectShow 框架里面,在處理媒體資料流的程序中,你可以在整個處理鏈條中間,插入任意的 Filter,當然,能不能夠插入,還得看具體的媒體資料型別,但原理就是這個原理,
3.7. 構建好整個鏈條后,它如何被驅動?所有這些代碼,被誰驅動的?DirectShow 框架內部有執行緒在驅動這些代碼,驅動資料流在 Filter 之間傳遞,我們自己寫的程式,可以不用在意哪個執行緒在驅動它,具體到 Delphi,這個被封裝到 Dspack 里面,使用 Dspack 就可以了,
4. 視頻壓縮,也就是要在整個鏈條里面,加入一個視頻壓縮的 Filter,取找現成的,這個自己寫顯然不太現實,另外,如果你的電腦安裝了很多媒體相關的軟體,可能它么也帶來了一些 Filter,你也可以直接拿來用,DirectShow 的好處是,這些 Filter 都是二進制兼容的,在二進制底下可以互相掛接呼叫,無需源代碼,
4.1. 如何知道自己電腦里面有哪些 Filter?其實用 Dspack 控制元件,拖一個 Filter 到界面上,就可以知道,
4.2. DirectShow 官方有提供一個工具:GraphEdit ,這個工具可以列舉電腦里面安裝的 Filter,還可以可視化把各個 Filter 拿出來建立一個鏈條,讓媒體資料在這個鏈條上跑起來,當然,你拿一個音頻的 Filter 接到一個視頻資料的 Filter 后面,多半是接不上去的,資料型別都不同嘛,
4.3. 關于 H.264 的解碼 Filter,有一個開源的給 Delphi 用的,叫做 FFDShow,自己上網搜,這個東西里面可能也包含了一個壓縮編碼的 Filter,我不確定有沒有,
5. 關于錄像成 MP4:
MP4 是一個媒體檔案封裝標準,它內部的編碼可能是 H.264,因此,這里需要 2 個 Filter:
5.1. 壓縮編碼 H.264 的 Filter
5.2. 把視頻資料打包為 MP4 檔案格式的 Filter -- 這個不太好找,但我曾經找到過,
5.3. 其實可以考慮其它的檔案格式,檔案格式和編碼壓縮格式,是兩件不同的事,
5.4. 如果不想通用檔案格式,僅僅是要保存錄像檔案,其實你在編碼為 H.264 以后,可以用自己的檔案格式來保存視頻幀資料,解碼的時候自己決議出幀資料,自己丟給 DirectShow 解碼就好了,
至于,自己寫一個 Filter,DsPack 里面有 Filter 的例子,拿例子來改就好了,這里唯一需要注意的是執行緒問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/356858.html
標籤:其他
上一篇:簡單五子棋的實作
