• FFmpeg音视频解封装


    一 . 解封装用到的函数和结构体

      1.av_register_all() : open 一次就调用一次

      2.avformat_network_init() : 网络模块初始化

      3.avformat_open_input(...) : 打开文件并解析文件

      4.avformat_find_stream_info(...) : 去查找没有头文件索引    探测网络流,也没有头文件

      5.av_find_best_stream(...) :  确定正确的流

      6.av_read_frame : 读取AVPacket的数据

      7.AVFormatContext  :  添加封装  解封装 的上下文

       AVStream : 存流的相关信息

       AVPacket  :  FFmpeg解码 编码接受的数据包(从网络来的数据包需要转换成AVPacket包才可以编解码)

       int  av_packet_from_data(AVPacket  *pkt , uint8_t  *data  , int size)

    二.avformat_open_input()的参数讲解

      1.AVFormatContext  **ps   封装格式上下文

      2.const char *url  -------->   数据的地址(http rtp 本地)

      3.AVInputFormat *fmt ------->  指定输入封装格式,一般参数为null,自行去探测(一般不使用了,除非频繁打开同一个内容)

      4.AVDictionary  **options ------->  一组key-value的数组 

    三.AVFormatContext 的结构体分析

      1.AVIOContext  *pb  : 自定义读写格式或者从内存来读

      2.char filename[1024] : 把打开文件的名字保存起来(譬如断开或者重连)

      3.unsigned int  nb_stream  : 数组流总数的个数

      4.AVStream  **streams :  数组 0:视频 1:音频  AVMediaType(这里面有枚举各种流)

      5.int64_t  duration(AV_TIME_BASE)  : 代表一个媒体文件的长度,以AV_TIME_BASE(1000000)为时间基数单位,

      6.int64_t  bit_rate  :  

      void avformat_close_input(AVFormatContext  **s) : 关闭封装格式的上下文的输入流

    四. avformat_find_stream_info(AVFormatContext *ic , AVDictionary  **options) :  探测获取封装格式的信(获得头部没有索引的文件信息)

      flv(无法获得总时长)   H264  : 没有头部信息

    五 . AVStream的参数

      1.AVRational(代表分数的含义) time_base : 时间基数(它是分数形式)  duration * (time_base.num / time_base.den) ------>转换成秒

      2.int64_t(%lld)   duration :  单位为毫秒(以AVFormat->duration那个为准,这个只是作为参考)

      3.int64_t  nb_frames  : 

      4.AVRational  avg_frame_rate

      5.AVCodecParameters  *codecpar  (音视频的参数) ------->替代AVCodecContext  *codec

        1).enum AVMediaType codec_type : 区分编码格式是音频还是视频

        2).enum AVCodecID  codec_id  : 枚举编码格式

        3).uint32_t  codec_tag : 用四个字节来表示各种编码器

        4).int format  : 像素格式或者音频采样格式

        5).int width,int height : 视频的宽高

        6).uint64_t  channel_layout (取默认值), int channel (声道数), int sample_rate , int frame_size

    六 . av_find_best_stream  :  获取音视频的索引

      1.int av_find_best_stream(AVFormatContext *ic , enum AVMediaType type , int  wanted_stream_nb , int related_stream , AVCode **  decoder_ret , int flags)

      2.AVFormatContext  : 封装格式的上下文

      3.AVMediaType : 获取流的类型

      4.wanted_stream_nb :  -1

      5.related_stream : ..........(相关流) -1

      6.decoder_ret   :  解码器相关知识目前用不到

      7.flags  :  目前用不到

          读取数据的流的信息方法 : 

      audioStream  =  av_find_best_stream     --------->获得流的索引

       AVFormatContext->streams[audioStream]->codecpar->channels  --------->stream[索引]->codecpar->后面就是流的信息

    七.av_read_frame : 读取音视频的帧数据

      1.AVFormatContext *s  : 处理文件的上下文

      2.AVPacket  *pkt :   return 0 if OK  < 0 on error or end of file

    八 . AVPacket 结构体的使用

      1.AVBufferRef  *buf  : 存储引用的技术

      2.int64_t  pts  :  表示显示时间  //pts*(num/den)  num/den-------->时间基数

      3.int64_t  dts   : 表示解码时间  //同上   如果没有B帧,pts和dts一样

      4.uint8_t  *data , int size  : 指的是AVBufferRef里面再分配的空间

      5.AVPacket *av_packet_alloc(void)  : 初始化并创建AVPacket的对象,在堆上申请的空间,必须要释放

      6.AVPacket *av_packet_clone(const  AVPacket  *src) : 创建AVPacket的对象,并用计数--------------->先创建对象(分配空间),然后再引用+1.

      7.int av_packet_ref(AVPacket *dst , const AVPacket *src) :  在AVPacket创建好的前提下,手动引用+1

       int av_packet_unref(const AVPacket *pkt) : 手动引用-1

      8.void av_packet_free(AVPacket  **pkt)  :  清空对象并减引用计数(与6是一对)

      9.void av_init_packet(AVPacket  * pkt) :  默认初始化

      10. int  av_packet_from_data(AVPacket  *pkt , uint8_t  *data  , int size) : 自定义格式或者抓取网络流转化为AVPacket包

    九.  av_seek_frame : 拖动进度条

      int  av_seek_frame(AVFormatContext  *s , int stream_index , int64_t timestamp , int flags)

      1.AVFormatContext  :  处理文件上下文

      2.stream_index  :  流的索引  默认是-1  必须用视频的索引

      3.timestamp  :  时间戳 ----->指拖动到什么位置

      4.flags : 表示移动的方法

       (1).AVSEEK_FLAG_BACKWARDN  1  ----------->找到后面最近的关键帧

       (2).AVSEEK_FLAG_BYTE  2  

       (3).AVSEEK_FLAG_ANY    4    

       (4).AVSEEK_FLAG_FRAME  8  --------------->找到关键帧  

      Logw("stream = %d size = %d pts = %lld dts = %lld flag = %d",pkt->stream_index , pkt->size , pkt->pts
    ,pkt->dts, pkt->flags);

        

      

      

  • 相关阅读:
    P1082 同余方程
    P2678 跳石头
    P2827 蚯蚓
    P1351 联合权值
    P2822 组合数问题
    P3958 奶酪
    P2296 寻找道路
    P2661 信息传递
    平时问题总结
    平时总结
  • 原文地址:https://www.cnblogs.com/liunx1109/p/9263792.html
Copyright © 2020-2023  润新知