前言
公司最近再搞類似 GoPro 的項目,要 mjpeg playback
目前使用的 display system 是 directfb 的。
找到的方案是 SDL2 directfb backend
Makefile & buildroot package
package | 說明 |
---|---|
SDL2 | right-aligned buildroot ==需要勾選 directfb enable == |
SDL2_image | 如果沒裝sdl2_image 只有 sdl2 的話只能收bmp 格式,mjpeg stream 本身是 一串 JPEG 的流, 需要SDL2_Image 解碼 |
- 有關什麼是 JPEG ,請參考 MJPEG格式和码流分析 感謝大大!!
- 簡單說就是以 0xff d8 為起點, 0xff d9 為終點的有壓縮格式
- directfb 怎樣都無法把光標消除,只好使用下策 /etc/directfbrc
system=fbdev
fbdev=/dev/fb0
no-cursor
原碼
首先要看 怎麼找 0xFFD8 (start) & FFD9 (end)
我寫了以下函數,如果往後有找到 FF D9, 返回 FF 的指標
可以理解如果沒有抵達檔案EOF,則 FF D9 後必為 FF D8 (年年年尾接年頭)
char *searchBuffer(char *b, size_t siz)
{
unsigned char *p1 = (unsigned char *)b;
unsigned char *end = p1 + siz;
for (;;) {
/* find the next 0xff char */
p1 = memchr(p1, 0xff, end - p1);
if (!p1) {
/* sequnce not found, return NULL */
break;
}
if (((p1 + 1) != end) && (*(p1 + 1) == 0xd9)) {
/* found the 0xff 0xd9 sequence */
break;
}
p1 += 1;
}
return (char *)p1;
}
加上main function 就是
這邊參考 SDL2教程(四):timer 定時器 的寫法
如果開啟 DEBUG define 就會改為將mjpeg 逐幀存檔為 .jpeg
unsigned int callback(unsigned int interval, void *param)
{
char file_name[FILE_NAME_LEN];
memcpy(&file_name[0], param, FILE_NAME_LEN);
int ret = 0;
static int cnt = 0;
if (g_cnt == 0) {
g_window = SDL_CreateWindow("SDL Hello", /*title*/
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, /*start by system select*/
320, 240, /*g_window file_size*/
SDL_WINDOW_FULLSCREEN);
g_surface = SDL_GetWindowSurface(g_window);
pFile = fopen(file_name, "rb");
if