介绍
主要的操作是读取视频每一帧,然后解码,再转换成RGB
流程如下
1.打开输入流
int ret = avformat_open_input(&formatCtx, pFileName, NULL, NULL);
if (ret < 0)
{
std::cout << "avformat_open_input failed" << std::endl;
return -1;
}
2.查找流
if (avformat_find_stream_info(formatCtx, NULL) < 0)
{
std::cout << "avformat_find_stream_info failed" << std::endl;
return -1;
}
3.找到视频流索引
int nVideoIndex = -1;
for (unsigned int i = 0; i < formatCtx->nb_streams; i++)
{
if (formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
nVideoIndex = i;
break;
}
}
4.查找解码器
AVCodecParameters* codecParams = formatCtx->streams[nVideoIndex]->codecpar;
AVCodec* codec = avcodec_find_decoder(codecParams->codec_id);
if (codec == NULL)
{
std::cout << "avcodec_find_decoder failed" << std::endl;
return -1;
}
5.打开解码器
if (avcodec_open2(codecCtx, codec, NULL) < 0)
{
std::cout << "avcodec_open2 failed" << std::endl;
return -1;
}
6.循环读取
int nFrames = 0;
while (av_read_frame(formatCtx, packet) >= 0)
{
//格式转换
//存盘
}
7.格式转换
//格式转换
sws_scale(swsContex, frameYUV->data, frameYUV->linesize, 0, codecCtx->height, frameRGB->data, frameRGB->linesize);
8.存盘
//循环写入数据
for (int y = 0; y < codecCtx->height; y++)
{
fwrite(frameRGB->data[0] + y * frameRGB->linesize[0], 1, codecCtx->width * 3, wj);
}