本文来自:
http://blog.chinaunix.net/uid-23093301-id-86399.html
SDL开源图形图像库的简介
SDL(Simple DirectMedia Layer)是一个自由的跨平台的多媒体开发包,它被广泛的用于游戏、演示软件、模拟器、MPEG播放器等应用软件,SDL可以设置8bpp或更高的任意色彩深度的视频模式,也可以直接写入线性的图像帧缓冲framebuffer。SDL支持各种事件如键盘输入、鼠标输入、用户推出等。除此之外,SDL还提供完整的CD音频控制API,以及线程、定时器等工具函数。
基于SDL的视频显示
本课题选用的SDL版本为1.2.13。
基于SDL显示模块主要分如下几步:
● SDL函数库的初始化,主要是设置SDL支持视频显示。
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
● 设置视频显示模式,SDL会尝试使用硬件加速,如果硬件加速失败,SDL会自动调整尽量使用与设置最为接近的模式。
screen = SDL_SetVideoMode (WIDTH, HEIGHT, 0, SDL_HWSURFACE
| SDL_DOUBLEBUF
| SDL_ANYFORMAT
| SDL_RESIZABLE);
● 设置窗口显示标题
SDL_WM_SetCaption ("USB Camera By Breeze", NULL);
● 创建YUV覆盖。多媒体领域中,尤其涉及到MPEG的播放时,通常使用YUV的颜色空间,如果MPEG的图片要在屏幕上显示则需要YUV到RGB的转化。某些显示芯片能够支持YUV到RGB的转换,免去软件转换的性能损失。这样,只要将YUV信息写到缓冲区,硬件就能自动完成YUV到RGB的转换并将图像显示到屏幕上。
overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
● 将视频信息传送到显示设备上。SDL_LockSurface(screen);
SDL_LockYUVOverlay(overlay);
pict.data[0] = overlay->pixels[0];
pict.data[1] = overlay->pixels[2];
pict.data[2] = overlay->pixels[1];
pict.linesize[0] = overlay->pitches[0];
pict.linesize[1] = overlay->pitches[2];
pict.linesize[2] = overlay->pitches[1];
SDL_UnlockYUVOverlay(overlay);
SDL_UnlockSurface(screen);
SDL_DisplayYUVOverlay(overlay, &rect);
基于x264压缩保存图像
x264压缩编码介绍
x264是优秀的免费的MPEG-4视频编码格式,基于H264算法,拥有如下特点:
● 采用CAVLC/CABAC多种算法编码
● 内置所有macroblock格式(16x16, 8x8, and 4x4 )
● Inter P:所有的分割块(从16x16到4x4 )
● Inter B:分割块从16x16到8x8
● 码率控制:恒定的分层编制,单次或多次的ABR压制,可选的VBV压制
● 场景剪切侦测
● 支持B-frame
● 能够任意编制B-frame命令行
● 无损模式
● 8x8和4x4的格式能够进行翻转或旋转
● 自定义精确的矩阵模板
● 可在多个CPU平行编码
● 隔行扫描的文件质量要好。它符合GPL许可证。
x264库的安装
● 通过如下方式获得x264源码:
svn co svn://svn.videolan.org/x264/trunk x264
● 进行编译安装
./configure --prefix=/usr --enable-shared
配置为下:
Platform: X86 System: LINUX asm: yes avis input: no mp4 output: yes pthread: yes debug: no gprof: no PIC: no shared: yes visualize: no
#make && make install
FFMPEG中安装对x264的支持
本课题利用FFMPEG将视频进行无损的压缩保存,x264编码能在尽量保证视频质量到同时做到大比例到压缩,是非常流行到MPEG-4编码,本课题选用x264编码压缩视频数据后保存为mp4文件。
● 配置FFMPEG 支持x264
./configure
--enable-gpl
--enable-static
--enable-xvid
--enable-x264
--disable-shared
配置的最终效果为:
C compiler gcc
.align is power-of-two no
ARCH x86 (generic)
big-endian no
yasm yes
MMX enabled yes
MMX2 enabled yes
3DNow! enabled yes
3DNow! extended enabled yes
SSE enabled yes
SSSE3 enabled yes
CMOV enabled no
CMOV is fast no
EBX available yes
EBP available yes
10 operands supported yes
gprof enabled no
debug symbols yes
strip symbols yes
optimizations yes
static yes
shared yes
postprocessing support no
software scaler enabled yes
new filter support no
filters using lavformat no
video hooking yes
Imlib2 support no
FreeType support yes
network support yes
IPv6 support yes
threading support no
SDL support yes
libx264 enabled yes
libxvid enabled yes
vdpau enabled no
zlib enabled yes
bzlib enabled yes
Enabled encoders:
ac3 ljpeg pcm_u24le
adpcm_adx mjpeg pcm_u32be
adpcm_g726 mp2 pcm_u32le
adpcm_ima_qt mpeg1video pcm_u8
adpcm_ima_wav mpeg2video pcm_zork
adpcm_ms mpeg4 pgm
adpcm_swf msmpeg4v1 pgmyuv
adpcm_yamaha msmpeg4v2 png
alac msmpeg4v3 ppm
asv1 nellymoser qtrle
asv2 pam rawvideo
bmp pbm roq
dnxhd pcm_alaw roq_dpcm
dvbsub pcm_f32be rv10
dvdsub pcm_f32le rv20
dvvideo pcm_f64be sgi
ffv1 pcm_f64le snow
ffvhuff pcm_mulaw sonic
flac pcm_s16be sonic_ls
flashsv pcm_s16le svq1
flv pcm_s24be targa
gif pcm_s24daud tiff
h261 pcm_s24le vorbis
h263 pcm_s32be wmav1
h263p pcm_s32le wmav2
huffyuv pcm_s8 wmv1
jpegls pcm_u16be wmv2
libx264 pcm_u16le zlib
libxvid pcm_u24be zmbv
License: GPL
● 编译安装
#make && make install
最后在生成如下文件:
1)头文件
libavcodec/ libavformat/ libswscale/
libavdevice/ libavutil/
2)库文件
libavcodec.a libavdevice.a libavformat.a libavutil.a
libavcodec.so libavdevice.so libavformat.so libavutil.so
FFMPEG实现视频流压缩保存
● 初始化FFMPEG函数库,初始化视频编码器
● 根据编码器初始化视频流结构体,设置比特率等
st = av_new_stream(oc, 0);
if (!st) {
fprintf(stderr, "Could not alloc stream
");
exit(1);
}
c = st->codec;
c->codec_id = CODEC_ID_H264;
c->codec_type = CODEC_TYPE_VIDEO;
/* put sample parameters */
c->bit_rate = 1000;//40;
c->sample_rate = 800*1000;
c->time_base = (AVRational){1,25};//! 如果有延迟就改这里
c->gop_size = 12;
● 转换原始图像数据颜色空间到YUV420P
img_convert_ctx = sws_getCachedContext( img_convert_ctx,
cc->width, cc->height,
cc->pix_fmt,
cc->width, cc->height,
(PixelFormat)src_pix_fmt,
sws_flags,
NULL, NULL, NULL);
sws_scale(img_convert_ctx, picture->data, picture->linesize,
0, cc->height, destFrame->data, destFrame->linesize);
● 编码压缩
out_size = avcodec_encode_video(cc, m_video_outbuf, m_video_outbuf_size, picture);
● 将编码后的一帧图像数据写到文件里
pkt.stream_index= m_video_st->index;
pkt.data= m_video_outbuf;
pkt.size= out_size;
ret = av_write_frame(m_fc, &pkt);
● 最后写文件尾等信息到MP4目标文件,关闭文件,释放资源等。
avcodec_close(m_video_st->codec);
av_write_trailer(m_fc);
url_fclose(m_fc->pb);
av_free(m_fc);
小结
本章讨论了PC端视频监控系统的设计和实现。JRTPLIB是开源的优秀的RTP函数库,PC端基于JRTPLIB实现的RTP接收模块。本章讨论了FFMPEG音视频函数库的开发技术,基于FFMPEG实现了图像颜色空间的转换,并通过SDL图形显示库将视频图像实时显示到屏幕上。H264是优秀的视频编码算法,本章通过FFMPEG实现了将图像数据按H264进行编码压缩,并保存成MP4文件。