ffmpeg avformat_open_input之后如何正常关闭,方便再次打开
时间: 2023-08-18 16:10:02 浏览: 236
在使用FFmpeg的avformat_open_input函数打开一个媒体文件之后,为了正常关闭并方便再次打开,需要按照以下步骤:
1. 调用avformat_close_input函数关闭输入流,释放AVFormatContext相关资源。
2. 调用avformat_free_context函数,释放AVFormatContext结构体及其内部的AVStream、AVCodecContext等结构体相关的资源。
为了方便再次打开同一文件,可以在关闭后保留AVFormatContext结构体及其内部结构体的信息,以便下一次打开时可以直接使用,而不需要再次调用avformat_find_stream_info函数获取流信息。具体操作步骤如下:
1. 定义一个全局AVFormatContext结构体变量,用于保存读取媒体文件时的上下文信息。
2. 在第一次读取媒体文件时,先调用avformat_open_input、avformat_find_stream_info等函数获取流信息,并将AVFormatContext结构体保存到全局变量中。
3. 在关闭输入流时,只需要调用avformat_close_input函数关闭输入流即可,AVFormatContext结构体及其内部结构体的信息不需要释放。
4. 下一次读取同一媒体文件时,直接使用保存在全局变量中的AVFormatContext结构体即可。
示例代码:
```
AVFormatContext *pFormatCtx = NULL;
int videoStream = -1;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVPacket packet;
static AVFormatContext *globalFormatCtx = NULL; // 全局变量,用于保存AVFormatContext结构体
av_register_all();
if (!globalFormatCtx) {
if(avformat_open_input(&pFormatCtx, filename, NULL, NULL)!=0){
printf("Could not open file\n");
return -1;
}
if(avformat_find_stream_info(pFormatCtx, NULL)<0){
printf("Could not find stream information\n");
return -1;
}
videoStream = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if(videoStream == -1){
printf("Could not find video stream\n");
return -1;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec == NULL){
printf("Codec not found\n");
return -1;
}
if(avcodec_open2(pCodecCtx, pCodec, NULL)<0){
printf("Could not open codec\n");
return -1;
}
globalFormatCtx = pFormatCtx; // 将AVFormatContext结构体保存到全局变量中
} else {
pFormatCtx = globalFormatCtx; // 直接使用全局变量中的AVFormatContext结构体
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
}
av_init_packet(&packet);
while(av_read_frame(pFormatCtx, &packet)>=0){
// 处理读取到的数据帧
av_packet_unref(&packet);
}
avformat_close_input(&pFormatCtx); // 关闭输入流,释放输入流相关资源
if (globalFormatCtx != pFormatCtx) {
avformat_free_context(pFormatCtx); // 释放AVFormatContext结构体及其内部资源
}
globalFormatCtx = NULL; // 清空全局变量,以便下一次打开同一文件
avcodec_free_context(&pCodecCtx);
```
以上代码演示了如何打开一个媒体文件,读取其中的数据帧,并在完成后正常关闭并保留AVFormatContext结构体及其内部结构体的信息,以便下一次再次打开同一文件。在关闭输入流时,只需要调用avformat_close_input函数关闭输入流,AVFormatContext结构体及其内部结构体的信息不需要释放,只有在不再需要读取该文件时才需要释放。
阅读全文