【音视频】FFmpeg打开视频 | 保存图片

2023-05-31,,

1、初始化FFmpeg

av_register_all(); //初始化FFMPEG  调用了这个才能正常使用编码器和解码器

  但是这个函数如今已经没什么用了,它的就是把你定义和系统初始化的编码器和解码器连接起来而已,然后就没有了。

  现在解码器和编码器的初始化都是通过定义全局变量来初始化的。与原来相比,唯一的改变就是使用数组替换链表完成解码器和编码器的初始化。

## 参考文章:https://www.jianshu.com/p/ebb219ec1c0f

2、分配一个AVFormatContext,FFMPEG所有的操作都要通过这个AVFormatContext数据结构来进行

AVFormatContext *pFormatCtx = avformat_alloc_context();

  AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数。

  此结构包含了一个视频流的格式内容:AVInputFormat(or AVOutputFormat同一时间AVFormatContext内只能存在其中一个),和AVStream、AVPacket这几个重要的数据结构以及一些其他的相关信息,比如title,author,copyright等。还有一些可能在编解码中会用到的信息,诸如:duration, file_size, bit_rate等。

3、打开视频文件:

char *file_path = "./movie/ifwithoutu.mp4";
avformat_open_input(&pFormatCtx, file_path, NULL, NULL);

  

4、视频打开之后,查找文件中的视频流

    ///循环查找视频中包含的流信息,直到找到视频类型的流
///便将其记录下来 保存到videoStream变量中
///这里我们现在只处理视频流 音频流先不管他
for (i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
}
} ///如果videoStream为-1 说明没有找到视频流
if (videoStream == -1)
{
printf("Didn't find a video stream.");
return -1;
}

  

5、根据视频流,打开一个解码器来解码

    ///查找解码器
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL)
{
printf("Codec not found.");
return -1;
} ///打开解码器
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
printf("Could not open codec.");
return -1;
}

  FFmpeg可以让我们根据查找到的视频流信息获取到解码器,不需要知道实际用到的是什么解码器

6、读取视频

     int y_size = pCodecCtx->width * pCodecCtx->height;
AVPacket *packet = (AVPacket *) malloc(sizeof(AVPacket)); //分配一个packet
av_new_packet(packet, y_size); //分配packet的数据 if (av_read_frame(pFormatCtx, packet) < 0)
{
break; //这里认为视频读取完了
}

  av_read_frame读取的是一帧视频,并存入一个AVPacket的结构中

7、视频里的数据是经过编码压缩的,需要将其解码

   if (packet->stream_index == videoStream)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture,packet); if (ret < 0)
{
printf("decode error.");
return -1;
}
}

  

8、解码器解码之后得到的图像数据都是YUV420格式的,需要将其保存成图片文件,因此需要转换为RGB格式

    if (got_picture)
{
sws_scale( img_convert_ctx,
(uint8_t const * const *) pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize
);
}

  

9、将RGB图片写入

SaveFrame(pFrameRGB,
pCodecCtx->width,
pCodecCtx->height,
index++
);

  

错误:

(1):改成  AV_PIX_FMT_RGB24

音视频】FFmpeg打开视频 | 保存图片的相关教程结束。

《【音视频】FFmpeg打开视频 | 保存图片.doc》

下载本文的Word格式文档,以方便收藏与打印。