zoukankan      html  css  js  c++  java
  • FFmpeg:AVFrame结构体分析

    最近发现了ffmpeg有个网页版的文档,分享给大家:ffmpeg文档,查询起来看是挺方便的。现在才发现,是不是有点太晚了?

    之前都是直接看源码上的注释,反过来想想,那些注释写的也都听清晰易懂的哈(自我安慰)。

    AVFrame

    AVFrame结构体描述了解码后的(原始)音频或视频数据。

    AVFrame通常被分配一次,然后多次重复使用以持有不同的数据(例如,单个AVFrame持有从解码器接收的帧)。 在这种情况下,av_frame_unref()将释放帧所持有引用,再次重用之前将其重置为初始状态。

    AVFrame描述的数据通常通过AVBuffer API引用计数。 底层缓冲区引用存储在AVFrame.bufAVFrame.extended_buf中。 如果设置了至少一个引用,即AVFrame.buf [0]!= NULL,则AVFrame被认为是引用计数。 在这种情况下,每"平面(plane)"数据必须包含在AVFrame.bufAVFrame.extended_buf中的一个缓冲区中。 所有数据可能只有一个缓冲区,或者每个平面可能有一个单独的缓冲区,或者介于两者之间的任何内容。

    只要使用FFmpeg做解码,必然会使用到AVFrame结构体,它比较重要的字段有:

    • *data[AV_NUM_DATA_POINTERS]:存放解码后的原始媒体数据的指针数组。
      • 对于视频数据而言,planar(YUV420)格式的数据,Y、U、V分量会被分别存放在data[0]、data[1]、data[2]……中。packet格式的数据会被存放在data[0]中。
      • 对于音频数据而言,data数组中,存放的是channel的数据,例如,data[0]、data[1]、data[2]分别对应channel 1,channel 2 等。
    • linesize[AV_NUM_DATA_POINTERS]:视频或音频帧数据的行宽数组。
      • 对video而言:每个图片行的字节大小。linesize大小应该是CPU对齐的倍数,对于现代pc的CPU而言,即32或64的倍数。
      • 对audio而言:代表每个平面的字节大小。只会使用linesize[0]。 对于plane音频,每个通道 的plane必须大小相同。
    • **extended_data:
      • 对于视频数据:只是简单的指向data[]。
      • 对于音频数据:planar音频,每个通道都有一个单独的数据指针,而linesize [0]包含每个通道缓冲区的大小。 对于packet音频,只有一个数据指针,linesize [0]包含所有通道的缓冲区总大小。
    • key_frame:当前帧是否为关键帧,1表示是,0表示不是。
    • pts:以time_base为单位的呈现时间戳(应向用户显示帧的时间)。

    初始化与清理

    AVFrame* avFrame = av_frame_alloc(); // 初始化
    av_frame_free(&avFrame); // 释放
    av_frame_unref(avFrame); // 释放AVFrame的所有引用,以便重用
    
    • 1
    • 2
    • 3

    av_frame_alloc:分配AVFrame并将其字段设置为默认值。主要该函数只分配AVFrame的空间,它的data字段的指定的buffer需要其它函数分配。

    av_frame_free:AVFrame的释放,必须使用该函数释放帧和其中的任何动态分配的对象,例如extended_data。 如果帧被引用计数,则它的引用计数-1。

    av_frame_unref:取消引用帧引用的所有缓冲区并重置帧字段。

    结构定义及成员解读

    typedef struct AVFrame {
    #define AV_NUM_DATA_POINTERS 8
        uint8_t *data[AV_NUM_DATA_POINTERS]; // 存放媒体数据的指针数组
        int linesize[AV_NUM_DATA_POINTERS]; // 视频或音频帧数据的行宽
        uint8_t **extended_data; // 音频或视频数据的指针数组。
        int width, height; // 视频帧的款和高
    
        /**
         * number of audio samples (per channel) described by this frame
         */
        int nb_samples; // 当前帧的音频采样数(每个通道)
        int format; // 视频帧的像素格式,见enum AVPixelFormat,或音频的采样格式,见enum AVSampleForma
        int key_frame; // 当前帧是否为关键帧,1表示是,0表示不是。
        AVRational sample_aspect_ratio; // 视频帧的样本宽高比
        int64_t pts; // 以time_base为单位的呈现时间戳(应向用户显示帧的时间)。
        int64_t pkt_dts; // 从AVPacket复制而来的dts时间,当没有pts时间是,pkt_dts可以替代pts。
        int coded_picture_number; // 按解码先后排序的,解码图像数
        int display_picture_number; // 按显示前后排序的,显示图像数。
        int quality; // 帧质量,从1~FF_LAMBDA_MAX之间取之,1表示最好,FF_LAMBDA_MAX之间取之表示最坏。
        void *opaque; // user的私有数据。
        int interlaced_frame; // 图片的内容是隔行扫描的(交错帧)。
        int top_field_first; // 如果内容是隔行扫描的,则首先显示顶部字段。
        int sample_rate; // 音频数据的采样率
        uint64_t channel_layout; // 音频数据的通道布局。
        /**
         * AVBuffer引用,当前帧数据。 如果所有的元素为NULL,则此帧不是引用计数。 必须连续填充此数组,
         * 即如果buf [i]为非NULL,j <i,buf[j]也必须为非NULL。
         *
         * 每个数据平面最多可以有一个AVBuffer,因此对于视频,此数组始终包含所有引用。 
         * 对于具有多于AV_NUM_DATA_POINTERS个通道的平面音频,可能有多个缓冲区可以容纳在此阵列中。 
         * 然后额外的AVBufferRef指针存储在extended_buf数组中。
         */
        AVBufferRef *buf[AV_NUM_DATA_POINTERS];
        AVBufferRef **extended_buf; // AVBufferRef的指针
        int        nb_extended_buf; // extended_buf的数量
        enum AVColorSpace colorspace; // YUV颜色空间类型。
        int64_t best_effort_timestamp; // 算法预测的timestamp
        int64_t pkt_pos; // 记录上一个AVPacket输入解码器的位置。
        int64_t pkt_duration; // packet的duration
        AVDictionary *metadata;
        int channels; // 音频的通道数。
        int pkt_size; // 包含压缩帧的相应数据包的大小。
    
    } AVFrame;
  • 相关阅读:
    奇异值分解 SVD 的数学解释
    [实现] 利用 Seq2Seq 预测句子后续字词 (Pytorch)2
    [实现] 利用 Seq2Seq 预测句子后续字词 (Pytorch)
    pycharm debug后会出现 step over /step into/step into my code /force step into /step out 分别表示
    单步调试 step into/step out/step over 区别
    终端(terminal)、tty、shell、控制台(console)、bash之间的区别与联系
    pytorch: Variable detach 与 detach_
    RNN,LSTM,GRU基本原理的个人理解
    FMDB官方使用文档-GCD的使用-提高性能(翻译)
    CocoaPods一个Objective-C第三方库的管理利器
  • 原文地址:https://www.cnblogs.com/lidabo/p/15825666.html
Copyright © 2011-2022 走看看