一、介紹
??? 不論是音頻數據還是視頻數據,我都為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報告并跟進
??? 不論是音頻數據還是視頻數據,我都為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項目開發過一些開源的解碼器。因此我個人認為我有資格寫一篇文檔來介紹如何開發新的編解碼器。
??? 學習如何添加一個新的編解碼器的最好方法通常是學習大量的已有代碼。本文檔僅僅是對代碼的一個補充,給出一些技巧、關鍵點和一般的路線圖。
??? 術語介紹:“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。