简单播放器(增加sdl事件控制)
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <time.h> #define SFM_REFRESH_EVENT (SDL_USEREVENT + 1) int thread_exit=;
//Thread
int sfp_refresh_thread(void *opaque)
{
SDL_Event event;
while (thread_exit==) {
event.type = SFM_REFRESH_EVENT;
SDL_PushEvent(&event);
//Wait 40 ms
SDL_Delay();
}
return ;
} int main(int argc, char* argv[])
{
AVFormatContext *pFormatCtx;//格式上下文结构体
int i, videoindex;
AVCodecContext *pCodecCtx;//codec上下文
AVCodec *pCodec;//codec int screen_w=,screen_h=;
SDL_Window *screen;
SDL_Renderer* sdlRenderer;
SDL_Texture* sdlTexture;
SDL_Rect sdlRect;
SDL_Thread *video_tid;
SDL_Event event; av_register_all();//ffmpeg flow 0,注册codec
avformat_network_init();//如要打开网络流,必须运行此函数
pFormatCtx = avformat_alloc_context();//格式上下文结构体指针开空间
if(avformat_open_input(&pFormatCtx, argv[], NULL, NULL) != )//打开多媒体文件
{
printf("open file error\n");
return -;
} AVDictionary* pOptions = NULL;
if ( avformat_find_stream_info(pFormatCtx, &pOptions) < )//读取音视频数据相关信息,参数0:上下文结构体指针,参数1:option
{
return -;
}
av_dump_format(pFormatCtx, , argv[], );//调试函数,输出文件的音、视频流的基本信息 //获取视频的时长
if(pFormatCtx->duration != AV_NOPTS_VALUE)
{
int hours, mins, secs, us;
int64_t duration = pFormatCtx->duration + ;
secs = duration / AV_TIME_BASE;
us = duration % AV_TIME_BASE;
mins = secs / ;
secs %= ;
hours = mins/ ;
mins %= ;
printf("%02d:%02d:%02d.%02d\n", hours, mins, secs, ( * us) / AV_TIME_BASE);
} i = ;
int videostream = -;
printf("pFormatCtx->nb_streams=%d\n", pFormatCtx->nb_streams);
for(i=;i<pFormatCtx->nb_streams;i++)//遍历多媒体文件中的每一个流,判断是否为视频。
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videostream = i;
break;
}
}
printf("videostream=%d\n", videostream); if (- == videostream)
{
printf("error no video stream\n");
return;
} pCodecCtx = pFormatCtx->streams[videostream]->codec;//codec上下文指定到格式上下文中的codec pCodec = avcodec_find_decoder( pCodecCtx->codec_id );//找到一个codec,必须先调用av_register_all() if(NULL == pCodec)
{
printf("couldn't find the decode\n");
return -;
} if( avcodec_open2(pCodecCtx, pCodec, NULL) < )//初始化一个视音频编解码器的AVCodecContext
{
printf("open decode error\n");
return -;
} AVFrame *pFrame,*pFrameYUV;//Frame结构体
pFrame = av_frame_alloc();//原始帧
pFrameYUV = av_frame_alloc();//YUV帧
uint8_t *out_buffer; int num = avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
printf("num=%d\n", num); out_buffer = (uint8_t *)av_malloc(num*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);//将pFrameYUV和out_buffer联系起来(pFrame指向一段内存) AVPacket packet;//packet结构体
int ret = -;
i = ;
struct SwsContext *img_convert_ctx = NULL;//图像格式转化上下文
img_convert_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt , pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);//初始化SWS,图片格式转化上下文 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
{
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -;
} screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
//SDL 2.0 Support for multiple windows
screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h,
SDL_WINDOW_OPENGL); if(!screen)
{
printf("SDL: could not create window - exiting:%s\n",SDL_GetError());
return -;
} sdlRenderer = SDL_CreateRenderer(screen, -, );
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);
sdlRect.x=;
sdlRect.y=;
sdlRect.w=screen_w;
sdlRect.h=screen_h; int f1 = ;
int f2 = ;
int got_picture = -; video_tid = SDL_CreateThread(sfp_refresh_thread,NULL,NULL);
time_t t;
time(&t);
printf("begin :%s\n", ctime(&t)); while ()
{
SDL_WaitEvent(&event);
if(event.type==SFM_REFRESH_EVENT)
{
if(av_read_frame(pFormatCtx, &packet)>=)//读取码流中的音频若干帧或者视频一帧,作为packet
{
f1++;
if(packet.stream_index == videostream)//如果是视频
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);//解码一帧视频数据。输入一个压缩编码的结构体AVPacket,输出一个解码后的结构体AVFrame if(ret < )
{
printf("decode error\n");
return -;
} if(got_picture)
{
//转换
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize,
, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);//将输出结果转化成YUV SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
pFrameYUV->data[], pFrameYUV->linesize[],
pFrameYUV->data[], pFrameYUV->linesize[],
pFrameYUV->data[], pFrameYUV->linesize[]); SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer ); //SDL_Delay(40); f2++; }
} av_free_packet(&packet);
}
else
{
thread_exit=;
break;
}
} } time(&t);
printf("begin :%s\n", ctime(&t)); SDL_Quit(); sws_freeContext(img_convert_ctx); free(out_buffer);
av_free(pFrameYUV); // Free the YUV frame
av_free(pFrame); // Close the codec
avcodec_close(pCodecCtx); // Close the video file
avformat_close_input(&pFormatCtx); printf("f1=%d\n", f1);
printf("f2=%d\n", f2); return ;
}
简单播放器(增加sdl事件控制)的更多相关文章
- Android应用--简、美音乐播放器增加音量控制
Android应用--简.美音乐播放器增加音量控制 2013年6月26日简.美音乐播放器继续完善中.. 题外话:上一篇博客是在6月11号发的,那篇博客似乎有点问题,可能是因为代码结构有点乱的原因,很难 ...
- 腾讯X5内核使用详解(X5内核播放器使用如何去除控制栏全屏播放)以及一些注意事项
例子下载地址 https://www.lanzous.com/i2zsv5g GIT就不用了麻烦的不行 本人安卓刚学 就上X5内核弄了老长时间由于对maven 和idea不熟悉刚开始导包都是 ...
- FFmpeg入门,简单播放器
一个偶然的机缘,好像要做直播相关的项目 为了筹备,前期做一些只是储备,于是开始学习ffmpeg 这是学习的第一课 做一个简单的播放器,播放视频画面帧 思路是,将视频文件解码,得到帧,然后使用定时器,1 ...
- 基于libvlc和wxWidgets的简单播放器代码阅读
源代码来自 http://git.videolan.org/?p=vlc.git;a=blob_plain;f=doc/libvlc/wx_player.cpp // g++ wx_player.cp ...
- ffmpeg学习(三)——ffmpeg+SDL2 实现简单播放器
本篇实现基于ffmpeg动态库用测试程序播放本地文件和RTSP视频流. 参考文章:http://blog.csdn.net/leixiaohua1020/article/details/8652605 ...
- 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- 【转】100行代码实现最简单的基于FFMPEG+SDL的视频播放器
FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我把自己做项目过程中实现的一个非常简单的视频播放器 ...
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
随机推荐
- java8 学习系列--NIO学习笔记
近期有点时间,决定学习下java8相关的内容: 当然了不止java8中新增的功能点,整个JDK都需要自己研究的,不过这是个漫长的过程吧,以自己的惰性来看: 不过开发中不是有时候讲究模块化开发么,那么我 ...
- lua拾遗之lua中冒号(:)与点号(.)的区别和来由
参考资料 1.https://my.oschina.net/lonewolf/blog/173065 其结论为: 1.定义的时候:Class:test()与 Class.test(self)是等价的, ...
- goim socket丢包粘包问题解决。
-(NSInteger)bytesToInt:(unsigned char*) data { return (data[3]&255)|(data[2]&255)<<8|( ...
- C正则库做DNS域名验证时的性能对比
C正则库做DNS域名验证时的性能对比 本文对C的正则库regex和pcre在做域名验证的场景下做评测. 验证DNS域名的正则表达式为: "^[0-9a-zA-Z_-]+(\\.[0-9a ...
- TP框架主要文件夹注释
TP框架主要文件夹注释 common -> 函数库目录 conf -> 配置文件目录lang -> 语言包librang -> 核心资源库 behacior -> 行为目 ...
- Windows下通过socket进行字符串和文件传输
今天在windows平台下,通过socket实现了简单的文件传输.通过实现这一功能,了解基本的windows网络编程和相关函数的使用方法. 在windows平台上进行网络编程,首先都需要调用函数WSA ...
- 浅谈php中使用websocket
在PHP中,开发者需要考虑的东西比较多,从socket的连接.建立.绑定.监听等都需要开发者自己去操作完成,对于初学者来说,难度方面也挺大的,所以本文的思路如下: 1.socket协议的简介 2.介绍 ...
- python学习笔记系列----(八)python常用的标准库
终于学到了python手册的最后一部分:常用标准库.这部分内容主要就是介绍了一些基础的常用的基础库,可以大概了解下,在以后真正使用的时候也能想起来再拿出来用. 8.1 操作系统接口模块:OS OS模块 ...
- Git/GitHub 初用体验与总结
Git,一个神奇而又陌生的东西,居然到现在才去了解它,就像有一位仁兄说的,现在不会用Git真的都不好意思说自己搞IT的. 简单的讲,这Git是目前最先进的分布式版本控制系统,和他相对应的就是众所周知的 ...
- Hdu 4681 2013 Multi-University Training Contest 8 String
带跨越式的LCS,同样是在朴素的LCS上加入一种跨越一段的转移,这样我们要预处理出跨越一段给定串的转移函数. 这个题同样可以正反两边LCS做 呆马: #include <iostream> ...