实战FFmpeg + OpenGLES--iOS平台上视频解码和播放
一个星期的努力终于搞定了视频的播放,利用FFmpeg解码视频,将解码的数据通过OpenGLES渲染播放。搞清楚了自己想知道的和完成了自己的学习计划,有点小兴奋。明天就是“五一”,放假三天,更开心啦。
本文实现视频文件的播放是在自己之前写的文章实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 、 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片 的基础上改进合成来完成的。不多种解释,直接上代码,清晰明了。
NSString *path = [[NSBundle mainBundle] pathForResource:@"nwn" ofType:@"mp4"];
const char *filepath= [path UTF8String]; av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=){
printf("Couldn't open input stream.\n");
exit();
} /*
* av_find_stream_info():ffmpeg版本更新后没有这个函数了,用avformat_find_stream_info这个函数,可以自己看一下版本更新改动
*/
// if(av_find_stream_info(pFormatCtx)<0)
if(avformat_find_stream_info(pFormatCtx, NULL) < )
{
printf("Couldn't find stream information.\n");
exit();
} videoindex=-;
for(int i=; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoindex=i;
break;
}
if(videoindex==-)
{
printf("Didn't find a video stream.\n");
exit();
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
printf("Codec not found.\n");
exit();
}
/*
* avcodec_open():ffmpeg版本更新后没有这个函数了,用avformat_find_stream_info这个函数,可以自己看一下版本更新改动
* avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
*/
// if(avcodec_open(pCodecCtx, pCodec)<0)
if(avcodec_open2(pCodecCtx, pCodec, NULL)<)
{
printf("Could not open codec.\n");
exit();
}
AVFrame *pFrame,*pFrameYUV;
pFrame=avcodec_alloc_frame();
pFrameYUV=avcodec_alloc_frame();
uint8_t *out_buffer;
out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)];
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); int ret, got_picture;
int y_size = pCodecCtx->width * pCodecCtx->height; AVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));
av_new_packet(packet, y_size); printf("video infomation:\n");
av_dump_format(pFormatCtx,,filepath,); while(av_read_frame(pFormatCtx, packet)>=)
{
if(packet->stream_index==videoindex)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < )
{
printf("Decode Error.\n");
exit();
}
if(got_picture)
{
char *buf = (char *)malloc(pFrame->width * pFrame->height * / ); AVPicture *pict;
int w, h;
char *y, *u, *v;
pict = (AVPicture *)pFrame;//这里的frame就是解码出来的AVFrame
w = pFrame->width;
h = pFrame->height;
y = buf;
u = y + w * h;
v = u + w * h / ; for (int i=; i<h; i++)
memcpy(y + w * i, pict->data[] + pict->linesize[] * i, w);
for (int i=; i<h/; i++)
memcpy(u + w / * i, pict->data[] + pict->linesize[] * i, w / );
for (int i=; i<h/; i++)
memcpy(v + w / * i, pict->data[] + pict->linesize[] * i, w / ); [myview setVideoSize:pFrame->width height:pFrame->height];
[myview displayYUV420pData:buf width:pFrame->width height:pFrame->height]; //利用OpenGLES渲染YUV
free(buf);
}
}
av_free_packet(packet);
}
delete[] out_buffer;
av_free(pFrameYUV);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
本周的学习任务完成啦,写完这篇博客就下班回家,哈哈。五一长假,我要休息下,列出自己下一步的学习计划。下周我想做的是本地音频文件解码播放,以及本地视频文件中音频与视频同步播放。现在所做的都是本地音视频文件的处理,因为本地文件处理起来方便一些,这也让自己学起来也快速一些。关于网络音视频实时流的同步与播放,这个涉及的内容就要复杂一些了,有效学习+时间规划,我肯定能玩透播放器的开发。
本文完整工程 FFmpegDecode_OpenGLESRenderYUV 的下载地址为:http://pan.baidu.com/s/1dDvpECh
实战FFmpeg + OpenGLES--iOS平台上视频解码和播放的更多相关文章
- 使用Vitamio开发iOS平台上的万能播放器
迅速了解 Vitamio是干什么的?看官方怎么说: "Vitamio SDK for iOS是Yixia Ltd官方推出的 iOS 平台上使用的软件开发工具包(SDK),为iOS开发人员提供 ...
- iOS 平台上常见的安装包有三种,deb、ipa 和 pxl
前言:目前 iOS 平台上常见的安装包有三种,deb.ipa 和 pxl. 其中 deb 格式是 Debian 系统(包含 Debian 和 Ubuntu )专属安装包格式,配合 APT 软件管理系统 ...
- 实战AudioToolbox--在iOS平台上播放音频
上午看了关于AudioToolbox.framework相关的资料,结合网上的资料对AudioToolbox的基本使用有了整体上的认识,上一篇文章 笔谈AudioToolbox(一) 中提到使用Aud ...
- unity 在安卓个IOS平台上 同一个按钮 点击后实现不同的功能
#if UNITY_IOS UIEventListener.Get(mSprites["Recharge"].gameObject).onClick = OnIOSRecharge ...
- mui搜索框在ios平台上点击多次才弹出键盘的解决方法
今天使用Hbuilder调试手机端时,发现搜索框在安卓系统下,点击一次就可以弹出键盘 但是在iso下非常的不规律,要点击多次 代码实现如下: <div class="mui-input ...
- 实战FFmpeg--编译iOS平台使用的FFmpeg库(支持arm64的FFmpeg2.6.2)
编译环境:Mac OS X 10.10.2 ,Xcode 6.3 iOS SDK 8.3 FFmpeg库的下载地址是 http://www.ffmpeg.org/releases/ . ...
- iOS平台在ffmpeg中使用librtmp
转载请注明出处:http://www.cnblogs.com/fpzeng/p/3202344.html 系统版本:OS X 10.8 一.在iOS平台上交叉编译librtmp librtmp lin ...
- (译)cocos2d-x跨android&ios平台开发入门教程
免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...
- U3D中IOS平台泛型方法尽少使用
U3D的IOS最小运行库use micro mscorlib是不包含泛型反射方法的,如FieldType.GetGenericArguments方法.所以尽量少用List而直接使用array. 另外请 ...
随机推荐
- 【Eclipse】Eclipse如何导出java项目为jar包
1.首先确定要导出的项目 从项目结构可以看出,笔者的项目是一个Dynamic Java Project.com/db下面有一个config的数据库配置文件.WEB-INF/lib文件夹下面有依赖的ja ...
- 关于Android Studio3.2新建项目无法运行出现Failed to find Build Tools revision 28.0.3的解决方法
关于Android Studio3.2新建项目无法运行出现Failed to find Build Tools revision 28.0.3的解决方法 https://blog.csdn.net/h ...
- Spark连续特征转化成离散特征
当数据量很大的时候,分类任务通常使用[离散特征+LR]集成[连续特征+xgboost],如果把连续特征加入到LR.决策树中,容易造成overfit. 如果想用上连续型特征,使用集成学习集成多种算法是一 ...
- java多线程(六)线程控制类
1. 多线程控制类 为了保证多线程的三个特性,Java引入了很多线程控制机制,下面介绍其中常用的几种: l ThreadLocal l 原子类 l Lock类 l Volatile关键字 ...
- Superset配置impala数据源
1.安装impyla pip install impyla 2.在superset页面配置如下,此时impala是有kerberos认证的 impala://xxxx:xx/default?auth_ ...
- javafx这些学会后,开发就不难了,往tablecloumn列中添加按钮,修改javafx中tableview中tablecell中的值,修改完回车表示保存到内存中
javafx开发过程中遇见难题,往tablecloumn列中添加按钮 想了很久的方法,也配有办法判断每行中有数据的地方添加按钮set bank_caozuo.setCellFactory((col)- ...
- 深入Nginx之《HTTP请求报文与HTTP响应报文》
HTTP请求报文 这个很有必要了解,好歹我们得知道Nginx在提供HTTP服务时,客户端都会传些什么.HTTP请求中客户端传送的内容称为HTTP请求报文. 1.请求行包含: 请求方法,请求URL,HT ...
- mysql数据库每天备份
以备份mysql下的test数据库为例,备份到/home/data 使用mysqldunp命令 dump.sh mysqldump -h127. -uadmin -P3306 -ppassword t ...
- 基于zynq 7020的串口UART中断实验
1.参考 UG585,P1790[JokerのZYNQ7020]UART学会Zynq(27)UART中断驱动模式示例 2.理论知识 在ZYNQ的中断中有一个IOP的中断集,它包几个外设的中断,其中包含 ...
- (CSDN 迁移) JAVA循环删除List的某个元素
若列表中只可能存在一个则可以用简单的循环删除,不多说. 若列表中可能存在多个,尤其是可能有多个连续的需要删除,用简单循环有可能发生异常. 需要使用迭代器(Iterator),两种具体实现: 逻辑上是一 ...