我已經寫了許多播放器應用程序(適用於Windows),它們結合了視頻和音頻,並且需要兩者之間的精確同步。在Windows音頻中,您基本上準備緩衝區(它們只是音頻採樣值的數組),並將它們排隊到音頻子系統進行播放;子系統會在每個緩衝區完成回放時對您的應用程序進行回調,並且您的應用程序會使用每個回調來1)將下一幀渲染到屏幕,以及2)準備將下一個音頻塊排入音頻子系統。例如,假設您想要以每秒50幀的速度在內存中播放一些視頻幀,並與單聲道音頻,每個樣本2個字節和每秒44,100個樣本同步播放。這意味着您的音頻緩衝區需要882個樣本(44,100/50 = 882),因此每個緩衝區只是一個包含882個元素的短整型數組(2字節)。您至少需要兩個緩衝區,但在實踐中更多更好(與緩衝區的折衷是更多的緩衝區意味着以更長的啓動延遲和更大的內存佔用爲代價的更平滑的回放)。
視頻的幀需要以相同的方式「緩衝」,以便至少有一幀始終準備好進行渲染;將單個圖像傳輸到PC屏幕非常快,以至於它實際上是瞬間的,而不是您需要擔心的事情。唯一的問題是用任何方法提取或組成幀。這些方法需要至少足夠快以跟上播放速度,或者需要在播放之前進行緩衝,這也會導致較長的啓動延遲和較大的內存佔用量(這些問題對於視頻而言要差得多它們是用於音頻的,具有任何合理的分辨率)。
當應用程序開始播放時,它會將所有帶有音頻的緩衝區預加載並排隊等待播放;然後,它同時開始播放並將第一幀渲染到屏幕上。用戶看到第一幀並聽到音頻的前20 ms(20 ms = 1/50秒)。此時音頻子系統將回放從第一個緩衝區切換到第二個緩衝區,並對應用程序進行回調。然後,應用程序將第二幀渲染到屏幕上,並使用下一個可用的音頻塊填充第一個緩衝區,然後將第一個緩衝區再次排隊到音頻子系統。
只要應用程序有音頻和視頻數據可用來保持填充緩衝區和幀,此過程將繼續,並且您可以看到/聽到視頻。
VLC是開源的不是嗎?你可以檢查:) –
我只記得我們是如何用袖珍電腦上的mpeg lib做到的。就像你描述的那樣。我們使用了一個2D庫,打開了一個表面,將框架位複製到表面並將其翻轉到屏幕上。當然你可以提前緩衝幾幀,或者在幀之間進行內插等整齊的操作。但我不認爲在這一點上有更多的魔力,而不僅僅是將像素帶到屏幕上。 – dowhilefor
繪製圖像並將音頻數據與音頻 - 視頻時間同步。 – 9dan