SDL2播放YUV
本文記錄SDL播放視訊的技術。在這裡使用的版本是SDL2。實際上SDL本身並不提供視音訊播放的功能,它只是封裝了視音訊播放的底層API。在Windows平臺下,SDL封裝了Direct3D這類的API用於播放視訊;封裝了DirectSound這類的API用於播放音訊。因為SDL的編寫目的就是簡化視音訊播放的開發難度,所以使用SDL播放視訊(YUV/RGB)和音訊(PCM)資料非常的容易。下文記錄一下使用SDL播放視訊資料的技術。
SDL簡介
SDL(Simple DirectMedia Layer)是一套開放原始碼的跨平臺多媒體開發庫,使用C語言寫成。SDL提供了數種控制影象、聲音、輸出入的函式,讓開發者只要用相同或是相似的程式碼就可以開發出跨多個平臺(Linux、Windows、Mac OS X等)的應用軟體。目前SDL多用於開發遊戲、模擬器、媒體播放器等多媒體應用領域。用下面這張圖可以很明確地說明SDL的位置。
SDL實際上並不限於視音訊的播放,它將功能分成下列數個子系統(subsystem):
Video(影象):影象控制以及執行緒(thread)和事件管理(event)。
Audio(聲音):聲音控制
Joystick(搖桿):遊戲搖桿控制
CD-ROM(光碟驅動器):光碟媒體控制
Window Management(視窗管理):與視窗程式設計整合
Event(事件驅動):處理事件驅動
在Windows下,SDL與DirectX的對應關係如下。
SDL |
DirectX |
SDL_Video、SDL_Image |
DirectDraw、Direct3D |
SDL_Audio、SDL_Mixer |
DirectSound |
SDL_Joystick、SDL_Base |
DirectInput |
SDL_Net |
DirectPlay |
SDL播放視訊的流程
SDL播放視訊的技術在此前做的FFmpeg的示例程式中已經多次用到。在這裡重新總結一下流程。
1. 初始化
1) 初始化SDL
2) 建立視窗(Window)
3) 基於視窗建立渲染器(Render)
4) 建立紋理(Texture)
2. 迴圈顯示畫面
1) 設定紋理的資料
2) 紋理複製給渲染目標
3) 顯示
下面詳細分析一下上文的流程。
1. 初始化
1) 初始化SDL
使用SDL_Init()初始化SDL。該函式可以確定希望啟用的子系統。SDL_Init()函式原型如下:
[cpp] view plain copy- int SDLCALL SDL_Init(Uint32 flags)
其中,flags可以取下列值:
SDL_INIT_TIMER:定時器
SDL_INIT_AUDIO:音訊
SDL_INIT_VIDEO:視訊
SDL_INIT_JOYSTICK:搖桿
SDL_INIT_HAPTIC:觸控式螢幕
SDL_INIT_GAMECONTROLLER:遊戲控制器
SDL_INIT_EVENTS:事件
SDL_INIT_NOPARACHUTE:不捕獲關鍵訊號(這個沒研究過)
SDL_INIT_EVERYTHING:包含上述所有選項
有關SDL_Init()有一點需要注意:初始化的時候儘量做到“夠用就好”,而不要用SDL_INIT_EVERYTHING。因為有些情況下使用SDL_INIT_EVERYTHING會出現一些不可預知的問題。例如,在MFC應用程式中播放純音訊,如果初始化SDL的時候使用SDL_INIT_EVERYTHING,那麼就會出現聽不到聲音的情況。後來發現,去掉了SDL_INIT_VIDEO之後,問題才得以解決。
2) 建立視窗(Window)
使用SDL_CreateWindow()建立一個用於視訊播放的視窗。SDL_CreateWindow()的原型如下。
- SDL_Window * SDLCALL SDL_CreateWindow(const char *title,
- int x, int y, int w,
- int h, Uint32 flags);
引數含義如下。
title :視窗標題
x :視窗位置x座標。也可以設定為SDL_WINDOWPOS_CENTERED或SDL_WINDOWPOS_UNDEFINED。
y :視窗位置y座標。同上。
w :視窗的寬
h :視窗的高
flags :支援下列標識。包括了視窗的是否最大化、最小化,能否調整邊界等等屬性。
::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL,
::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_BORDERLESS,
::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED,
::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_INPUT_GRABBED,
::SDL_WINDOW_ALLOW_HIGHDPI.
返回建立完成的視窗的ID。如果建立失敗則返回0。
3) 基於視窗建立渲染器(Render)
使用SDL_CreateRenderer()基於視窗建立渲染器。SDL_CreateRenderer()原型如下。
- SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window,
- int index, Uint32 flags);
引數含義如下。
window : 渲染的目標視窗。
index :打算初始化的渲染裝置的索引。設定“-1”則初始化預設的渲染裝置。
flags :支援以下值(位於SDL_RendererFlags定義中)
SDL_RENDERER_SOFTWARE :使用軟體渲染
SDL_RENDERER_ACCELERATED :使用硬體加速
SDL_RENDERER_PRESENTVSYNC:和顯示器的重新整理率同步
SDL_RENDERER_TARGETTEXTURE :不太懂
返回建立完成的渲染器的ID。如果建立失敗則返回NULL。
4) 建立紋理(Texture)
使用SDL_CreateTexture()基於渲染器建立一個紋理。SDL_CreateTexture()的原型如下。
- SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer,
- Uint32 format,
- int access, int w,
- int h);
引數的含義如下。
renderer:目標渲染器。
format :紋理的格式。後面會詳述。
access :可以取以下值(定義位於SDL_TextureAccess中)
SDL_TEXTUREACCESS_STATIC :變化極少
SDL_TEXTUREACCESS_STREAMING :變化頻繁
SDL_TEXTUREACCESS_TARGET :暫時沒有理解
w :紋理的寬
h :紋理的高
建立成功則返回紋理的ID,失敗返回0。
在紋理的建立過程中,需要指定紋理的格式(即第二個引數)。SDL的中的格式很多,如下所列。
- SDL_PIXELFORMAT_UNKNOWN,
- SDL_PIXELFORMAT_INDEX1LSB =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0,
- 1, 0),
- SDL_PIXELFORMAT_INDEX1MSB =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0,
- 1, 0),
- SDL_PIXELFORMAT_INDEX4LSB =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0,
- 4, 0),
- SDL_PIXELFORMAT_INDEX4MSB =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0,
- 4, 0),
- SDL_PIXELFORMAT_INDEX8 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1),
- SDL_PIXELFORMAT_RGB332 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB,
- SDL_PACKEDLAYOUT_332, 8, 1),
- SDL_PIXELFORMAT_RGB444 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
- SDL_PACKEDLAYOUT_4444, 12, 2),
- SDL_PIXELFORMAT_RGB555 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
- SDL_PACKEDLAYOUT_1555, 15, 2),
- SDL_PIXELFORMAT_BGR555 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
- SDL_PACKEDLAYOUT_1555, 15, 2),
- SDL_PIXELFORMAT_ARGB4444 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB,
- SDL_PACKEDLAYOUT_4444, 16, 2),
- SDL_PIXELFORMAT_RGBA4444 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA,
- SDL_PACKEDLAYOUT_4444, 16, 2),
- SDL_PIXELFORMAT_ABGR4444 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR,
- SDL_PACKEDLAYOUT_4444, 16, 2),
- SDL_PIXELFORMAT_BGRA4444 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA,
- SDL_PACKEDLAYOUT_4444, 16, 2),
- SDL_PIXELFORMAT_ARGB1555 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB,
- SDL_PACKEDLAYOUT_1555, 16, 2),
- SDL_PIXELFORMAT_RGBA5551 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA,
- SDL_PACKEDLAYOUT_5551, 16, 2),
- SDL_PIXELFORMAT_ABGR1555 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR,
- SDL_PACKEDLAYOUT_1555, 16, 2),
- SDL_PIXELFORMAT_BGRA5551 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA,
- SDL_PACKEDLAYOUT_5551, 16, 2),
- SDL_PIXELFORMAT_RGB565 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
- SDL_PACKEDLAYOUT_565, 16, 2),
- SDL_PIXELFORMAT_BGR565 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
- SDL_PACKEDLAYOUT_565, 16, 2),
- SDL_PIXELFORMAT_RGB24 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0,
- 24, 3),
- SDL_PIXELFORMAT_BGR24 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0,
- 24, 3),
- SDL_PIXELFORMAT_RGB888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB,
- SDL_PACKEDLAYOUT_8888, 24, 4),
- SDL_PIXELFORMAT_RGBX8888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX,
- SDL_PACKEDLAYOUT_8888, 24, 4),
- SDL_PIXELFORMAT_BGR888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR,
- SDL_PACKEDLAYOUT_8888, 24, 4),
- SDL_PIXELFORMAT_BGRX8888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX,
- SDL_PACKEDLAYOUT_8888, 24, 4),
- SDL_PIXELFORMAT_ARGB8888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
- SDL_PACKEDLAYOUT_8888, 32, 4),
- SDL_PIXELFORMAT_RGBA8888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA,
- SDL_PACKEDLAYOUT_8888, 32, 4),
- SDL_PIXELFORMAT_ABGR8888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR,
- SDL_PACKEDLAYOUT_8888, 32, 4),
- SDL_PIXELFORMAT_BGRA8888 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA,
- SDL_PACKEDLAYOUT_8888, 32, 4),
- SDL_PIXELFORMAT_ARGB2101010 =
- SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
- SDL_PACKEDLAYOUT_2101010, 32, 4),
- SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */
- SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'),
- SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */
-
相關推薦
8.基於SDL2播放YUV視訊
參考資料: 1.雷博部落格 一.簡介 二、流程及函式 1)視訊播放流程 2)常用函式 3)程式碼 4)工程 前面講video解碼為YUV原始資料,接下來則需
SDL2播放YUV
本文記錄SDL播放視訊的技術。在這裡使用的版本是SDL2。實際上SDL本身並不提供視音訊播放的功能,它只是封裝了視音訊播放的底層API。在Windows平臺下,SDL封裝了Direct3D這類的API用於播放視訊;封裝了DirectSound這類的API用於播放音訊。因為SDL的編寫目的
最簡單的視音頻播放演示樣例7:SDL2播放RGB/YUV
pro big 更新 沒有 opaque support 解決 控制 mem =====================================================最簡單的視音頻播放演示樣例系列文章列表:最簡單的視音頻播放演示樣例1:總述最簡單的視音
最簡單的視音訊播放示例7:SDL2播放RGB/YUV
=====================================================最簡單的視音訊播放示例系列文章列表:=====================================================本文記錄SDL播放視訊的技術
10.基於FFMPEG+SDL2播放video---音視訊同步(參考音訊時鐘)
繼續FFMPEG學習之路。。。 參考資料: An ffmpeg and SDL Tutorial 文章目錄 1 綜述 2 音視訊同步 3 DTS 和 PTS 4 音訊時鐘 5 視訊PTS 6 同步 7 不
9.基於FFMPEG+SDL2播放視訊(解碼執行緒和播放執行緒分開)
參考資料: 1.雷博部落格 2. An ffmpeg and SDL Tutorial 繼續FFMPEG學習之路。。。 文章目錄 1 綜述 2 程式碼1(基礎程式碼) 3 程式碼2(播放執行緒和解碼執行緒分開) 3.1 幾個結構體
6.基於FFMPEG+SDL2播放音訊
參考資料: 1.雷博部落格 2. An ffmpeg and SDL Tutorial 前面瞭解了FFMPEG解碼MP3檔案為PCM,以及將PCM通過SDL2進行播放,下面就是將這兩者進行結合,使之能夠邊解碼邊播放。。。。 一、綜述 二、程式碼
5.基於SDL2播放PCM音訊
接上一篇<基於FFMPEG將音訊解碼為PCM>,接下來就是需要將PCM音訊進行播放,查閱資料是通過SDL進行音視訊的播放,因此這裡記錄一下SDL相關的筆記。。。 一.簡介 摘抄自百度百科: SDL(Simple DirectMedia Layer)是一套開
最簡單的視音訊播放示例9:SDL2播放PCM
最簡單的視音訊播放示例系列文章列表: ===================================================== 本文記錄SDL播放音訊的技術。在這裡使用的版本是SDL2。實際上SDL本身並不提供視音訊播放的功能,它只
VLC播放YUV檔案
副檔名需為.yuv,每秒5幀播放畫素格式為UYVY解析度為704x576的yuv檔案的步驟如下: 1、執行VLC 2、“媒體”-》“高階開啟檔案...”選單項調出“開啟媒體”對話方塊 3、新增檔案 4、選中“顯示更多選項”,在“編輯選項”中輸入:demux=
android ffmpeg+OpenGL播放yuv+openSL 快放 慢放 視訊播放器
這裡是完整的音視訊播放器,功能如下(這裡有iOS版的): 視訊是通過opengl 播放yuv資料,音訊是opensl播放。 app執行流程如下圖: 紅色虛線內的是一個執行緒的執行,總共涉及到四個執行緒。 java層幾乎沒有播放器的內容,ffmpe
使用SDL2播放音訊檔案出現斷斷續續的問題
自己在雷神的部落格上找到了播放音訊檔案的示例程式。程式順利跑通。 自後自己在window進行編譯,編譯通過。可是在進行播放的時候,聲音老是斷斷續續地播放。我嘗試了好多次,實在是不知道原因。仔細翻閱了雷神相關的SDL部落格。才發現, 原來時SDL版本的問題。 我看的示例程式是
android ffmpeg+OpenGL播放yuv+openSL 快放 慢放 視訊播放器
這裡是完整的音視訊播放器,功能如下(這裡有iOS版的): 視訊是通過opengl 播放yuv資料,音訊是opensl播放。 app執行流程如下圖: 紅色虛線內的是一個執行緒的執行,總共涉及到四個執行緒。 java層幾乎沒有播放器的內容,ffmpeg,opengl,opensl都
SDL2播放FFmpeg解壓的視頻
open dex n) end pac ios 文件中 h.264 second SDL2簡化了播放過程,這裏引入播放視頻。 1. 以我的《FFmpeg入門測試》為工程。 2. 到http://www.libsdl.org/index.php下載SDL2-devel
播放yuv檔案遇到的問題及解決方法
其實這也算是一個簡單的問題,可是自己老是忘記。播放yuv檔案,需要注意兩個地方的引數。 幀率不用管,一般是25或者30幀左右。其中注意yuv型別和解析度。自己犯錯的地方是就是這兩個引數。 一般來說,從攝像頭獲取的型別是Iyuv(I420),這個地方預設的是RGB3
SDL2---編譯SDL庫、測試播放簡單畫素資料(YUV、RGB等)
本篇博文整理自雷神(雷霄驊https://blog.csdn.net/leixiaohua1020/article/list/3)多篇博文,多謝分享,在此致敬! SDL簡介: SDL庫的作用說白了就是封裝了複雜的視音訊底層操作,簡化了視音訊處理的難度。 以下轉自WiKi:
mac:使用VLC播放純視訊YUV檔案(命令列)
有時候,我們需要播放一些純視訊檔案,判斷YUV資料是否可用。舉個例子,我們使用命令列播放/Users/lz目錄下的test_yuv420p_320x180.yuv檔案,命令如下: /Applications/VLC.app/Contents/MacOS/VLC --demux rawvide
FFmpeg 4.0.2 + SDL2-2.0.8 實現H264解碼後播放
一、初級版 功能:實現了簡易視訊播放器的功能,能解碼H264後播放 工具:FFmpeg 4.0.2 + SDL2-2.0.8 C++程式碼: /************************************* 功能:H264解碼為YUV序列,通過SDL播放 FFmpeg:
FFmpeg把MP4檔案解碼為YUV,然後通過SDL播放
#include <iostream> extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swsca
windows下使用FFmpeg生成YUV視訊檔案並播放(通過命令的方式)
一、YUV的定義 YUV是一種顏色編碼方法。它跟我們常見的RGB格式區分開來,常使用在各個視訊處理元件中。其中"Y"代表明亮度,"U"和"V"代表其色度。視訊播放器把市面上流行的MP4等格式的視訊檔案解碼出來,得到的一般會是YUV格式的資料,然後得進行轉碼(比如通過op