您当前的位置: 首页 >  音视频

命运之手

暂无认证

  • 1浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android音视频开发】【021】ffmpeg实现视频解码播放

命运之手 发布时间:2021-07-20 21:37:07 ,浏览量:1

项目简介

写这个项目的初衷,是为了给初学NDK和FFMPEG的人提供一个完善的模版项目

除了实现ffmpeg解码在线视频,ndk直接绘制SurfaceView,OpenSL播放音频等基本功能

还封装了很多常用的NDK功能,设计了很完善的播放器控制机制

暂停,恢复,播放,停止,销毁,视频源切换,横竖屏切换,所有功能快速乱点也不会有问题

花了很大精力把这个项目做完善,就是为了让大家能学到更多细节上的东西

以后在NDK开发的路上就能少走弯路

通过这个项目,大家可以学习到以下知识

C++和NDK知识

CMakeLists脚本的使用

NDK同时编译多种指令集的so库

C++语法巩固

JNI集成Logcat

JNI中的线程切换和方法回调

iostream打印到Logcat

线程等待,互斥锁,条件锁,队列的组合使用

音视频知识

音视频基本原理

FFmpeg视频API的使用

OpenSL音频API的使用

音视频同步

通过ANativeWindow实现视频渲染

实现帧数据回调

业务方案

播放器功能的设计和实现

暂停、恢复、横竖屏切换等细节的高效实现方案

用户频繁操作时,如何解决高并发问题,保证操作的有序性

FFMPEG解码播放原理

代码较多,先帮大家把核心思路给提取出来了

对于对C++和NDK还不是很熟的新手,建议一行行阅读代码和博客

因为真的能学到很多比较细的东西,少走弯路,代码注释也非常全

FFMpeg::prepare 修改标志位为准备中(在复杂情况下,标志位的控制也是一种哲学,设计得好,通过标志位就能避免很多并发问题) 通过avformat_alloc_context创建格式上下文AVFormatContext 通过avformat_open_input打开url,打开成功后,AVFormatContext中会记录格式信息 通过avformat_find_stream_info查找媒体流信息,获得AVStream[] 遍历stream,获得每个stream的解码参数AVCodecParameters 通过avcodec_find_decoder,找到AVCodecParameters对应的解码器AVCodec 通过avcodec_alloc_context3创建解码上下文AVCodecContext 通过avcodec_parameters_to_context,将解码参数设置给AVCodecContext 通过avcodec_open2打开解码上下文 通过AVCodecParameters和AVCodecContext,判断stream格式是否正确 通过AVStream和AVCodecContext,创建AudioChannel和VideoChannel AudioChannel和VideoChannel分别创建decode和play线程,一个用于将AVPacket解码为AVFrame,一个用于播放AVFrame ffmpeg创建read线程,通过av_read_frame,不断从AVCodecContext中读取AVPacket,再交给channel去decode和play channel通过avcodec_send_packet将读取到的AVPacket交给AvCodecContext解码 channel通过avcodec_receive_frame从AvCodecContext获取到解码后的AVFrame VideoChannel通过SwsContext将AVFrame转化为ARGB图像,交给ANativeWindow/Surface进行渲染 AudioChannel通过SwrContext将AVFrame重采样为PCM数据,交给OpenSL进行播放 read、decode、play线程都根据ffmpeg.playing这个标志位来决定是否继续工作,初始化值为false,即只创建线程,不立刻工作 修改标志位为已准备

FFMpeg::resume 将ffmpeg.playing字段设置为true,read、decode、play线程开始工作

FFMpeg::pause 将ffmpeg.playing字段设置为false,read、decode、play线程暂停工作

FFMpeg::release 修改标志位为释放中 通过pthread_join等待ffmpeg.read线程结束 通过avformat_close_input关闭并释放AVFormatContext 通过pthread_join等待channel.decode和channel.play线程结束 通过avcodec_close关闭并释放AVCodecContext 关闭并释channel中的数据队列,再释放channel 修改标志位为已释放

源码下载

ffmpeg-MediaPlayer.zip

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0397s