FFMpeg 解封装

本例子实现的是将音视频分离,例如将封装格式为 FLV、MKV、MP4、AVI 等封装格式的文件,将音频、视频分离开来。

大致的解封装流程:

1.首先要对解复用器进行初始化。

2.其次将输入的封装格式文件给到解复用器内。

3.最后利用解封装对 Container 进行解封装。

根据流程可以推到出大致的代码流程

  • 首先对输入文件(Container 文件)、输出文件(Video/Audio 进行处理),方便后面的使用;

  • 其次打开输入文件,并分配 Format Context,从输入文件中得到流信息

  • 之后打开视频、音频编码器 Context,针对视频数据,分配图像 image。

  • 分配 frame 结构,初始化 packet,从输入文件中读取 frame 信息,并之后进行解码 packet。

  • 最后释放各种分配的数据信息。

ffmpeg解封装案例分析

下面讨论如何利用ffmpeg提供的API函数进行多媒体文件的解封装(demux)过程。

在讲解之前,我们先复习一些基本的多媒体文件知识。

容器格式:

不管是音频文件还是视频格式的文件,都是一个多媒体的容器,即container,比如常见的视频容器格式有avi、mp4、mkv、flv、rm/rmvb、mov、ts、vob、dat,音频容器格式有MP3、WAV、AAC、APE,FLAC等等,它容纳了视频、音频、字幕(subtitle)等一个或多个基本流数据,有的甚至一个容器中存放有多个视频、音频以及字幕。

压缩格式:

对视频、音频数据的基本流进行的压缩方式就是音视频的压缩格式。

常见的视频压缩格式如mpeg2、mpeg4、H264、VC1、Rm/Rmvb,常见音频压缩格式如MPA、AAC、AC3、DTS。注意这里的部分名字和上面的一样,但意义不同,上面是封装格式,这里是压缩格式。

为什么要压缩呢?因为不压缩的话,要存储图像或声音就需要非常多的空间,比如mpeg2压缩比能达到25:1左右,而H264甚至能达到102:1的惊人程度!

        ES:也就是ElementaryStream,也称为基本流、组件流等称呼,就是单独的一路视频、一条音频、一个subtitle字幕或者单个的附加数据。显然常见的多媒体文件一个都有一个视频ES、音频ES,有的也含有多个视频ES和音频ES以及subtitleES。比如蓝光原版的TS一般都含有多个音轨ES和字幕ES,但不是所有有字幕都有字幕ES,可能字幕已经内嵌进视频,这样的字幕其实成了视频的一部分。

        Demux:在播放时,需要把这些视音频以及字幕等基本流分离出来,这个过程就叫Demux,或者解封装,也称为解复用。分离出来的各个基本流(ES)分别送给视频解码器、音频解码器等解码后才能得到图像声音。:

        Remux:当然Demux反过来把基本的音频、视频、字幕等组合成一个完整的多媒体就是Remux或者封装,也称为复用。比如很多电影网站的音视频压制的人就需要先做Demux,分离成ES,在加入必要的中文字幕和音轨后、重新封装。所有的转码工具也都必须有Remux和重新Demux的过程。复用与解复用的概念对于熟悉DVB行业的读者来说应该比较清楚。

        PTS:也就是显示时间戳,指图像或者声音在解码后应该显示或者发声的时间点。音视频不是一解码出来就播出来,否则就乱了,性能好的解码器播放的快,差的播放的慢,并且视频和音频也对不上号。所有这些都是靠PTS来同步的。至于DTS解码时间戳在现在相对以前较大解码内存缓冲下,显得不那么重要了。

几个API函数:

有了这些基本的多媒体知识,我们就可以继续讲解如何利用ffmpeg来进行Demux这个过程。

首先介绍一下主要的几个API函数:

Int avformat_open_input(AVFormatContext **ps, const char *filename,

AVInputFormat *fmt, AVDictionary **options);

这个函数用于打开多媒体文件,并读取相关文件头信息。

void  avformat_close_input(AVFormatContext **ps);

这个函数用于关闭上面打开的多媒体文件,释放相关资源。

int  avformat_find_stream_info(AVFormatContext *ic, AVDictionary**options);

这个函数通过注册的文件格式解析器读取文件的取各种信息,比如播放持续时间、音视频压缩格式、音轨信息、字幕信息、帧率、采样率等等。

int av_read_frame(AVFormatContext*s, AVPacket *pkt);

这个函数对于Demux过程是最重要的一个函数,它从文件中读取一帧视频、一帧或多帧音频、字幕等ES数据包,除了数据本身之外,还包括PTS、持续时间、参考帧等重要信息。

void av_free_packet(AVPacket *pkt);

这个函数用于释放ES数据包,与上面的函数成对使用。

简单的Demux框架实例

有了这些函数和上面的基本知识,下面我们来实现一个简单的Demux框架实例。

这个实例的功能是把多媒体文件中的音视频ES数据抽出来分别写入不同文件。

我们为了简单,这里不处理返回错误,在实际项目中自己添加错误处理机制。

本文用最简单最原始的方式把ffmpeg解封装的基本框架讲解清楚。

extern "C"{#include <libavformat/avformat.h>
}
static const char *media_file = "test_media.mp4";
int main(void)
{int i, vid_idx, aud_idx;FILE *fp_vides = NULL, *fp_audes = NULL;AVFormatContext *pFormatCtx = NULL;AVPacket pkt;av_register_all();avformat_open_input(&pFormatCtx, media_file, NULL, NULL);avformat_find_stream_info(pFormatCtx, NULL);fp_vides = fopen("vid_es.dat", "wb");fp_audes = fopen("aud_es.dat", "wb");// 1, handle stream infofor (i=0; i<pFormatCtx->nb_streams; i++){if (pFormatCtx->streams[i]->codec->codec_type ==AVMEDIA_TYPE_VIDEO)vid_idx = i;else if (pFormatCtx->streams[i]->codec->codec_type ==AVMEDIA_TYPE_AUDIO)aud_idx = i;else;//such as subtitile}while (av_read_frame(pFormatCtx, &pkt) >= 0){// 2, handle pkt dataif (pkt.stream_index == vid_idx)fwrite(pkt.data, pkt.size, 1, fp_vides);else if (pkt.stream_index == aud_idx)fwrite(pkt.data, pkt.size, 1, fp_audes);else;// such as subtitileav_free_packet(&pkt);}fclose(fp_vides);fclose(fp_audes);avformat_close_input(&pFormatCtx);return 0;
}

FFmpeg入门详解之43:FFmpeg解封装的原理与实战相关推荐

  1. FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社

    大家好,我的第一本书正式出版了,可以在京东各大店铺抢购哦. <FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社> 京东自营链接:https://item.jd.com/13 ...

  2. FFmpeg入门详解之100:搭建Nginx流媒体服务器

    这里小编给大家推荐一款流媒体服务器Nginx,可以实现RTMP和HLS等.搭建完成后,可以使用FFmpeg推流,实现直播功能. 注意:操作环境是Ubuntu18.04, 总共分为几个步骤: 1.安装N ...

  3. FFmpeg入门详解之82:FFmpeg转码器Java版之ava编码

    创建数据库:db_webavtc 创建数据表:avcategory(素材类别) id int primary key, pid int , cname varchar(255), cmemo varc ...

  4. FFmpeg入门详解之116:rtsp live555摄像头直播

    rtsp+live555摄像头直播 Live555直播流程简介与演示 第一步,读取摄像头数据 第二步,x264编码 第三步,扩展live555 第四步,vlc或ffplay播放 ffplay -sta ...

  5. FFmpeg入门详解之83:流媒体与直播技术

    流媒体 流媒体又叫流式媒体,它是指商家用一个视频传送服务器(比如:vlc)把节目(比如:ande10.mp4)当成数据包发出,传送到网络上.用户通过解压设备对这些数据进行解压后,节目就会像发送前那样显 ...

  6. FFmpeg入门详解之117:视频监控的架构和流程

    几张架构图带您快速了解视频监控 图一 图二 图三 图四 视频监控系统的简介 视频监控 视频监控是安全防范系统的重要组成部分,英文Cameras and Surveillance.传统的监控系统包括前端 ...

  7. FFmpeg入门详解之121:颜色空间转换RGB和YUV的原理与实战

    5.颜色空间转换RGB和YUV的原理与实战 三种颜色空间模型:RGB.YUV.HSV 一.概述 颜色通常用三个独立的属性来描述,三个独立变量综合作用,自然就构成一个空间坐标,这就是颜色空间. 但被描述 ...

  8. FFmpeg入门详解之122:Qt5 FFmpeg本地摄像头采集预览实战

    6.Qt5+FFmpeg本地摄像头采集预览实战 源码工程:S26_Test2 FFmpeg命令行处理摄像头 ffmpeg -list_devices true -f dshow -i dummy 命令 ...

  9. FFmpeg入门详解之124:Qt5 FFmpeg单路网络摄像头采集预览

    Qt5+FFmpeg单路网络摄像头采集预览 源码工程:S26_Test4 RTSP协议简介 RTSP(Real Time Streaming Protocol),RFC2326 RTSP(Real T ...

  10. FFmpeg入门详解之111:RTSP协议2

    rtsp消息详解 1.RTSP的消息有两大类,一是请求消息(request),一是回应消息(response),两种消息的格式不同. 请求消息格式: 方法 URI RTSP版本 CR LF 消息头 C ...

最新文章

  1. 区块链软件公司:创新的区块链技术如何改变法律行业的面貌
  2. list字母排序 java_通过Java排序List集合的元素的几种方法
  3. xadmin 更改后台一级目录名称
  4. 如何在我的世界里打造一台计算机,在《我的世界》里从零打造一台计算机有多难?...
  5. codeforces#236_div2_A nuts 贪心
  6. 关于linux中的 秘钥认证 ,最清晰解读
  7. IOS学习之数据库(6)--SQLite常用的函数
  8. MySQL流浪记(七)—— MySQL删除表数据
  9. network reactnative_从零学React Native之14 网络请求
  10. 华为路由器时间同步_4G网络变WIFI,华为4G路由2 Pro让上网变得更简单
  11. CentOS6.X安装10G需要额外安装的软件包
  12. MacBook 键盘出现故障,如何修复?
  13. alpha-beta 极大极小值剪枝算法
  14. 元宇宙持续升温,金蝶推出数字员工破圈而来
  15. 微信小程序获取年月日周及早上、中午、晚上
  16. 2篇SCI二区+3篇一类论文认定A档博士!享110万房补!直接副教授、甚至教授待遇,30万科启
  17. 男人,就要对自己下手狠一点
  18. JavaScript实现在线websocket WSS测试工具 -toolfk程序员工具网
  19. buntu22.04安装WPS中文版(一百一十八)
  20. web3创业合伙人招募!!!

热门文章

  1. unity hdrp的TAA
  2. Ubuntu 16.04系统安装VS Code流程详解
  3. LR脚本录制3——Fiddler生成LR脚本(推荐)
  4. 维图PDMS切图软件
  5. 星空银河html,[内蒙好星空]5个夜晚一人逛银河[有星云星系]
  6. 小白之路由浅入深之------day05
  7. 黑麦4k可以安装Linux,全高清屏你就满足了?GTX1050Ti+4K屏麦本本黑麦5X颠覆你的视界...
  8. STM32F429--STM32的PWM占空比产生与测量
  9. 你认为微软 Win12 可以在哪些方面改进?
  10. Linux- rsync企业级实战