最近项目开发中需要使用FFmpeg进行音视频的解码,在使用过程中遇到了一些问题对其进行记录。
FFmpeg版本:FFmpeg3.4.1 下载地址如下:ffmpeg3.4.1Win32开发包-编解码工具类资源-CSDN下载
1、音频解码:
- av_register_all(); 遍历注册所有的组件,包括各种编解码器、解复用器等等;
- AVFormatContext *pFormatCtx = avformat_alloc_context(); 主要存储视音频封装格式中包含的信息,此变量非常重要,几乎贯穿了解码过程的始终,此后主要位pFormatCtx变量分配内存;
- avformat_open_input(&pFormatCtx, pInput_test, NULL, NULL); 打开输入视频文件,读取文件头信息,将文件头信息读取到pFormatCtx 结构体内,为后续解码做准备;
- avformat_find_stream_info(pFormatCtx, NULL); 获取文件流信息,主要根据pFormatCtx结构体内的已有信息对pFormatCtx结构体内流字段赋值流信息,即,可看作进一步为pFormatCtx结构体进行赋值;
- AVCodecParameters *pAudioCodecCtx= pFormatCtx->streams[a_stream_idx]->codecpar; 提取pFormatCtx结构体内的对应流编码器信息
- AVCodec *pAudioCodec= avcodec_find_decoder(pAudioCodecCtx->codec_id); 根据编解码的编码id号查找对应的音频解码器信息
- AVCodecContext *pAudioEnc = avcodec_alloc_context3(pAudioCodec); 根据初始化AVCodecContext,只是分配,还没打开
- avcodec_parameters_to_context(pAudioEnc, pFormatCtx->streams[a_stream_idx]->codecpar); 填充CodecContext信息,此步骤对于解码音频十分重要,若无此步骤,则无法进行正常的音频解码
- avcodec_open2(pAudioEnc , pAudioCodec, NULL); 打开解码器
- av_read_frame(pFormatCtx, packet); 从pFormatCtx结构体内流字段读取视频文件压缩流到packet变量内
- avcodec_send_packet(pAudioEnc , packet); 将packet内文件压缩流导入到对应解码器内
- avcodec_receive_frame(pAudioEnc , pFrame); 从解码器pAudioEnc 内解码压缩流到pFrame变量内(存储解压缩后的音视频数据)
- pFrame结构体内的 uint8_t *data[AV_NUM_DATA_POINTERS]; 成员内存储了音视频流解码后的数据,可对其进行相应操作(可保存可进行图像处理等等)。
以下是示例代码(由于从项目中扣取出来,大致流程无问题,未进行验证可能会有一些小问题,现先记录后续再进行验证):
#include <windows.h>
#include <stdint.h>
#include <iostream>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
#include "libswscale/swscale.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
};
#define ES_STREAM_VIDEO 1
#define ES_STREAM_AUDIO 2
#pragma comment(lib, "FFmpeg/lib/avcodec.lib")
#pragma comment(lib, "FFmpeg/lib/avformat.lib")