ffmpeg和SDL实现的视频播放程序
2012-08-21 19:13
441 查看
ffmpeg和SDL库实现视频解码、显示、按键控制,这里使用了较少的代码70多行,文中使用的视频文件是从优酷网下载的一段264视频“stealth.flv”,与代码放在同一文件夹下。
注:1.
文中没有考虑函数执行错误的情况和内存释放问题。
2.代码只实现了基于ffmpeg和SDL库的视频解码、显示和按键控制,音频和同步待以后学习。
3. ffmpeg版本为0.5.10,其它版本程序可能出错。
4.程序功能在ubuntu上运行正常。
5. 编译命令 gcc -o test test.c -I/INCLUDE_PATH -L/LIB_PATH -pthread -lavdevice -lavformat -lavcodec -ldl -lSDL -lz -lavutil -lm
以下是完整代码:
注:1.
文中没有考虑函数执行错误的情况和内存释放问题。
2.代码只实现了基于ffmpeg和SDL库的视频解码、显示和按键控制,音频和同步待以后学习。
3. ffmpeg版本为0.5.10,其它版本程序可能出错。
4.程序功能在ubuntu上运行正常。
5. 编译命令 gcc -o test test.c -I/INCLUDE_PATH -L/LIB_PATH -pthread -lavdevice -lavformat -lavcodec -ldl -lSDL -lz -lavutil -lm
以下是完整代码:
#include<unistd.h> #include<libavformat/avformat.h> #include<libavcodec/avcodec.h> #include<SDL/SDL.h> #include<SDL/SDL_thread.h> int main(void) { AVFormatContext *pFormatCtx; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame; AVPacket packet; AVPicture pic; SDL_Surface *screen; SDL_Overlay *bmp; SDL_Rect rect; SDL_Event event; int i; int frameFinished; char *filename="stealth.flv"; //初始化解码器和SDL av_register_all(); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER); //打开文件,将文件信息保存到AVFormatContext结构中 av_open_input_file(&pFormatCtx,filename,NULL,0,NULL); //找到文件中的视频流,stealth.flv中有两个流,即nb_streams=2,视频流为0,音频流为1 av_find_stream_info(pFormatCtx); for(i=0;i<pFormatCtx->nb_streams;i++) { if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) { break; } } //找到解码器的信息放到AVCodecContex结构中 pCodecCtx=pFormatCtx->streams[i]->codec; //找到解码器放到AVCodec结构中,并打开它(也就是做一些初始化的工作) pCodec=avcodec_find_decoder(pCodecCtx->codec_id); avcodec_open(pCodecCtx, pCodec); //pFrame用来保存一帧图像,这里为它申请空间 pFrame=avcodec_alloc_frame(); //设置视频显示区域 screen=SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0,0); //创建一个YUV覆盖,显示格式SDL_YV12_OVERLAY bmp=SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen); rect.x=0; rect.y=0; rect.w=pCodecCtx->width; rect.h=pCodecCtx->height; //循环读取视频放到packet中 while( av_read_frame(pFormatCtx, &packet)>=0) { //如果是视频流 if(packet.stream_index==i) { //解码视频流 avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size); //是否解码完一帧? Stealth.flv在这里循环两到三次才解码完一帧 if(frameFinished) { // 上面定义了显示格式SDL_YV12_OVERLAY,与解码出来的YUV420格式U和V分量位置相反 pic.data[0]=bmp->pixels[0]; pic.data[1]=bmp->pixels[2]; pic.data[2]=bmp->pixels[1]; pic.linesize[0]=bmp->pitches[0]; pic.linesize[1]=bmp->pitches[2]; pic.linesize[2]=bmp->pitches[1]; //将pFrame转换到pic中 img_convert(&pic, PIX_FMT_YUV420P, (AVPicture *)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); //显示视频 SDL_DisplayYUVOverlay(bmp,&rect); //由于没有使用时间同步,这里等待30ms,视频传输大约30f/s。使用头文件unistd.h usleep(30000); } } //查询事件 SDL_PollEvent(&event); switch(event.type) { //如果有键盘按键按下 case SDL_KEYDOWN: // 视频退出 SDL_Quit(); exit(0); break; defualt: break; } } return 0; }
相关文章推荐
- 第一个ffmpeg程序,实现播放视频
- VC++实现视频聊天:FFmpeg解码+SDL播放视频
- iOS编译FFmpeg、kxmovie实现视频播放
- qt中用SDL 1.3实现播放视频双窗口
- FFMpeg+SDL2.0 播放本地AVI文件练手示例程序
- FFMPEG小白-day09(sdl项目播放视频)
- qt中用SDL 1.3实现播放视频双窗口(附源代码)
- [绍棠] iOS编译FFmpeg、kxmovie实现视频播放
- iOS编译FFmpeg及使用实现视频播放
- ffmpeg 实现转码一个普通视频文件为视频mpeg4,音频mp3的功能的程序(摘)
- java实现视频上传和播放SpringMVC + Mybatis + ckplayer+ffmpeg+mencoder
- MFC中如何利用ffmpeg和SDL2.0多线程多窗口播放摄像头的视频
- opencv+ffmpeg实现avi视频的播放
- FFMPEG小白-day08(sdl项目播放视频流程及结构体关系图)
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- ffmpeg+SDL的使用之使用SDL播放视频流
- OpenCV 实践程序17——用C++实现ip camera的视频播放
- iOS编译FFmpeg、kxmovie实现视频播放
- Javacv使用ffmpeg实现音视频同步播放
- [iOS]iOS编译FFmpeg、kxmovie实现视频播放