今天到月末了,才发我这个月的第一篇文章,因为这个月前三周一直在看ffmpeg的libavcodec和libavformat两个库源码。实验室要做一个“小传大”的软件,就是android手机或平板电脑的屏幕包括操作等全映射到电脑或电视上去。这个首先想到的就是用TS串流来做,一来是符合标准规范,音视频同步方便;二来是接收端非常简单,普通能播放网络串流的播放器都可以胜任,大大降低开发难度。于是我就开始看ffmpeg的libav库,如下是我的小体会。

ffmpeg库的框架非常漂亮,接口函数在几个主要的头文件中,如avformat.h,avcodec.h等,内部静态函数虽然调用层次非常纷繁复杂,但是命名规范,层次也非常清晰,看起来只要自己不乱,那是非常爽的,这个必须赞一下先哈。如果只是编解码的话,只要调用avcodec.h里面的接口函数就足够了,关于编码有两个结构体,AVCodecContext和AVCodec。AVCodecContext结构体里面的成员是编解码器的一些参数,codec_type,codec_id,width,height,bit_rate,time_base,pix_fmt这些,其中前两个在avcodec_alloc_context3(codec)函数初始化的时候自动赋值,其实也就是用的其参数AVCodec *codec里面设置的值;后面的几个参数要用户自己赋值。AVCodec结构体是由函数avcodec_find_encode(CODEC_ID)来初始化的,这一步通过用户传入的参数CODEC_ID,比如AV_CODEC_ID_MJPEG,不仅把type和id赋了值(这俩就是在AVCodecContext初始化时传入的值),而且把encode等这些函数指针也都赋了值,指向了相应的编解码函数。当做完两个结构体的初始化后,就可以编码了。但是yuv文件和编完码后的码流存在哪里?这就用到ffmpeg的AVFrame和AVPacket两个结构体。有时候也可以用AVPicture来存yuv裸数据,毕竟AVPicture只是AVFrame的子集,我就一直用AVFrame了。AVFrame结构体里面除了width和height以及linesize后,就是一个8个元素的指针数组:data[8],我不知道为啥要给8个,即使是BGRA格式也只用4个哈,这就不管了,现在用YUV420P只占用3个,即data[0]->Y,data[1]->U,data[2]->V。好了,初始化工作完成后,调用avcodec_encode_video2函数就妥了,然后直接从AVPacket结构体里取编成你设置好的格式的码流就行了。

关键要说的不是上面的这些,因为我3个星期才看出这点玩意就太山寨了。我要把yuv编成ts流,当初不知道,直接上面的步骤只是把CODEC_ID设为AV_CODEC_ID_MPEG2TS,结果各种报错,当时我世界观就踏了,到处发贴问,但都石沉大海,木有人回应,不知道是大家都不做TS流编码还是怎么着。当我再回过头仔细看源码并且看TS的标准18030之后,才发现是怎么一回事。TS流就是个容器,可以包mpeg2或h264等ES流,所以如果要编码TS流就要经过两步,第一步是编码成mpeg2或h264,第二步封装成TS流,后者就是libavformat要干的事儿,这就引出了下面的结构体:AVFormatContext,AVOutputFormat和AVStream。AVFormatContext结构体是标准的始祖,太全了,包罗万象,用avformat_alloc_context()初始化,捎带把AVOutputFormat也初始化了,这个结构体里面的write_header,write_packet,interleave_packet这些函数太重要了,但也就是这里出现了大的问题,我后面说明。AVStream结构体就是保存各种流,如果有音频和视频那么就是两个流。

方是时,正当我高兴的以为做出来了的时候,才发现,av_interleaved_write_frame()函数里一个参数是AVIOContext,就是这个结构体太坑了,给TA初始化的时候要添加文件名,也就是说必须是硬盘上的文件才可以,而我要把yuv做成TS流的目的就是要实时打成RTP包发出去,TA让我先存到硬盘上,再从硬盘上读取到内存中打包发送是怎么个意思??还怎么实时性?!我第一个想到的就是直接从AVIOContext结构体里面把那个指向编玩码的流指针找出来,这样就可以解决,但是又当我欣喜的时候,我才发现,这个AVIOContext里面的buffer指针指向的根本就不是封装好的TS流!!!我再一次进去扒代码,才发现,经过了层层的函数调用后,TA的过程我描述如下:

编好的mpeg2或h264 ES流文件存在AVPacket *pkt中,pkt作为输入传入av_interleaved_write_frame()函数,在里面新实例了一个AVPacket *opkt的局部结构体,当调用mpegts_write_packet_internal()函数的时候,输入参数已经是opkt了,写上TS的头,写上opkt的部分长数据,写入文件,free掉buf指针,再写上TS body的数据,再写入部分opkt数据,写入文件,free掉buf指针,。。。不断循环操作,直到写完为止。这样,这个局部TS流文件指针就压根没有!!如果改库的话在AVIOContext结构体里面新建一个TS流指针,把上面的文件操作全部赋给这个指针,我最后也是可以得到的,但是改库的代价和不可预期的错误太大,我稚嫩的肩膀不能hold住。。。。但临近月末,啥都做不出来太没有工作量了,于是我换了一种简单的思路先凑和解决了,就是yuv编码成jpg然后直接udp传,接收端我用QT写了个界面,实时把接到的图片显示出来。虽然做出来了,但是以后音视频同步还是个问题,我还是认为应该用TS流来做,但具体怎么做我要歇几天以后靠灵感了~也期待大家给点灵感~~:-)

转载请注明: 转自http://blog.csdn.net/littlethunder/article/details/9164929

转载于:https://www.cnblogs.com/jiangu66/p/3155485.html

ffmpeg利用libav库把yuv视频流转换为TS串流相关推荐

  1. 利用ffmpeg提供的库(API)进行音频与视频的编码并生成文件

    Output example.c 目录 [隐藏] 1 概述 2 音频输出 2.1 add_audio_stream 2.2 open_audio 2.3 get_audio_frame 2.4 wri ...

  2. 使用jsmpegjs前,先把利用 ffmpeg 将 MP4 格式的文件转换为 ts 格式

    利用 ffmpeg 将 MP4 格式的文件转换为 TS 格式 ffmpeg官网:http://ffmpeg.org/download.html ffmpeg下载地址: https://github.c ...

  3. python实现视频格式转换_Python小工具:利用ffmpy3库3秒钟将视频转换为音频

    作者 | pk 哥 来源公众号 | Python知识圈(ID:PythonCircle) 最近,有读者微信上私聊我,想让我写一篇视频批量转换成音频的文章,我答应了,周末宅家里把这个小工具做出来了. 这 ...

  4. [学习笔记]基于ffmpeg的视频解码,输出YUV图像到文件。

    虽然在音视频领域工作了一段时间,但是对于ffmpeg还是比较陌生,从这周开始入手学习. 拜读了雷霄骅的<最简单的基于FFMPEG+SDL的视频播放器 ver2>,受益匪浅,链接如下 htt ...

  5. FFmpeg学习之二 (yuv视频渲染)

    FFmpeg学习之二 (yuv视频渲染) yuv简介 1.yuv是什么 2.yuv采集方式 3.yuv存储方式 4.yuv格式 yuv视频渲染 1. iOS YUV视频渲染 1.1 IOS利用open ...

  6. python turtle画彩虹-Python利用turtle库绘制彩虹代码示例_天津SEO

    天津SEO RGB模型:光的三原色,共同决定色相 HSB/HSV模型:H色彩,S深浅,B饱和度,H决定色相 需要将HSB模型转换为RGB模型 代码示例: #-*- coding:utf-8 –*- f ...

  7. python画图代码彩虹-Python利用turtle库绘制彩虹代码示例

    语言:Python IDE:Python.IDE 需求 做出彩虹效果 颜色空间 RGB模型:光的三原色,共同决定色相 HSB/HSV模型:H色彩,S深浅,B饱和度,H决定色相 需要将HSB模型转换为R ...

  8. Py之pygame:有趣好玩——利用pygame库实现一个移动底座弹球的小游戏

    Py之pygame:有趣好玩--利用pygame库实现一个移动底座弹球的小游戏 目录 输出结果 实现代码 输出结果 实现代码 # -*- coding: utf-8 -*-#Py之pygame:有趣好 ...

  9. pygame小游戏代码_Py之pygame:有趣好玩——利用pygame库实现一个移动底座弹球的小游戏...

    Py之pygame:有趣好玩--利用pygame库实现一个移动底座弹球的小游戏 目录 输出结果 实现代码 输出结果 ​ 实现代码 # -*- coding: utf-8 -*-#Py之pygame:有 ...

最新文章

  1. Spring Cloud剖析--云平台技术栈17
  2. 4星|《高手》:会讲故事的科学家的经管社科书读书笔记
  3. 抽象语法树 Abstract syntax tree
  4. Java内存溢出和内存泄露后怎么解决
  5. cocos2d 屏幕適配_cocos2d-x 2.x屏幕适配基础
  6. C# NHtmlFilter 帮你过滤Html危险脚本 防止XSS攻击
  7. go 原子操作 atomic的使用
  8. hrjava项目原型html_Mockplus for Mac(原型设计工具)
  9. java中,剩下的这两个内部类不太好理解!
  10. dynamodb java_使用Java扫描DynamoDB项目
  11. java基础面试题之:switch的参数类型
  12. 《高性能MySQL》第5章 创建高性能的索引
  13. Together与Visual.Studio.NET的结合使用(一)
  14. 仿得微博字符限制效果
  15. CCTV主持人博客列表
  16. iOS程序拨打电话方法
  17. 在只有一个网线的前提下,实现两个电脑之间的局域网通信(伽卡他卡电子教室通信)...
  18. 【Matlab系列】MATLAB中显示输出数据的四种方式
  19. Oracle的dual是什么东西啊
  20. 从王者荣耀这款游戏分析unity3d开发游戏需要的资源

热门文章

  1. javascript 克隆/clone:Object.assign
  2. spring mvc 接收List数组类型参数
  3. 【maven插件】maven-help-plugin
  4. ie导出excel是html文件路径,导出HTML到Excel中的IE11 - “拒绝访问”
  5. python hist 参数_关于python中plthist参数的使用详解
  6. java ftp复制文件_如何使用Java将FTP服务器上的文件复制到同一服务器上的目录中?...
  7. php创建mysql计划任务_有关创建PHP-MySQL后台任务的建议
  8. python numpy库等差不均分_numpy.linspace 生成等差数组的方法
  9. angularjs与PHP,我应该混合AngularJS与PHP框架吗?
  10. 关于python的全局变量和局部变量、以下描述错误的是_Python:全局变量与局部变量的问题...