该代码几乎类似于过滤 _video.c,这是 ffmpeg doc 中的一个示例代码。
在原始示例文件中,有许多全局静态变量。这是第一版代码的一个片段(与原始示例相同):
static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
int main(int argc, char **argv) {
// .... other code
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// .... other code
}
由于所有这些变量都用于打开视频文件,因此我更喜欢将它们分组。所以我的代码的目的是重新排列这些变量,使源文件更有条理。
我想到的第一个想法是使用struct。
struct structForInVFile {
AVFormatContext *inFormatContext;
AVCodecContext *inCodecContext;
AVCodec* inCodec;
AVPacket inPacket;
AVFrame *inFrame;
int video_stream_index;
int inFrameRate;
int in_got_frame;
};
现在第二版代码变成:
int main(int argc, char **argv) {
// .... other code
structForInVFile inStruct;
if ((ret = avformat_open_input(&inStruct.inFormatContext, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// .... other code
}
第 2 版的结果:代码无法在 avformat_open_input 处工作。没有错误信息。程序静默退出。通过调试发现:inStruct.inFormatContext: 0xffffefbd22b60000
在第三版代码中,我将 inStruct 设置为全局变量。代码变为:
structForInVFile inStruct;
int main(int argc, char **argv) {
// .... other code
if ((ret = avformat_open_input(&inStruct.inFormatContext, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// .... other code
}
第三版的结果:代码有效。通过调试发现:inStruct.inFormatContext: 0x0
所以我认为原因是: AVFormatContext 应该为零初始化,以便 avformat_open_input 工作。现在,问题是:
为什么 AVFormatContext 指针在非全局结构对象中初始化,而在全局对象中初始化为零?
我不知道将结构对象定义为全局变量或非全局变量有什么区别。