播放器的流程和解码流程

一. 播放器的流程

1. 输入 : 从文件或网络等读取原数据,对原数据进行解析,比如文件,首先要分析文件格式,从文件中取得音视频编码参数,视频时间长度等信息,然后要从其中取出音频编码数据和视频编码数据送到解码部分,这里暂称这种编码源数据块为 packet。
2. 解码 : 初始化时,利用输入端从源数据中取得的信息调用不同的解码库初始化;然后接收输入端传送来的音视频编码数据,分别进行音频解码和视频解码,视频解码出来的数据一般是 YUV 或 RGB 数据,这里暂称为 picture, 音频解码出来的数据是采样数据,是声卡可以播放的数据,这里暂称为 sample。 解码所得的数据接下来送到输出部分。
3. 输出 : 接收解码部分送来的 picture 和 sample 并显示。 视频显示一般使用某个图形库,如 SDL, Xlib, DirectDraw, OpengGL, FrameBuffer等, 音频输出是把 sample 写入系统的音频驱动,由音频驱动送入声卡播放, 可用的音频输出有 ALSA, OSS, SDL, DirectSound, WaveOut等。

二. FFMPEG解码流程:

1. 注册所有容器格式和CODEC:av_register_all()
  2. 打开文件: avformat_open_input()
  3. 从文件中提取流信息: avformat_find_stream_info()
  4. 穷举所有的流av_find_best_stream(),查找其中种类 AVMEDIA_TYPE_VIDEO或 AVMEDIA_TYPE_AUDIO
  5. 查找对应的解码器: avcodec_find_decoder()
        6. 打开编解码器:avcodec_open2()
7. 为解码帧分配内存:avcodec_alloc_frame()
8. 不停地从码流中提取出帧数据:av_read_frame()
9. 判断帧的类型,对于视频帧调用:avcodec_decode_video2()对于音频帧调用avcodec_decode_video2
10. 解码完后,释放解码器: avcodec_close()
11. 关闭输入文件: avformat_close_input_file()

主要数据结构:
基本概念:
   
   编解码器、数据帧、媒体流和容器是数字媒体处理系统的四个基本概念。
首先需要统一术语:
    容器/文件(Conainer/File):即特定格式的多媒体文件。
    媒体流(Stream):指时间轴上的一段连续数据,如一段声音数据,一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器。
    数据帧/数据包(Frame/Packet):通常,一个媒体流由大量的数据帧组成,对于压缩数据,帧对应着编解码器的最小处理单元。通常,分属于不同媒体流的数据帧交错复用于容器之中,参见交错。
    编解码器:编解码器以帧为单位实现压缩数据和原始数据之间的相互转换。
在FFMPEG中,使用AVFormatContext、AVStream、AVCodecContext、AVCodec及AVPacket等结构来抽象这些基本要素。
AVCodecContext
AVCodecContext:
    这是一个描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息,如下列出了部分比较重要的域:
typedef struct AVCodecContext {
 / **
     *一些编解码器需要/可以像使用extradata Huffman表。
     * MJPEG:Huffman表
     * RV10其他标志
     * MPEG4:全球头(也可以是在比特流或这里)
     *分配的内存应该是FF_INPUT_BUFFER_PADDING_SIZE字节较大
     *,比extradata_size避免比特流器,如果它与读prolems。
     * extradata按字节的内容必须不依赖于架构或CPU的字节顺序。
     * - 编码:设置/分配/释放由libavcodec的。
     * - 解码:由用户设置/分配/释放。
     * /
    uint8_t *extradata;
    int extradata_size;
   / **
     *这是时间的基本单位,在条件(以秒为单位)
     *帧时间戳派代表出席了会议。对于固定fps的内容,
     *基应该1/framerate和时间戳的增量应该
     *相同的1。
     * - 编码:必须由用户设置。
     * - 解码:libavcodec的设置。
     * /
    AVRational time_base;
 /*视频* /
    / **
     *
    / **
     *图片宽度/高度。
     * - 编码:必须由用户设置。
     * - 解码:libavcodec的设置。
     *请注意:兼容性,它是可能的,而不是设置此
     * coded_width/高解码之前。
     * /
    int width, height;
    ......
    / *仅音频* /
    int sample_rate; ///<
    int sample_rate; ///< 每秒采样
    int channels; ///< 音频通道数
    / **
     *音频采样格式
     * - 编码:由用户设置。
     * - 解码:libavcodec的设置。
     * /
    enum SampleFormat sample_fmt; ///< 样本格式
 
    / *下面的数据不应该被初始化。* /
    / **
     *
    / **
     *每包样品,初始化时调用“init”。
     * /
    int frame_size;
    int frame_number; ///<音频或视频帧数量
    char codec_name[32];
    enum AVMediaType codec_type; /* 看到AVMEDIA_TYPE_xxx */
    enum CodecID codec_id; /* see CODEC_ID_xxx */
 / **
     *
    enum CodecID codec_id; /* see CODEC_ID_xxx */
 / **
     *的fourcc(LSB在前,所以“的ABCD” - >(“D”<< 24)(“C”<< 16)(“B”<< 8)+“A”)。
     *这是用来解决一些编码错误。
     *分路器应设置什么是编解码器用于识别领域中。
     *如果有分路器等多个领域,在一个容器,然后选择一个
     *最大化使用的编解码器有关的信息。
     *如果在容器中的编解码器标记字段然后32位大分路器应该
     *重新映射到一个表或其他结构的32位编号。也可选择新
     * extra_codec_tag+大小可以添加,但必须证明这是一个明显的优势
     *第一。
     * - 编码:由用户设置,如果没有则默认基础上codec_id将使用。
     * - 解码:由用户设置,将被转换成在初始化libavcodec的大写。
     * /
    unsigned int codec_tag;
    ......
    / **
     *在解码器的帧重排序缓冲区的大小。
     *对于MPEG-2,这是IPB1或0低延时IP。
     * - 编码:libavcodec的设置。
     * - 解码:libavcodec的设置。
     * /
    int has_b_frames;
 
   / **
     *每包的字节数,如果常量和已知或0
     *
     *用于一些WAV的音频编解码器。
     * /
    int block_align;
    / **
     *从分路器位每个样品/像素(huffyuv需要)。
     * - 编码:libavcodec的设置。
     * - 解码:由用户设置。
     * /
     int bits_per_coded_sample;
     .....
} AVCodecContext;
如果是单纯使用libavcodec,这部分信息需要调用者进行初始化;如果是使用整个FFMPEG库,这部分信息在调用avformat_open_input和avformat_find_stream_info的过程中根据文件的头信息及媒体流内的头部信息完成初始化。其中几个主要域的释义如下:
    extradata/extradata_size:这个buffer中存放了解码器可能会用到的额外信息,在av_read_frame中填充。一般来说,首先,某种具体格式的demuxer在读取格式头信息的时候会填充extradata,其次,如果demuxer没有做这个事情,比如可能在头部压根儿就没有相关的编解码信息,则相应的parser会继续从已经解复用出来的媒体流中继续寻找。在没有找到任何额外信息的情况下,这个buffer指针为空。
    time_base:
    width/height:视频的宽和高。
    sample_rate/channels:音频的采样率和信道数目。
    sample_fmt:音频的原始采样格式。
        codec_name/codec_type/codec_id/codec_tag:编解码器的信息。
AVStrea
   该结构体描述一个媒体流,定义如

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值