zoukankan      html  css  js  c++  java
  • 解码前世今生——avcodec

    本节主要讲AVPacket中的数据解码到AVFrame中的过程。

    前置知识点

    1.FFmpeg数据结构简介

    AVFormatContext:封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息

    AVInputFormat:每种封装格式对应一个该结构体

    AVStream:视频文件每个视频(音频)流对应一个该结构体

    AVCodecContext:编码器上下文结构体,保存了视频(音频)编解码相关信息

    AVCodec:每种视频(音频)编解码器对应一个该结构体

    AVPacket:存储一帧压缩编码数据

    AVFrame:存储一帧解码后像素(采样)数据

    2.AVCodecInternal

    AVCodecContext中持有一个AVCodecInternal变量,保存了AVCodecContext的各种状态信息,详细如下:

    3.AVCodec

    编解码器的结构体,详细如下:

    源码分析

    由于作者也在学习阶段,本系列文章的规划路线也是参照了雷神总结的视频播放流程图。而本篇文章的起点也就是avcodec_decode_video2。所以,让我们从avcodec_decode_video2开始一步一步分析吧~

    首先来看一下avcodec_decode_video2的注释和实现:

    avcodec_decode_video2

    compat_decode

    在这里我们发现,avcodec_decode_video2这个函数已经被废弃掉了,新的函数为avcodec_send_packet() 和 avcodec_receive_frame(),而新的avcodec_decode_video2也是通过调用这两个函数来实现的。那么接下来我们来看看这两个函数

    avcodec_send_packet

    代码中我们可以看到,通过av_bsf_send_packet发送数据,通过decode_receive_frame_internal解码数据,接下来看这两个函数

    av_bsf_send_packet

    av_packet_move_ref

    这里完成了将AVPacket中的数据放入了指定的AVCodecContext->AVCodecInternal->DecodeFilterContext->AVBSFContext->AVPacket中

    decode_receive_frame_internal

    解码数据时,根据是否指定了解码方式,分为调用receive_frame和调用decode_simple_receive_frame两种方式:

    1)receive_frame

    2)decode_simple_receive_frame

    decode_simple_receive_frame中直接调用了decode_simple_internal

    解码时调用了AVCodec的decode函数,以AYUV为例

    send的过程就是以上这些,接下来我们看一下receive的过程:

    avcodec_receive_frame

    总结

    旧API:avcodec_decode_video2

    新API:avcodec_send_packet与avcodec_receive_frame

    avcodec_decode_video2:新版本中的实现也是使用新的API来完成

    avcodec_send_packet:通过av_bsf_send_packet发送数据,通过decode_receive_frame_internal解码数据,将AVPacket中的数据放入了指定的AVCodecContext->AVCodecInternal->DecodeFilterContext->AVBSFContext->AVPacket中;解码数据时,根据是否指定了解码方式,分为调用receive_frame和调用decode_simple_receive_frame,解码时调用了AVCodec的decode函数

    avcodec_receive_frame:如果存在可以已解码的数据,则直接取出使用,否则调用decode_receive_frame_internal自行解码。decode_receive_frame_internal的解码流程同上。

  • 相关阅读:
    Android 权限表
    自己动手写shell命令之write
    libgdx 1.4.1公布
    【JUnit4.10源码分析】5.2 Rule
    TCP协议具体解释(上)
    关于 二维码 与 NFC 之间的出身贫贱说
    Effective C++ Item 42 了解 typename 的双重意义
    C++第12周(春)项目2
    HDU 2256 Problem of Precision(矩阵高速幂)
    【OC语法快览】二、存取方法
  • 原文地址:https://www.cnblogs.com/lidabo/p/15040758.html
Copyright © 2011-2022 走看看