MPlayer開發

一、介紹
??? 不論是音頻數據還是視頻數據,我都為MPlayer項目開發過一些開源的解碼器。因此我個人認為我有資格寫一篇文檔來介紹如何開發新的編解碼器。
??? 學習如何添加一個新的編解碼器的最好方法通常是學習大量的已有代碼。本文檔僅僅是對代碼的一個補充,給出一些技巧、關鍵點和一般的路線圖。
??? 術語介紹:“Codec"表示編碼器/解碼器(如果你愿意,也可以稱為壓縮器/解壓縮器),它表示一個模塊既可以對數據進行編碼,也可以進行解碼。然而本文檔主要是針對解碼器,而術語“decoder”和“codec”通常也被一起使用。

二、必要的資源
??? 當你決定要為MPlayer實現一個新的解碼器時,那么下面這些應該是你需要的:
(1)實現編解碼器的知識
??? 你需要知道MPlayer傳給你的數據格式,知道如何把其中的數據結構拆開,在重組這些原始的媒體數據時,需要知道對這些數據的算法操作。
(2)媒體樣本
??? MPlayer在解碼時需要確切地知道如何解析存儲在媒體文件中經編碼后的數據格式(包括AVI,ASF,MOV,RM,VIVO等等)。如果MPlayer無法識別媒體文件中的編碼數據,那么你就必須把這種格式轉換為能識別的格式,或者為MPlayer寫你自己的文件解復用器來處理這些數據。如何寫解復用器已經超出了本文檔的論述范圍,此處不做論述。
??? 盡力獲得支持所有可能模式的解碼器的媒體樣本。如果一個音頻的編解碼器同時支持單聲道和立體聲,那么就要找到相應的媒體樣本來測試。如果一個視頻編解碼器能夠同時工作在7種不同的比特率,那么你也要想盡辦法去獲得相應7種比特率編碼的媒體樣本。
(3)最新的CVS快照
??? 為最新的MPlayer開發版本來開發編解碼器同樣也是很重要的,因此要經常用CVS更新你的版本。
(4)普通的編程知識,能在Linux環境下開發
??? 這通常是不用說的,但有時候你卻不得不說。

三、開發流程
(1)建立基本的開發環境
??? 首先,修改你的本地配置文件codecs.conf,它可能是系統共享的或在你主目錄下。為你的編解碼器添加一個新的條目,如果是開源的編解碼器,那么最好把它放在其他開源的編解碼器一起。當你確信把條目添加正確后,一定要把它添加到你的工作目錄的etc/codecs.conf中。想要了解這個配置文件的詳細信息,可以查看codecs.conf.txt。創建一個新的包含相關信息,格式,輸出格式,特定驅動名稱的音頻編解碼或視頻編解碼塊,并記住驅動的名稱。
??? 創建一個新的源文件,它應該包含解碼的主函數以便MPlayer調用來進行解碼數據。最終你可能會有多個文件組成你的解碼器,舉一個簡單的例子如下:
對于一個音頻解碼器,比如ad_sample.c。針對視頻解碼器,可以命名為vd_*.c。
??? 接下來,需要修改Makefile文件使得新的編解碼器被編譯進去。當然,你還需要把解碼器加入到ad.c(對音頻來說)或vd.c(對視頻來說)的數組中。
??? 編譯整個工程,看看到目前為止是否有錯誤。
??? 為了把你的解碼函數放在首要位置,你需要確保你的編碼數據。這聽起來像是一個微小的練習,但卻可能發生很多錯誤。在你解碼函數的開始,加入下面的代碼:
??? int i;
??? for (i = 0; i < 16; i++)
??? ??? printf ("%02X ", input[i]);
??? printf ("/n");
??? 當你編譯并運行MPlayer時,你的解碼函數將會打印它所接收到的每個數據塊的前16個字節。用16進制編輯器打開媒體樣本,看看你屏幕上的輸出和打開文件所看到的,如果解碼器打印的與文件中的一致,那么說明你已經準備好進入第二步了,否則你就要找出為什么沒有得到正確的數據,是因為解碼器沒有被觸發嗎?為什么?
(2)開發解碼器
??? 記住首先要讓它能工作,其次才是工作的快。
??? 解碼器支持什么輸出格式?任何都可以。通常YUV輸出要比RGB輸出受歡迎。如果一個編碼器采用YUV數據作為它的源數據,那么就需要能解碼一個YUV數據的幀。如果編碼器想很多老的視頻編碼器一樣用RGB數據作為輸入,那么支持YUV輸出就沒有意義了,盡可能的輸出RGB格式就可以了。
??? 最受歡迎的視頻數據輸出格式是YV12,因為MPlayer支持大量的硬件設備來對這些數據直接顯示、縮放和過濾。MPlayer同樣也有很多優化的轉換函數能把YV12數據轉換為其他數據輸出格式。
??? 如果你確實采用RGB作為輸出,你必須意識到MPlayer事實上打包RGB為BGR,如果你解碼成BGR24數據緩存,那么輸出如下:
??? B G R B G R B G R B ...
??? 如果你解碼成BGR32,那么在每個BGR后面需要一個額外的字節:
??? B G R - B G R - B G ...
??? 很好地利用檢查方法。在解碼器的開始包含頭文件mp_msg.h,你可以使用mp_msg()函數作為你的printf()語句。一旦你的解碼器發現奇怪的數據或情況,打印如下:
??? mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Odd data encountered: %d/n", data);
顯然,為了你好,你應該使得消息更加清晰。MSGL_WARN對這種類型的信息來說是一個好的消息級別。mp_msg.h中定義了所有的錯誤級別,你甚至可以用MSGL_FATAL來使得MPlayer完全退出,但這不是解碼數據需要的級別。
??? 什么情況下應該觸發一個警告呢?任何超出普通的情況。許多壓縮的視頻數據包含的頭里有寬、高和大小這些數據,把這些域作為參數傳給解碼函數,這些數據應該是匹配的,否則應該給出一個警告并決定應該使用哪個數據。如果頭部信息里應該有一個Magic Number,或是從頭部數據計算出來的,但卻不正確,則應該給出警告。
??? 無論檢查邊界索引有多枯燥,你都必須確保沒有超出理論上的內存范圍,訪問超出范圍的內存會導致段錯誤,永遠不要相信傳遞給你的所有數據都是正確的。一旦索引超出了范圍,就需要給出警告并退出解碼過程(而不是整個應用程序)。
??? 寫出所有可能產生警告的情況看似無聊的,但如果不寫的話,萬一在解碼過程中出現錯誤,你卻不知道是為什么以及在哪里出了錯誤。
(3)調試和測試解碼器
??? 如果你超級幸運,解碼器第一次運行就成功了;或是你很幸運,通過修改了幾個程序錯誤以后,你的解碼器也能工作了。現實來說,你需要查看很多次,修改很多明顯和不明顯的程序錯誤,還需要通過調試來解決一個很小的功能。
??? 提示:請求所有的警告信息。例如gcc的-Wall選項。開發時使用調試模式是很有用的,為了在調試模式下編譯你的MPlayer,使用--enable-debug選項。注意所有的警告并消除所有警告。
(4)把解碼器貢獻到代碼庫
??? 用"diff -u"來創建一個補丁,然后給MPlayer開發組發郵件獲得許可,你需要diff下列文件:
??? - Makefile
??? - etc/codecs.conf
??? - ad.c or vd.c
??? 當然,你應該包含你新創建的文件:vd_<name>.c 或 ad_<name>.c。如果你貢獻夠多的話,MPlayer開發組或許會授予你修改CVS的權利。
(5)等待BUG報告并跟進

??? 當你發布你的編解碼器后,你也許認為你已經完成了,但前提是你足夠幸運。但往往卻事與愿違,所以你需要查看BUG報告并跟進修改BUG。


MPlayer編解碼開發指導

一、介紹
??? 不論是音頻數據還是視頻數據,我都為MPlayer項目開發過一些開源的解碼器。因此我個人認為我有資格寫一篇文檔來介紹如何開發新的編解碼器。
??? 學習如何添加一個新的編解碼器的最好方法通常是學習大量的已有代碼。本文檔僅僅是對代碼的一個補充,給出一些技巧、關鍵點和一般的路線圖。
??? 術語介紹:“Codec"表示編碼器/解碼器(如果你愿意,也可以稱為壓縮器/解壓縮器),它表示一個模塊既可以對數據進行編碼,也可以進行解碼。然而本文檔主要是針對解碼器,而術語“decoder”和“codec”通常也被一起使用。

二、必要的資源
??? 當你決定要為MPlayer實現一個新的解碼器時,那么下面這些應該是你需要的:
(1)實現編解碼器的知識
??? 你需要知道MPlayer傳給你的數據格式,知道如何把其中的數據結構拆開,在重組這些原始的媒體數據時,需要知道對這些數據的算法操作。
(2)媒體樣本
??? MPlayer在解碼時需要確切地知道如何解析存儲在媒體文件中經編碼后的數據格式(包括AVI,ASF,MOV,RM,VIVO等等)。如果MPlayer無法識別媒體文件中的編碼數據,那么你就必須把這種格式轉換為能識別的格式,或者為MPlayer寫你自己的文件解復用器來處理這些數據。如何寫解復用器已經超出了本文檔的論述范圍,此處不做論述。
??? 盡力獲得支持所有可能模式的解碼器的媒體樣本。如果一個音頻的編解碼器同時支持單聲道和立體聲,那么就要找到相應的媒體樣本來測試。如果一個視頻編解碼器能夠同時工作在7種不同的比特率,那么你也要想盡辦法去獲得相應7種比特率編碼的媒體樣本。
(3)最新的CVS快照
??? 為最新的MPlayer開發版本來開發編解碼器同樣也是很重要的,因此要經常用CVS更新你的版本。
(4)普通的編程知識,能在Linux環境下開發
??? 這通常是不用說的,但有時候你卻不得不說。

三、開發流程
(1)建立基本的開發環境
??? 首先,修改你的本地配置文件codecs.conf,它可能是系統共享的或在你主目錄下。為你的編解碼器添加一個新的條目,如果是開源的編解碼器,那么最好把它放在其他開源的編解碼器一起。當你確信把條目添加正確后,一定要把它添加到你的工作目錄的etc/codecs.conf中。想要了解這個配置文件的詳細信息,可以查看codecs.conf.txt。創建一個新的包含相關信息,格式,輸出格式,特定驅動名稱的音頻編解碼或視頻編解碼塊,并記住驅動的名稱。
??? 創建一個新的源文件,它應該包含解碼的主函數以便MPlayer調用來進行解碼數據。最終你可能會有多個文件組成你的解碼器,舉一個簡單的例子如下:
對于一個音頻解碼器,比如ad_sample.c。針對視頻解碼器,可以命名為vd_*.c。
??? 接下來,需要修改Makefile文件使得新的編解碼器被編譯進去。當然,你還需要把解碼器加入到ad.c(對音頻來說)或vd.c(對視頻來說)的數組中。
??? 編譯整個工程,看看到目前為止是否有錯誤。
??? 為了把你的解碼函數放在首要位置,你需要確保你的編碼數據。這聽起來像是一個微小的練習,但卻可能發生很多錯誤。在你解碼函數的開始,加入下面的代碼:
??? int i;
??? for (i = 0; i < 16; i++)
??? ??? printf ("%02X ", input[i]);
??? printf ("/n");
??? 當你編譯并運行MPlayer時,你的解碼函數將會打印它所接收到的每個數據塊的前16個字節。用16進制編輯器打開媒體樣本,看看你屏幕上的輸出和打開文件所看到的,如果解碼器打印的與文件中的一致,那么說明你已經準備好進入第二步了,否則你就要找出為什么沒有得到正確的數據,是因為解碼器沒有被觸發嗎?為什么?
(2)開發解碼器
??? 記住首先要讓它能工作,其次才是工作的快。
??? 解碼器支持什么輸出格式?任何都可以。通常YUV輸出要比RGB輸出受歡迎。如果一個編碼器采用YUV數據作為它的源數據,那么就需要能解碼一個YUV數據的幀。如果編碼器想很多老的視頻編碼器一樣用RGB數據作為輸入,那么支持YUV輸出就沒有意義了,盡可能的輸出RGB格式就可以了。
??? 最受歡迎的視頻數據輸出格式是YV12,因為MPlayer支持大量的硬件設備來對這些數據直接顯示、縮放和過濾。MPlayer同樣也有很多優化的轉換函數能把YV12數據轉換為其他數據輸出格式。
??? 如果你確實采用RGB作為輸出,你必須意識到MPlayer事實上打包RGB為BGR,如果你解碼成BGR24數據緩存,那么輸出如下:
??? B G R B G R B G R B ...
??? 如果你解碼成BGR32,那么在每個BGR后面需要一個額外的字節:
??? B G R - B G R - B G ...
??? 很好地利用檢查方法。在解碼器的開始包含頭文件mp_msg.h,你可以使用mp_msg()函數作為你的printf()語句。一旦你的解碼器發現奇怪的數據或情況,打印如下:
??? mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Odd data encountered: %d/n", data);
顯然,為了你好,你應該使得消息更加清晰。MSGL_WARN對這種類型的信息來說是一個好的消息級別。mp_msg.h中定義了所有的錯誤級別,你甚至可以用MSGL_FATAL來使得MPlayer完全退出,但這不是解碼數據需要的級別。
??? 什么情況下應該觸發一個警告呢?任何超出普通的情況。許多壓縮的視頻數據包含的頭里有寬、高和大小這些數據,把這些域作為參數傳給解碼函數,這些數據應該是匹配的,否則應該給出一個警告并決定應該使用哪個數據。如果頭部信息里應該有一個Magic Number,或是從頭部數據計算出來的,但卻不正確,則應該給出警告。
??? 無論檢查邊界索引有多枯燥,你都必須確保沒有超出理論上的內存范圍,訪問超出范圍的內存會導致段錯誤,永遠不要相信傳遞給你的所有數據都是正確的。一旦索引超出了范圍,就需要給出警告并退出解碼過程(而不是整個應用程序)。
??? 寫出所有可能產生警告的情況看似無聊的,但如果不寫的話,萬一在解碼過程中出現錯誤,你卻不知道是為什么以及在哪里出了錯誤。
(3)調試和測試解碼器
??? 如果你超級幸運,解碼器第一次運行就成功了;或是你很幸運,通過修改了幾個程序錯誤以后,你的解碼器也能工作了。現實來說,你需要查看很多次,修改很多明顯和不明顯的程序錯誤,還需要通過調試來解決一個很小的功能。
??? 提示:請求所有的警告信息。例如gcc的-Wall選項。開發時使用調試模式是很有用的,為了在調試模式下編譯你的MPlayer,使用--enable-debug選項。注意所有的警告并消除所有警告。
(4)把解碼器貢獻到代碼庫
??? 用"diff -u"來創建一個補丁,然后給MPlayer開發組發郵件獲得許可,你需要diff下列文件:
??? - Makefile
??? - etc/codecs.conf
??? - ad.c or vd.c
??? 當然,你應該包含你新創建的文件:vd_<name>.c 或 ad_<name>.c。如果你貢獻夠多的話,MPlayer開發組或許會授予你修改CVS的權利。
(5)等待BUG報告并跟進
??? 當你發布你的編解碼器后,你也許認為你已經完成了,但前提是你足夠幸運。但往往卻事與愿違,所以你需要查看BUG報告并跟進修改BUG。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455052.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

可編程led燈帶原理_SCPSD-250-04-27派克真空壓力傳感器故障和工作原理

SCPSD-250-04-27派克PARKER真空壓力傳感器故障和工作原理PARKER壓力開關現貨 PARKER壓力傳感器特價 派克真空壓力傳感器 PARKER數字壓力開關2020年還剩最后2天了&#xff0c;這一年大家都過得不太容易&#xff0c;尤其是我自己這是30年以來過得最艱難的一年&#xff0c;經…

總結面試時沒有回答上的內存對齊問題

前兩天面試某公司時&#xff0c;沒有回答上的一個問題&#xff0c;總結如下&#xff0c;以供參考。 問&#xff1a;下面這個結構類型的實例變量占用多少內存&#xff1a; struct struct1 { int i; short j; char c; }; 我反問&#xff1a;是啥語言啥機器啥編譯環境…

Kibana入門安裝與介紹

Kibana入門 Kibana 是一款開源的數據分析和可視化平臺&#xff0c;它是 Elastic Stack 成員之一&#xff0c;設計用于和 Elasticsearch 協作。您可以使用 Kibana 對 Elasticsearch 索引中的數據進行搜索、查看、交互操作。您可以很方便的利用圖表、表格及地圖對數據進行多元化…

友善串口工具接收數據隨機換行_使用Python3+PyQT5+Pyserial 實現簡單的串口工具方法...

練手項目&#xff0c;先上圖先實現一個簡單的串口工具&#xff0c;為之后的上位機做準備代碼如下&#xff1a;pyserial_demo.pyimport sys import serial import serial.tools.list_ports from PyQt5 import QtWidgets from PyQt5.QtWidgets import QMessageBox from PyQt5.QtC…

Vue渲染函數

前面的話 Vue 推薦在絕大多數情況下使用 template 來創建HTML。然而在一些場景中&#xff0c;真的需要 JavaScript 的完全編程的能力&#xff0c;這就是 render 函數&#xff0c;它比 template 更接近編譯器。本文將詳細介紹Vue渲染函數 引入 下面是一個例子&#xff0c;如果要…

數據綁定原理

一、數據單向綁定原理指先把模板寫好&#xff0c;然后把模板和數據(數據可能來自后臺)整合到一起形成HTML代碼&#xff0c;最后把這段HTML代碼插入到文檔流里。缺點&#xff1a;一旦HTML代碼生成就沒有辦法改變&#xff0c;如果有新數據重新傳入&#xff0c;就必須重新把模板和…

視頻解碼優化

以下通過剖析一些經驗來了解視頻解碼優化 1. 在嵌入式系統中實現MPEG4的視頻解碼 有兩種方法可行 (1)采用ffmpeg(mplayer 的核心就是采用ffmpeg)&#xff0c;然后對ffmpeg mp4解碼優化 1).對IDCT匯編化,并優化VLD的實現 ->inline&匯編化 2).根據ARM9 cache&cache…

Logstash入門簡介

Logstash入門簡介 介紹 Logstash是一個開源的服務器端數據處理管道&#xff0c;能夠同時從多個來源采集數據&#xff0c;轉換數據&#xff0c;然后將數據發送到最喜歡的存儲庫中&#xff08;我們的存儲庫當然是ElasticSearch&#xff09; 我們回到我們ElasticStack的架構圖&a…

Django templates 和 urls 拆分

如果在Django項目 下面新建了blog和polls兩個APP應用&#xff0c;在每個APP下面都各自新建自己的url和templates&#xff0c;那么我們需要如何進行項目配置呢&#xff1f; INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, dja…

springboot怎么殺進程_線上服務平均響應時間太長,怎么排查?

線上服務平均響應時間太長&#xff0c;怎么排查&#xff1f;https://xie.infoq.cn/article/914b5c56000a3880016abd8d6前言&#xff1a;最近線上環境某個接口服務響應時間偏長&#xff0c;導致用戶體驗超差&#xff0c;那平時該怎么快速的排查這類問題呢&#xff1f;①、為代碼…

Redis學習第五課:Redis Set類型及操作

Set是集合&#xff0c;它是string類型的無序集合。set是通過hash table實現的&#xff0c;添加、刪除和查找的復雜度都是O(1)。 對集合我們可以取并集、交集、差集。通過這些操作我們可以實現SNS中的好友推薦和blog的tag功能。 Set集合操作&#xff1a; sadd:向名稱為Key的set中…

MPEG音視頻編解碼之MP3編解碼概述

2 MP3編解碼原理 2.1 MP3音頻壓縮標準概述 MP3全稱是動態影像專家壓縮標準音頻層面3&#xff08;Moving Picture Experts Group Audio Layer III&#xff09;。是當今較流行的一種數字音頻編碼和有損壓縮格式&#xff0c;它設計用來大幅度地降低音頻數據量&#xff0c;而對于…

Python實現GitBook工具

寫在前面 本工具是通過Python腳本實現 GitBook 自動 生成 執行 編譯 發布的功能 你可以在這里下載exe 使用 1. exe下載,并移動位置 將exe文件放在你的gitbook文件夾中,或者放在空文件夾中 2. file.md 創建 名為file.md的文件,在你要寫book的目錄下 注意: 這里file.md文件名…

shell腳本中用到的條件和循環語句

本博文介紹一下shell腳本中常用的條件和循環語句&#xff1a;條件語句&#xff1a;循環語句&#xff1a;示例&#xff1a;if語句&#xff1a;eg1.eg2.2.case語句&#xff1a;簡單的case語句&#xff1a;配合循環的case語句&#xff1a;3.for語句&#xff1a;簡單的for語句&…

BZOJ 2243 染色(樹鏈剖分好題)

2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 7971 Solved: 2990[Submit][Status][Discuss] Description 給定一棵有n個節點的無根樹和m個操作&#xff0c;操作有2類&#xff1a; 1、將節點a到節點b路徑上所有點都染成顏色c&#xff1b; 2、詢問…

processing動態代碼大全_做一張動態海報需要多少步?

人們習慣性地把程序員跟設計師分成兩種不同性質的人&#xff0c;好像程序員就不會有美感&#xff0c;設計師邏輯思維就一定會很弱&#xff0c;但最近幾年我們發現越來越多的程序員學設計&#xff0c;設計師學編程的跨界故事。新媒體藝術家&#xff0c;邱偉豪也是其中一員&#…

【ffmpeg for wince】音視頻編解碼多平臺移植(for window/wince)

from: http://www.cnblogs.com/windwithlife/archive/2009/05/31/1492728.html 終于完成了了第二個Client side原型&#xff08;for Wince)&#xff0c;其中花掉我最多時間的就是ffmpeg的對WINCE的移植。其中有大半時間是由于網上的一些不完整及不正確信息所誤導&#xff0c;…

python實現猴子爬山算法

猴子爬山一只頑猴在一座有N級臺階的小山上爬山跳躍。上山時需從山腳至山頂往上跳N級臺階&#xff0c;一步可跳1級&#xff0c;或跳3級&#xff0c;求上山有多少種不同的跳法&#xff1f; &#xff08;N<50&#xff09; 問題分析: 每一次都可以選擇1,2,3有3種跳法 方法1 直…

指針版 單鏈表復習

#include <bits/stdc.h> #define P pair<int,int> using namespace std;typedef long long LL;typedef struct LNode{int data;struct LNode *nxt; }LNode,*LinkList;bool Linklist_init(LinkList &root){root new LNode; ///分配頭結點&#xff0c;指針域為空…

手寫springboot_Spring Boot 入門教程 | 圖文講解

目錄一、Spring Boot 是什么二、為什么要使用 Spring Boot三、快速入門3.1 創建 Spring Boot 項目3.2 項目結構3.3 引入 Web 依賴3.4 編寫第一個接口3.5 啟動程序&#xff0c;驗證效果四、總結五、GitHub 示例代碼一、Spring Boot 是什么以下截圖自 Spring Boot 官方文檔&#…