/**
* 最简单的基于FFmpeg的视频播放器SU(SDL升级版)
* Simplest FFmpeg Player (SDL Update)
*
* 雷霄骅 Lei Xiaohua
* leixiaohua1020@126.com
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
* 本程序实现了视频文件的解码和显示(支持HEVC,H.264,MPEG2等)。
* 是最简单的FFmpeg视频解码方面的教程。
* 通过学习本例子可以了解FFmpeg的解码流程。
* 本版本中使用SDL消息机制刷新视频画面。
* This software is a simplest video player based on FFmpeg.
* Suitable for beginner of FFmpeg.
*
* Version:1.1
*
* 备注:
* 标准版在播放视频的时候,画面显示使用延时40ms的方式。这么做有两个后果:
* (1)SDL弹出的窗口无法移动,一直显示是忙碌状态
* (2)画面显示并不是严格的40ms一帧,因为还没有考虑解码的时间。
* SU(SDL Update)版在视频解码的过程中,不再使用延时40ms的方式,而是创建了
* 一个线程,每隔40ms发送一个自定义的消息,告知主函数进行解码显示。这样做之后:
* (1)SDL弹出的窗口可以移动了
* (2)画面显示是严格的40ms一帧
* Remark:
* Standard Version use's SDL_Delay() to control video's frame rate, it has 2
* disadvantages:
* (1)SDL's Screen can't be moved and always "Busy".
* (2)Frame rate can't be accurate because it doesn't consider the time consumed
* by avcodec_decode_video2()
* SU(SDL Update)Version solved 2 problems above. It create a thread to send SDL
* Event every 40ms to tell the main loop to decode and show video frames.
*/
#include "stdafx.h"
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
//新版里的图像转换结构需要引入的头文件
#include "libswscale/swscale.h"
//SDL
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
};
//自定义事件
//刷新画面
#define SFM_REFRESH_EVENT (SDL_USEREVENT + 1)
int thread_exit=0;
//Thread
int sfp_refresh_thread(void *opaque)
{
while (thread_exit==0) {
SDL_Event event;
event.type = SFM_REFRESH_EVENT;
SDL_PushEvent(&event);
//Wait 40 ms
SDL_Delay(40);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
char filepath[]="src01_480x272_22.hm10";
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
printf("Couldn't open input stream.(无法打开输入流)\n");
return -1;
}
if(av_find_stream_info(pFormatCtx)<0)
{
printf("Couldn't find stream information.(无法获取流信息)\n");
return -1;
}
videoindex=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoindex=i;
break;
}
if(videoindex==-1)
{
printf("Didn't find a video stream.(没有找到视频流)\n");
return -1;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
printf("Codec not found.(没有找到解码器)\n");
return -1;
}
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
{
printf("Could not open codec.(无法打开解码器)\n");
return -1;
}
AVFrame *pFrame,*pFrameYUV;
pFrame=avcodec_alloc_frame();
pFrameYUV=avcodec_alloc_frame();
uint8_t *out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
//------------SDL----------------
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
int screen_w=0,screen_h=0;
SDL_Surface *screen;
screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
screen = SDL_SetVideoMode(screen_w, screen_h, 0,0);
if(!screen) {
printf("SDL: could not set video mode - exiting:%s\n",SDL_GetError());
return -1;
}
SDL_Overlay *bmp;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen);
SDL_Rect rect;
int ret, got_picture;
AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
//输出一下信息-----------------------------
printf("File Information(文件信息)---------------------\n");
av_dump_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\n");
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
//--------------
SDL_Thread *video_tid = SDL_CreateThread(sfp_refresh_thread,NULL);
//
SDL_WM_SetCaption("Simple FFmpeg Player (SDL Update)",NULL);
//Event Loop
SDL_Event event;
for (;;) {
//Wait
SDL_WaitEvent(&event);
if(event.type==SFM_REFRESH_EVENT){
//------------------------------
if(av_read_frame(pFormatCtx, packet)>=0){
if(packet->stream_index==videoindex){
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < 0){
printf("Decode Error.(解码错误)\n");
return -1;
}
if(got_picture){
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
SDL_LockYUVOverlay(bmp);
bmp->pixels[0]=pFrameYUV->data[0];
bmp->pixels[2]=pFrameYUV->data[1];
bmp->pixels[1]=pFrameYUV->data[2];
bmp->pitches[0]=pFrameYUV->linesize[0];
bmp->pitches[2]=pFrameYUV->linesize[1];
bmp->pitches[1]=pFrameYUV->linesize[2];
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = screen_w;
rect.h = screen_h;
//测试自己填充数据----------------
SDL_DisplayYUVOverlay(bmp, &rect);
}
}
av_free_packet(packet);
}else{
//Exit Thread
thread_exit=1;
break;
}
}
}
SDL_Quit();
sws_freeContext(img_convert_ctx);
//--------------
av_free(out_buffer);
av_free(pFrameYUV);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
最简单的基于FFMPEG的视频播放器1.1
共315个文件
h:260个
lib:18个
dll:18个
5星 · 超过95%的资源 需积分: 0 1.1k 下载量 49 浏览量
2014-08-25
11:55:09
上传
评论 7
收藏 16.93MB 7Z 举报
温馨提示
本程序实现了视频文件的解码和显示(支持HEVC,H.264,MPEG2等)。 是最简单的FFmpeg视频解码方面的教程。 通过学习本例子可以了解FFmpeg的解码流程。 项目包含两个工程: simplest_ffmpeg_player:标准版,FFmpeg学习的开始。 simplest_ffmpeg_player_su:SU(SDL Update)版,加入了简单的SDL的Event。 备注: 标准版在播放视频的时候,画面显示使用延时40ms的方式。这么做有两个后果: (1)SDL弹出的窗口无法移动,一直显示是忙碌状态 (2)画面显示并不是严格的40ms一帧,因为还没有考虑解码的时间。 SU(SDL Update)版在视频解码的过程中,不再使用延时40ms的方式,而是创建了 一个线程,每隔40ms发送一个自定义的消息,告知主函数进行解码显示。这样做之后: (1)SDL弹出的窗口可以移动了 (2)画面显示是严格的40ms一帧
资源推荐
资源详情
资源评论
收起资源包目录
最简单的基于FFMPEG的视频播放器1.1 (315个子文件)
simplest_ffmpeg_player_su.cpp 6KB
simplest_ffmpeg_player.cpp 5KB
stdafx.cpp 231B
stdafx.cpp 230B
avcodec-55.dll 18.06MB
avcodec-55.dll 18.06MB
avformat-55.dll 5.1MB
avformat-55.dll 5.1MB
avfilter-4.dll 1.94MB
avfilter-4.dll 1.94MB
avdevice-55.dll 1.28MB
avdevice-55.dll 1.28MB
swscale-2.dll 424KB
swscale-2.dll 424KB
avutil-52.dll 409KB
avutil-52.dll 409KB
SDL.dll 297KB
SDL.dll 297KB
swresample-0.dll 270KB
swresample-0.dll 270KB
postproc-52.dll 119KB
postproc-52.dll 119KB
simplest_ffmpeg_player_su.vcxproj.filters 1KB
simplest_ffmpeg_player.vcxproj.filters 1KB
cuc_ieschool.flv 912KB
cuc_ieschool.flv 912KB
SDL_opengl.h 329KB
SDL_opengl.h 329KB
avcodec.h 171KB
avcodec.h 171KB
avformat.h 97KB
avformat.h 97KB
avfilter.h 56KB
avfilter.h 56KB
SDL_video.h 37KB
SDL_video.h 37KB
opt.h 34KB
opt.h 34KB
pixfmt.h 28KB
pixfmt.h 28KB
frame.h 22KB
frame.h 22KB
avio.h 18KB
avio.h 18KB
intreadwrite.h 18KB
intreadwrite.h 18KB
avdevice.h 16KB
avdevice.h 16KB
SDL_stdinc.h 16KB
SDL_stdinc.h 16KB
old_pix_fmts.h 14KB
old_pix_fmts.h 14KB
mem.h 14KB
mem.h 14KB
common.h 14KB
common.h 14KB
pixdesc.h 13KB
pixdesc.h 13KB
SDL_events.h 13KB
SDL_events.h 13KB
avstring.h 12KB
avstring.h 12KB
swscale.h 12KB
swscale.h 12KB
swresample.h 12KB
swresample.h 12KB
SDL_audio.h 11KB
SDL_audio.h 11KB
old_codec_ids.h 10KB
old_codec_ids.h 10KB
samplefmt.h 10KB
samplefmt.h 10KB
log.h 10KB
log.h 10KB
buffer.h 10KB
buffer.h 10KB
channel_layout.h 9KB
channel_layout.h 9KB
avutil.h 8KB
avutil.h 8KB
_mingw.h 8KB
_mingw.h 8KB
imgutils.h 8KB
imgutils.h 8KB
bprint.h 8KB
bprint.h 8KB
buffersink.h 7KB
buffersink.h 7KB
SDL_keysym.h 7KB
SDL_keysym.h 7KB
parseutils.h 7KB
parseutils.h 7KB
dict.h 6KB
dict.h 6KB
SDL_syswm.h 6KB
SDL_syswm.h 6KB
vdpau.h 6KB
vdpau.h 6KB
xvmc.h 6KB
xvmc.h 6KB
共 315 条
- 1
- 2
- 3
- 4
雷霄骅
- 粉丝: 4w+
- 资源: 141
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
- 5
- 6
前往页