一 编码流程
1 注册
avformat_network_init();
2 查找编码器、设置宽高、YUV format等。创建编码器上下文AVCodecContext。
AVCodec* pCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
AVCodecContext* m_pCodecCtxEncode=
avcodec_alloc_context3(pCodec);
3 打开编码器,设置编码参数,比如零延时。
AVDictionary *param = nullptr;
av_dict_set(¶m, "tune", "zerolatency", 0);
avcodec_open2(m_pCodecCtxEncode,pCodec, ¶m)
4 给AVFrame的data数组拷贝视频数据,注意YUV格式存储方式。
(编码后数据在enc_pkt,enc_pkt.data, enc_pkt.size)
avcodec_send_frame(m_pCodecCtxEncode, m_pInputYUV);
avcodec_receive_packet(m_pCodecCtxEncode, &enc_pkt);
5 关闭编码器,释放AVFrame
如果是H264,直接写编码后文件就行。不需用ffmpeg函数写头写尾。
二 解码流程
1 注册
avformat_network_init();
2 打开文件或流地址,查找音视频信息。
avformat_open_input(&m_pInputFormatCtx, pFileName, nullptr, &pOptions);
avformat_find_stream_info(m_pInputFormatCtx, nullptr);
3 根据音视频属性,查找相应的解码器。
(解码器上下文是AVFormatContext结构体的成员变量。)
m_pCodecContext = m_pFormatCtx->streams[m_videoStream]->codec;
m_pCodec=avcodec_find_decoder(m_pCodecContext->codec_id);
4 读文件,得到packet。解码,得到frame。
av_read_frame(m_pInputFormatCtx, &packet)
avcodec_send_packet(m_pCodecContext, packet);
avcodec_receive_frame(m_pCodecContext, frame);
5 关闭解码器,释放AVFrame。
``
## 三 几个结构体
```cpp
1 AVFrame是未压缩的,解码后的数据、
AVPacket是压缩的,编码前的数据。
2 AVCodec可以理解为函数,AVCodecContext是AVCodec上下文,该格式的具体参数,因为ffmpeg是C的,没有类。
AVCodecContext需要传给avcodec_open2、avcodec_encode_video2。
const AVCodec ff_h264_decoder = {
.name = "h264",
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(H264Context),
.init = h264_decode_init,
.close = h264_decode_end,
.decode = h264_decode_frame,
……
}
3 AVFormatContext和AVCodecContext区别?
avformat_open_input(&m_pFormatCtx, filename, NULL, NULL);打开文件、或者流地址。
m_pCodecContext = m_pFormatCtx->streams[m_videoStream]->codec;
AVFormatContext包含AVCodecContext,一个视频一个AVCodecContext。