【Android FFMPEG 开发】FFMPEG 读取音视频流中的数据到 AVPacket ( 初始化 AVPacket 数据 | 读取 AVPacket )
文章目录
- I . FFMPEG 获取 AVPacket 数据前置操作
- II . FFMPEG 获取 AVPacket 数据流程
- III . FFMPEG AVPacket 结构体
- IV . AVPacket 数据读取流程
- V . FFMPEG 初始化 AVPacket 数据包 av_packet_alloc ( )
- VI . FFMPEG 读取 AVPacket 数据 av_read_frame ( )
- VII . FFMPEG 获取 AVPacket 数据流程 代码示例
I . FFMPEG 获取 AVPacket 数据前置操作
FFMPEG 获取 AVPacket 数据前置操作 :
① FFMPEG 初始化 : 参考博客 【Android FFMPEG 开发】FFMPEG 初始化 ( 网络初始化 | 打开音视频 | 查找音视频流 )
② FFMPEG 获取 AVStream 音视频流 : 参考博客 【Android FFMPEG 开发】FFMPEG 获取 AVStream 音视频流 ( AVFormatContext 结构体 | 获取音视频流信息 | 获取音视频流个数 | 获取音视频流 )
③ FFMPEG 获取 AVCodec 编解码器 : 参考博客 【Android FFMPEG 开发】FFMPEG 获取编解码器 ( 获取编解码参数 | 查找编解码器 | 获取编解码器上下文 | 设置上下文参数 | 打开编解码器 )
II . FFMPEG 获取 AVPacket 数据流程
FFMPEG 获取 AVPacket 数据流程 :
〇 前置操作 : FFMPEG 环境初始化 , 获取 AVStream 音视频流 , 获取 AVCodec 编解码器 , 然后才能进行下面的操作 ;
① 初始化 AVPacket 空数据包 : av_packet_alloc ( )
AVPacket *avPacket = av_packet_alloc();
② 读取 AVPacket 数据 : av_read_frame ( AVFormatContext *s , AVPacket *pkt )
int read_frame_result = av_read_frame(formatContext, avPacket);
III . FFMPEG AVPacket 结构体
1 . AVPacket 结构体 : 该结构体用于封装被编码压缩的数据 , 不能直接使用 , 需要解码后才能进行音频视频播放 ;
typedef struct AVPacket {...
} AVPacket;
2 . AVPacket 存储数据 : AVPacket 存放编码后的音视频数据的 , 获取该数据包后 , 需要对该数据进行解码 , 解码后将数据存放在 AVFrame 中 ;
3 . 编码前后数据存放 : AVPacket 是编码后的数据 , AVFrame 是编码前的数据 ;
IV . AVPacket 数据读取流程
1 . 读取音视频流数据到 AVPacket 中 : 首先要在外部声明 AVPacket * 结构体指针 , 并为其初始化 , 然后调用 av_read_frame ( ) 方法 , 将已经初始化好内存的 AVPacket * 结构体指针 传给上述方法 , FFMPEG 将在 av_read_frame ( ) 方法中读取数据 , 并存储到堆内存中的 AVPacket 结构体中 ;
2 . AVPacket 的内存初始化和释放 :
① AVPacket 初始化 : 调用 av_packet_alloc ( ) 方法初始化内存 ;
② AVPacket 释放 : 调用 av_packet_free ( ) 释放内存 ;
V . FFMPEG 初始化 AVPacket 数据包 av_packet_alloc ( )
1 . av_packet_alloc ( ) 函数原型 : 在堆内存中为 AVPacket 分配内存 , 并为 AVPacket 结构体各个字段设置默认值 ;
① 返回值 : 返回一个 AVPacket * 结构体指针 , 如果内存分配失败 , 就会返回 NULL ;
/*** Allocate an AVPacket and set its fields to default values. The resulting* struct must be freed using av_packet_free().** @return An AVPacket filled with default values or NULL on failure.** @note this only allocates the AVPacket itself, not the data buffers. Those* must be allocated through other means such as av_new_packet.** @see av_new_packet*/
AVPacket *av_packet_alloc(void);
2 . 代码示例 :
//读取数据包
// AVPacket 存放编码后的音视频数据的 , 获取该数据包后 , 需要对该数据进行解码 , 解码后将数据存放在 AVFrame 中
// AVPacket 是编码后的数据 , AVFrame 是编码前的数据
//创建 AVPacket 空数据包
AVPacket *avPacket = av_packet_alloc();
VI . FFMPEG 读取 AVPacket 数据 av_read_frame ( )
1 . av_read_frame ( ) 函数原型 : 获取音视频流的下一帧数据 ;
① AVFormatContext *s 参数 : 该参数中存储了音视频流格式相关信息 , 该参数是在之前使用 avformat_find_stream_info ( ) 方法获取的 ;
② AVPacket *pkt 参数 : 传入该结构体指针 , 在方法中会按照 AVFormatContext *s 信息读取一帧音视频数据 , 并将该数据存储到 AVPacket 结构体中 ;
③ int 返回值 : 返回 0 代表读取一帧数据 ( 音频 / 视频 ) 成功 , < 0 说明获取数据失败 ;
/*** Return the next frame of a stream.* This function returns what is stored in the file, and does not validate* that what is there are valid frames for the decoder. It will split what is* stored in the file into frames and return one for each call. It will not* omit invalid data between valid frames so as to give the decoder the maximum* information possible for decoding.** If pkt->buf is NULL, then the packet is valid until the next* av_read_frame() or until avformat_close_input(). Otherwise the packet* is valid indefinitely. In both cases the packet must be freed with* av_packet_unref when it is no longer needed. For video, the packet contains* exactly one frame. For audio, it contains an integer number of frames if each* frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames* have a variable size (e.g. MPEG audio), then it contains one frame.** pkt->pts, pkt->dts and pkt->duration are always set to correct* values in AVStream.time_base units (and guessed if the format cannot* provide them). pkt->pts can be AV_NOPTS_VALUE if the video format* has B-frames, so it is better to rely on pkt->dts if you do not* decompress the payload.** @return 0 if OK, < 0 on error or end of file*/
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
2 . FFMPEG 读取 AVPacket 数据 代码示例 :
/*读取数据包 , 并存储到 AVPacket 数据包中参数分析 : 一维指针 与 二维指针 参数分析① 注意 : 第二个参数是 AVPacket * 类型的 , 那么传入 AVPacket *avPacket 变量不能修改 avPacket 指针的指向 , 即该指针指向的结构体不能改变只能修改 avPacket 指向的结构体中的元素的值因此 , 传入的 avPacket 结构体指针必须先进行初始化 , 然后再传入av_read_frame 函数内 , 没有修改 AVPacket *avPacket 的值 , 但是修改了结构体中元素的值② 与此相对应的是 avformat_open_input 方法 , 传入 AVFormatContext ** 二维指针传入的的 AVFormatContext ** 是没有经过初始化的 , 连内存都没有分配在 avformat_open_input 方法中创建并初始化 AVFormatContext * 结构体指针然后将该指针地址赋值给 AVFormatContext **avformat_open_input 函数内修改了 AVFormatContext ** 参数的值返回值 0 说明读取成功 , 小于 0 说明读取失败 , 或者 读取完毕*/
int read_frame_result = av_read_frame(formatContext, avPacket);
VII . FFMPEG 获取 AVPacket 数据流程 代码示例
//读取数据包
// AVPacket 存放编码后的音视频数据的 , 获取该数据包后 , 需要对该数据进行解码 , 解码后将数据存放在 AVFrame 中
// AVPacket 是编码后的数据 , AVFrame 是编码前的数据
//创建 AVPacket 空数据包
AVPacket *avPacket = av_packet_alloc();
/*读取数据包 , 并存储到 AVPacket 数据包中参数分析 : 一维指针 与 二维指针 参数分析① 注意 : 第二个参数是 AVPacket * 类型的 , 那么传入 AVPacket *avPacket 变量不能修改 avPacket 指针的指向 , 即该指针指向的结构体不能改变只能修改 avPacket 指向的结构体中的元素的值因此 , 传入的 avPacket 结构体指针必须先进行初始化 , 然后再传入av_read_frame 函数内 , 没有修改 AVPacket *avPacket 的值 , 但是修改了结构体中元素的值② 与此相对应的是 avformat_open_input 方法 , 传入 AVFormatContext ** 二维指针传入的的 AVFormatContext ** 是没有经过初始化的 , 连内存都没有分配在 avformat_open_input 方法中创建并初始化 AVFormatContext * 结构体指针然后将该指针地址赋值给 AVFormatContext **avformat_open_input 函数内修改了 AVFormatContext ** 参数的值返回值 0 说明读取成功 , 小于 0 说明读取失败 , 或者 读取完毕*/
int read_frame_result = av_read_frame(formatContext, avPacket);
【Android FFMPEG 开发】FFMPEG 读取音视频流中的数据到 AVPacket ( 初始化 AVPacket 数据 | 读取 AVPacket )相关推荐
- 【Android NDK 开发】NDK 交叉编译 ( Ubuntu 中交叉编译动态库 | Android Studio 中配置使用第三方动态库 )
文章目录 I . 动态库 与 静态库 II . 编译动态库 III. Android Studio 使用第三方动态库 IV . Android Studio 关键代码 V . 博客资源 I . 动态库 ...
- Android内核开发:在源码树中添加新的app应用
本文是<Android内核开发>系列的第十二篇文章,上一篇文章介绍了如何从源码中删除出厂的app应用,本文则在此基础上,详细介绍一下如何在Android内核源码树中添加一个新的app应用. ...
- 【ANDROID游戏开发之六】在SURFACEVIEW中添加系统控件,并且相互交互数据!
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/306.html - ...
- Android内核开发:从源码树中删除出厂的app应用
本文是<Android内核开发>系列的第十一篇文章,本文重点介绍如何从Android源码中删除出厂的app应用. 上一篇文章中提到过,系统出厂的app应用,其实就是被安装到/system分 ...
- 【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!
李华明Himi 原创,转载务必在明显处注明: 转载自 [黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/306.html 很多童鞋说 ...
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
本文为<Android/OPhone开发完全讲义>一书的内容连载.转载请注明出处 我们知道SharedPreferences只能保存简单类型的数据,例如,String.int等.如果想用S ...
- Android商城开发系列(六)——使用 OkHttpUtils 请求网络 + 使用 fastjson解析数据...
OkHttp是Google推荐使用的一个开源的网络请求框架,Android开发中涉及到网络请求和接口调用现在大部分都是使用OkHttp,网上已经有不少人针对OkHttp进行了封装,这里推荐一下鸿洋大神 ...
- android 软件开发 小米 魅族 htc 测试中的问题,iOS和Android-农行手机银行常见问题解决方法-K宝篇...
如果K宝不能正常使用,您就来对地方喽!!! 1.第一次使用K宝请充电3小时!充电后,才能保证电池寿命啊! 2.第一次不知如何下载?参考下面内容: iOS系统 登陆App Store,搜索 " ...
- 【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 )
文章目录 I . 创建 NDK 项目 II . NDK 项目 相关配置 III . NDK 中获取 Android 版本号 IV . 使用 __system_property_get 可获取的参数 I ...
最新文章
- Python+OpenCV 图像处理系列(9)—— 图像的翻转和缩放插值
- 基于Pytorch的动态卷积复现
- Metasploit发布了新版本5.0.83
- 计算机视觉之一:特征检测
- 服务拆分-案例Demo
- 创建一个带副本机制的topic
- java xfire webservice 异步_[Java教程]Java中使用webservice,简化开发(xfire的webservice)...
- 【收集】11款Linux数据恢复工具
- 倒计时1天,BDTC2016最新完整版日程公布
- 简述MapReduce执行过程?
- MacOS下载钉钉直播回放经验总结
- java匹配机制_Java Spring:需要通配符@RequestMapping来匹配所有BUT / images / *以及对原始URL的访问权限...
- android studio中如何替换gradle以防下载卡住
- [转载] python3 安装完Pycurl在import pycurl时报错
- [GPS模块]NEMA-0183(GPRMC GPGGA)数据格式详细解释
- 把编程当小葵花妈妈课堂
- swapidc不能连接到主机_kangle easypanel对接SWAP IDC虚拟主机销售平台完整教程 (linux)...
- 子线程与主线程之间的通信
- CAD文件怎么转成图片?手机也能轻松解决
- 小技巧,IDEA 卡住不动解决办法