文章目录

  • 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 )相关推荐

  1. 【Android NDK 开发】NDK 交叉编译 ( Ubuntu 中交叉编译动态库 | Android Studio 中配置使用第三方动态库 )

    文章目录 I . 动态库 与 静态库 II . 编译动态库 III. Android Studio 使用第三方动态库 IV . Android Studio 关键代码 V . 博客资源 I . 动态库 ...

  2. Android内核开发:在源码树中添加新的app应用

    本文是<Android内核开发>系列的第十二篇文章,上一篇文章介绍了如何从源码中删除出厂的app应用,本文则在此基础上,详细介绍一下如何在Android内核源码树中添加一个新的app应用. ...

  3. 【ANDROID游戏开发之六】在SURFACEVIEW中添加系统控件,并且相互交互数据!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/306.html - ...

  4. Android内核开发:从源码树中删除出厂的app应用

    本文是<Android内核开发>系列的第十一篇文章,本文重点介绍如何从Android源码中删除出厂的app应用. 上一篇文章中提到过,系统出厂的app应用,其实就是被安装到/system分 ...

  5. 【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!

     李华明Himi 原创,转载务必在明显处注明: 转载自 [黑米GameDev街区] 原文链接:  http://www.himigame.com/android-game/306.html 很多童鞋说 ...

  6. 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据

    本文为<Android/OPhone开发完全讲义>一书的内容连载.转载请注明出处 我们知道SharedPreferences只能保存简单类型的数据,例如,String.int等.如果想用S ...

  7. Android商城开发系列(六)——使用 OkHttpUtils 请求网络 + 使用 fastjson解析数据...

    OkHttp是Google推荐使用的一个开源的网络请求框架,Android开发中涉及到网络请求和接口调用现在大部分都是使用OkHttp,网上已经有不少人针对OkHttp进行了封装,这里推荐一下鸿洋大神 ...

  8. android 软件开发 小米 魅族 htc 测试中的问题,iOS和Android-农行手机银行常见问题解决方法-K宝篇...

    如果K宝不能正常使用,您就来对地方喽!!! 1.第一次使用K宝请充电3小时!充电后,才能保证电池寿命啊! 2.第一次不知如何下载?参考下面内容: iOS系统 登陆App Store,搜索 " ...

  9. 【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 )

    文章目录 I . 创建 NDK 项目 II . NDK 项目 相关配置 III . NDK 中获取 Android 版本号 IV . 使用 __system_property_get 可获取的参数 I ...

最新文章

  1. Python+OpenCV 图像处理系列(9)—— 图像的翻转和缩放插值
  2. 基于Pytorch的动态卷积复现
  3. Metasploit发布了新版本5.0.83
  4. 计算机视觉之一:特征检测
  5. 服务拆分-案例Demo
  6. 创建一个带副本机制的topic
  7. java xfire webservice 异步_[Java教程]Java中使用webservice,简化开发(xfire的webservice)...
  8. 【收集】11款Linux数据恢复工具
  9. 倒计时1天,BDTC2016最新完整版日程公布
  10. 简述MapReduce执行过程?
  11. MacOS下载钉钉直播回放经验总结
  12. java匹配机制_Java Spring:需要通配符@RequestMapping来匹配所有BUT / images / *以及对原始URL的访问权限...
  13. android studio中如何替换gradle以防下载卡住
  14. [转载] python3 安装完Pycurl在import pycurl时报错
  15. [GPS模块]NEMA-0183(GPRMC GPGGA)数据格式详细解释
  16. 把编程当小葵花妈妈课堂
  17. swapidc不能连接到主机_kangle easypanel对接SWAP IDC虚拟主机销售平台完整教程 (linux)...
  18. 子线程与主线程之间的通信
  19. CAD文件怎么转成图片?手机也能轻松解决
  20. 小技巧,IDEA 卡住不动解决办法

热门文章

  1. 防火墙术语详解(一)
  2. 人的一生,有三件事情不能等
  3. 对于python 3.x与python2.x中新型类的继承特性总结
  4. Django REST framework快速入门
  5. 20155227《网络对抗》Exp5 MSF基础应用
  6. UIPageControl
  7. 怎样使用SetTimer MFC 够具体
  8. 高维、相依和不完全数据的统计分析(二)
  9. linux kernel 2.6.36 编译升级
  10. 算法学习:AC自动机