音视频解码流程简介(使用 ffmpeg)

​第一步:注册组件
​​​av_register_all()
注册编码器、解码器等等…

​​第二步:打开封装格式->打开文件
打开.mp4、.mov、.wmv...格式文件
​​​avformat_open_input();
api解释(文档人肉翻译😓):

/**
 * Open an input stream and read the header. The codecs are not opened.
--->打开一个输入流并且读取它的头文件。注意:编解码器不会被打开。
 * The stream must be closed with avformat_close_input().
--->记住:一定要用 avformat_close_input() 关闭打开的流。
 * 
 * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
 *           May be a pointer to NULL, in which case an AVFormatContext is allocated by this
 *           function and written into ps.
 *           Note that a user-supplied AVFormatContext will be freed on failure.
--->使用用户提供的 AVFormatContext(封装格式上下文,使用 avformat_alloc_context 分配空间)创建。这个 AVFormatContext 大概是一个指向 NULL 的指针,在这种情况下,AVFormatContext 被这个函数(avformat_alloc_context)创建后,会被当前的函数写入到 ps 这个参数中。(人话:先自己创建一个空的内存空间,再传入此函数中,此函数会将信息写入到这个内存空间内)
--->注意:如果此函数失败了,用户提供的 AVFormatContext 将会被释放。
 * 
 * @param url URL of the stream to open.
--->需要打开的流路径。
 * @param fmt If non-NULL, this parameter forces a specific input format.
--->该参数如果不为空,就必须传入一个明确的输入格式。
 *            Otherwise the format is autodetected.
--->否则如果为空,会自动检测格式。
 * @param options  A dictionary filled with AVFormatContext and demuxer-private options.
--->一个参数字典(由 AVFormatContext 和 demuxer-private 填充)
 *                 On return this parameter will be destroyed and replaced with a dict containing
 *                 options that were not found. May be NULL.
--->如果填写的操作选项没有找到,则这个参数变为 NULL
 *
 * @return 0 on success, a negative AVERROR on failure.
--->返回值 0 表示成功,负数表示失败
 *
 * @note If you want to use custom IO, preallocate the format context and set its pb field.
--->注意:如果你想使用自己 IO 读取,需要给封装格式上下文预分配空间,并且设置 AVFormatContext 的 pb 属性。
 */
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);

​​第三步:查找视频流
​​​如果是视频解码,那么查找视频流,如果是音频解码,那么就查找音频流
​​​avformat_find_stream_info();
api解释:

/**
 * Read packets of a media file to get stream information. This
 * is useful for file formats with no headers such as MPEG. This
 * function also computes the real framerate in case of MPEG-2 repeat
 * frame mode.
--->读取媒体文件的包来获取流信息,对于没有头部的文件(如:MPEG)来说是很有用的。该函数也会重新计算类似于 MPEG-2 帧模式的真实帧率。
 * The logical file position is not changed by this function;
--->这个函数不会改变逻辑文件的位置。
 * examined packets may be buffered for later processing.
--->被检查的数据包可以被缓冲以便以后的处理。
 *
 * @param ic media file handle
--->媒体文件句柄(封装格式上下文)
 * @param options  If non-NULL, an ic.nb_streams long array of pointers to
 *                 dictionaries, where i-th member contains options for
 *                 codec corresponding to i-th stream.
 *                 On return each dictionary will be filled with options that were not found.
--->options 如果不为空,将会有一个指向多个字典的数组(长度:封装格式上下文的 nb_streams),该数组的每一个元素(字典指针)包含的编解码 options 将会赋给每一流。
--->(人话:你如果传入了 options 配置,那么你查找到的所有流就会使用这些 option 配置)
 * @return >=0 if OK, AVERROR_xxx on error
--->返回值:>=0表示成功,其他表示错误。
 *
 * @note this function isn't guaranteed to open all the codecs, so
 *       options being non-empty at return is a perfectly normal behavior.
--->注意:这个函数不能保证能打开所有的编解码器,所以传一个指定的 options 配置是一个非常正常的。
--->(人话:这个参数你最好自己传进来)
 *
 * @todo Let the user decide somehow what information is needed so that
 *       we do not waste time getting stuff the user does not need.
--->还有:让使用者自己来决定他们需要什么信息,所以我们不会浪费时间去给使用者不想要的东西。
 */
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

​​第四步:查找音频/视频解码器
​​​1、查找音频/视频流索引位置
​​​2、根据音频/视频流索引,获取解码器上下文
​​​3、根据解码器上下文,获得解码器ID,然后查找解码器

​​第五步:打开解码器
​​​avcodec_open2();

​​第六步:读取音频/视频压缩数据->循环读取
每读取一帧数据,立即解码一帧数据

​​第七步:音频/视频解码->得到音频采样数据/视频像素数据->播放音频/视频

​​第八步:关闭解码器->解码完成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容